webpack-obfuscatorを使ってTypeScriptを難読化する

# 環境

- Mac mini (2018)

```
[/Users/horyu]
sw_vers
ProductName:	macOS
ProductVersion:	11.7
BuildVersion:	20G817
[/Users/horyu]
node -v
v16.16.0
```


# 0. 初期化

ディレクトリとpackage.jsonを作成します。

```text
[/Users/horyu]
mkdir nandoku
[/Users/horyu]
cd nandoku
[/Users/horyu/nandoku]
npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help init` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (nandoku) 
version: (1.0.0) 
description: 
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: horyu
license: (ISC) WTFPL
About to write to /Users/horyu/nandoku/package.json:

{
  "name": "nandoku",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "horyu",
  "license": "WTFPL"
}


Is this OK? (yes) 
[/Users/horyu/nandoku]
# private: true を追加
cat <<< `jq '.+ {private: true}' < package.json` > package.json
[/Users/horyu/nandoku]
```

# 1. TypeScriptとWebpackのビルド環境を整える

[最新版TypeScript+webpack 5の環境構築まとめ(React, Vue.js, Three.jsのサンプル付き) - ICS MEDIA](https://ics.media/entry/16329/#webpack-ts) を参考に作ります。

```
[/Users/horyu/nandoku]
npm i -D webpack webpack-cli typescript ts-loader

added 133 packages, and audited 134 packages in 8s

18 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
[/Users/horyu/nandoku]
```

```package.json
{
  "name": "nandoku",
  "version": "1.0.0",
  "description": "",
  "main": "dist/index.mjs",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "horyu",
  "license": "WTFPL",
  "private": true,
  "devDependencies": {
    "ts-loader": "^9.4.1",
    "typescript": "^4.8.4",
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0"
  }
}
```

```tsconfig.json
{
  "compilerOptions": {
    "sourceMap": true,
    "target": "ES5",
    "module": "ES2015",
    "strict": true,
    "forceConsistentCasingInFileNames": true
  }
}
```

```webpack.config.js
const resolve = require('path').resolve;

module.exports = {
  mode: "production",
  entry: "./src/index.ts",
  output: {
    path: resolve(__dirname, "dist"),
    library: {
      type: 'module',
    },
  },
  experiments: {
    outputModule: true,
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: "ts-loader",
      },
    ],
  },
  resolve: {
    extensions: [".ts"],
  },
};
```

# 2. 通常のビルドをする

適当にTSを書きます。

```src/fizzbuzz.ts
export function fizzbuzz(n: number): number | string {
    if (n % 15 === 0) {
        return 'FizzBuzz';
    } else if (n % 3 === 0) {
        return 'Fizz';
    } else if (n % 5 === 0) {
        return 'Buzz';
    } else {
        return n;
    }
}
```

```src/index.ts
import { fizzbuzz } from "./fizzbuzz";

export { fizzbuzz as MyFizzBuzz };

for (let i = 1; i <= 30; i++) {
    console.log(fizzbuzz(i));
}
```

ビルドします。

```
[/Users/horyu/nandoku]
npx webpack
asset main.js 155 bytes [emitted] [minimized] (name: main)
./src/main.ts 341 bytes [built] [code generated]
webpack 5.74.0 compiled successfully in 2071 ms
[/Users/horyu/nandoku]
```

```js:dist/main.mjs
var r={d:(e,o)=>{for(var z in o)r.o(o,z)&&!r.o(e,z)&&Object.defineProperty(e,z,{enumerable:!0,get:o[z]})},o:(r,e)=>Object.prototype.hasOwnProperty.call(r,e)},e={};function o(r){return r%15==0?"FizzBuzz":r%3==0?"Fizz":r%5==0?"Buzz":r}r.d(e,{j:()=>o});for(var z=1;z<=30;z++)console.log(o(z));var t=e.j;export{t as MyFizzBuzz};
```

productionビルドなのでminifyされています。minifyされただけでも読みにくいですが、これを難読化していきます。

# 3. webpack-obfuscatorを導入する

```
[/Users/horyu/nandoku]
npm i -D javascript-obfuscator webpack-obfuscator

added 75 packages, and audited 209 packages in 8s

36 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
[/Users/horyu/nandoku]
```

```package.json
{
  "name": "nandoku",
  "version": "1.0.0",
  "description": "",
  "main": "dist/main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "horyu",
  "license": "WTFPL",
  "private": true,
  "devDependencies": {
    "javascript-obfuscator": "^4.0.0",
    "ts-loader": "^9.4.1",
    "typescript": "^4.8.4",
    "webpack": "^5.74.0",
    "webpack-cli": "^4.10.0",
    "webpack-obfuscator": "^3.5.1"
  }
}
```

# 4A. プラグインで難読化する

```diff:webpack.config.js
const resolve = require('path').resolve;
+ const WebpackObfuscator = require('webpack-obfuscator');

module.exports = {
  mode: "production",
  entry: "./src/index.ts",
  output: {
    path: resolve(__dirname, "dist"),
    library: {
      type: 'module',
    },
  },
  experiments: {
    outputModule: true,
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: "ts-loader",
      },
    ],
  },
  resolve: {
    extensions: [".ts"],
  },
+ plugins: [
+   new WebpackObfuscator ({
+     stringArrayCallsTransform: true,
+     stringArrayEncoding: [
+       'base64',
+       'rc4'
+     ],
+     stringArrayThreshold: 1,
+   }, [])
+ ]
};
```

```
[/Users/horyu/nandoku]
npx webpack
asset main.mjs 5.76 KiB [emitted] [javascript module] [minimized] (name: main)
runtime modules 396 bytes 2 modules
orphan modules 238 bytes [orphan] 1 module
./src/index.ts + 1 modules 376 bytes [built] [code generated]
webpack 5.74.0 compiled successfully in 1849 ms
[/Users/horyu/nandoku]
```

```js:dist/main.mjs
function a0_0x34af(){var _0x4e7f4f=['Bg9N','rML6EKj1ENO','mty2odiXmMHYDxfpsW','ENWTvez2wW','qNv6EG','mZqWmde4ngvMuuT3ua','W7NdKWxcJ8kJW7ddQCozqLDMqCoi','WP89WPzmoCk+W4VdUq','W6FdMtFcKurpb8oy','q8kJW5VdKGnStmk/yh1BW6u','sSkJW5dcQM8oD8kvua','y2fSBa','mtm5ntuYoe1xEeHyDW','WO3dImkTaSk5y2C','dmo3WOaNWRX/W6SdW4ZdGmoxjSoM','zCoMWO3cUNOfW4hdV3BdKSkeimk1','W5BdPCoqrW','odm5otG1B2nXq0XQ','AGJdG8o6q8oMcG','dSkwW4KyW796BWnVW6RcTdVcMa','nZKYmdCXnu1MBNfqtq','e8omWOOulcHPW5tdOKCLWOGTW7O','qSovWOdcOw41sq','ChjVDg90ExbL','mtmYnZyWEvHzueT4','AgfZt3DUuhjVCgvYDhK','CCkwz8krWPVcSSkMsvSNW7LBEq','mtmYqvrxveLb'];a0_0x34af=function(){return _0x4e7f4f;};return a0_0x34af();}var a0_0x52e2d9=a0_0x29d2;(function(_0x27e270,_0x431b8a){var a0_0x3a8c71={_0x339f6a:0x107,_0x1ed6f2:'*uBi',_0x1b1ba5:'Alxw',_0x24a94c:'[bPt',_0x49e031:0xfa,_0x2cfa25:0x108,_0x52d0eb:0xfc,_0x2e7e4e:'Hm6#',_0x269d24:0x103,_0x450ebe:'C)!y'},_0x640f7a=a0_0x29d2,_0x5a23e2=a0_0x81ec,_0x374c25=_0x27e270();while(!![]){try{var _0x42a377=-parseInt(_0x5a23e2(a0_0x3a8c71._0x339f6a,a0_0x3a8c71._0x1ed6f2))/0x1+parseInt(_0x5a23e2(0x104,a0_0x3a8c71._0x1b1ba5))/0x2+parseInt(_0x5a23e2(0x110,a0_0x3a8c71._0x24a94c))/0x3*(parseInt(_0x5a23e2(0x111,'3)Wi'))/0x4)+-parseInt(_0x640f7a(a0_0x3a8c71._0x49e031))/0x5*(-parseInt(_0x5a23e2(a0_0x3a8c71._0x2cfa25,'*uBi'))/0x6)+-parseInt(_0x5a23e2(a0_0x3a8c71._0x52d0eb,a0_0x3a8c71._0x2e7e4e))/0x7+parseInt(_0x640f7a(a0_0x3a8c71._0x269d24))/0x8*(parseInt(_0x5a23e2(0x101,a0_0x3a8c71._0x450ebe))/0x9)+parseInt(_0x5a23e2(0x106,'*vjj'))/0xa*(-parseInt(_0x5a23e2(0x10d,'ToH@'))/0xb);if(_0x42a377===_0x431b8a)break;else _0x374c25['push'](_0x374c25['shift']());}catch(_0x196fed){_0x374c25['push'](_0x374c25['shift']());}}}(a0_0x34af,0x6de0e));function a0_0x81ec(_0x427560,_0x392450){var _0x34afcb=a0_0x34af();return a0_0x81ec=function(_0x29d206,_0x64a2f5){_0x29d206=_0x29d206-0xf7;var _0x18a000=_0x34afcb[_0x29d206];if(a0_0x81ec['dDhxHo']===undefined){var _0x4b29a4=function(_0x502722){var _0x5f4976='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var _0x29e5b9='',_0x3a53ad='';for(var _0xc48135=0x0,_0x589c4f,_0x8ea0ba,_0x29ac17=0x0;_0x8ea0ba=_0x502722['charAt'](_0x29ac17++);~_0x8ea0ba&&(_0x589c4f=_0xc48135%0x4?_0x589c4f*0x40+_0x8ea0ba:_0x8ea0ba,_0xc48135++%0x4)?_0x29e5b9+=String['fromCharCode'](0xff&_0x589c4f>>(-0x2*_0xc48135&0x6)):0x0){_0x8ea0ba=_0x5f4976['indexOf'](_0x8ea0ba);}for(var _0x16c2e0=0x0,_0x1e315d=_0x29e5b9['length'];_0x16c2e0<_0x1e315d;_0x16c2e0++){_0x3a53ad+='%'+('00'+_0x29e5b9['charCodeAt'](_0x16c2e0)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x3a53ad);};var _0x81ecb6=function(_0x25f510,_0x167739){var _0x251988=[],_0x331f29=0x0,_0x54a607,_0x5bded8='';_0x25f510=_0x4b29a4(_0x25f510);var _0x4ea153;for(_0x4ea153=0x0;_0x4ea153<0x100;_0x4ea153++){_0x251988[_0x4ea153]=_0x4ea153;}for(_0x4ea153=0x0;_0x4ea153<0x100;_0x4ea153++){_0x331f29=(_0x331f29+_0x251988[_0x4ea153]+_0x167739['charCodeAt'](_0x4ea153%_0x167739['length']))%0x100,_0x54a607=_0x251988[_0x4ea153],_0x251988[_0x4ea153]=_0x251988[_0x331f29],_0x251988[_0x331f29]=_0x54a607;}_0x4ea153=0x0,_0x331f29=0x0;for(var _0x1390d6=0x0;_0x1390d6<_0x25f510['length'];_0x1390d6++){_0x4ea153=(_0x4ea153+0x1)%0x100,_0x331f29=(_0x331f29+_0x251988[_0x4ea153])%0x100,_0x54a607=_0x251988[_0x4ea153],_0x251988[_0x4ea153]=_0x251988[_0x331f29],_0x251988[_0x331f29]=_0x54a607,_0x5bded8+=String['fromCharCode'](_0x25f510['charCodeAt'](_0x1390d6)^_0x251988[(_0x251988[_0x4ea153]+_0x251988[_0x331f29])%0x100]);}return _0x5bded8;};a0_0x81ec['yPSrbW']=_0x81ecb6,_0x427560=arguments,a0_0x81ec['dDhxHo']=!![];}var _0x1d351a=_0x34afcb[0x0],_0x222ebf=_0x29d206+_0x1d351a,_0x2363fc=_0x427560[_0x222ebf];return!_0x2363fc?(a0_0x81ec['JnryCH']===undefined&&(a0_0x81ec['JnryCH']=!![]),_0x18a000=a0_0x81ec['yPSrbW'](_0x18a000,_0x64a2f5),_0x427560[_0x222ebf]=_0x18a000):_0x18a000=_0x2363fc,_0x18a000;},a0_0x81ec(_0x427560,_0x392450);}var r={'d':(_0x8ea0ba,_0x29ac17)=>{var a0_0x455f78={_0xae08bc:0xf7},_0x1ac94d=a0_0x81ec;for(var _0x16c2e0 in _0x29ac17)r['o'](_0x29ac17,_0x16c2e0)&&!r['o'](_0x8ea0ba,_0x16c2e0)&&Object[_0x1ac94d(a0_0x455f78._0xae08bc,'4^Bz')](_0x8ea0ba,_0x16c2e0,{'enumerable':!0x0,'get':_0x29ac17[_0x16c2e0]});},'o':(_0x1e315d,_0x25f510)=>Object[a0_0x52e2d9(0xf9)][a0_0x52e2d9(0xfb)][a0_0x52e2d9(0x109)](_0x1e315d,_0x25f510)},e={};function o(_0x167739){var a0_0x589daf={_0x144bff:0x10e,_0x2656af:0x102},_0x43a6ab=a0_0x81ec,_0x577482=a0_0x52e2d9;return _0x167739%0xf==0x0?_0x577482(0xff):_0x167739%0x3==0x0?_0x43a6ab(a0_0x589daf._0x144bff,'h7^Z'):_0x167739%0x5==0x0?_0x577482(a0_0x589daf._0x2656af):_0x167739;}r['d'](e,{'j':()=>o});function a0_0x29d2(_0x427560,_0x392450){var _0x34afcb=a0_0x34af();return a0_0x29d2=function(_0x29d206,_0x64a2f5){_0x29d206=_0x29d206-0xf7;var _0x18a000=_0x34afcb[_0x29d206];if(a0_0x29d2['KZIKjg']===undefined){var _0x4b29a4=function(_0x81ecb6){var _0x502722='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';var _0x5f4976='',_0x29e5b9='';for(var _0x3a53ad=0x0,_0xc48135,_0x589c4f,_0x8ea0ba=0x0;_0x589c4f=_0x81ecb6['charAt'](_0x8ea0ba++);~_0x589c4f&&(_0xc48135=_0x3a53ad%0x4?_0xc48135*0x40+_0x589c4f:_0x589c4f,_0x3a53ad++%0x4)?_0x5f4976+=String['fromCharCode'](0xff&_0xc48135>>(-0x2*_0x3a53ad&0x6)):0x0){_0x589c4f=_0x502722['indexOf'](_0x589c4f);}for(var _0x29ac17=0x0,_0x16c2e0=_0x5f4976['length'];_0x29ac17<_0x16c2e0;_0x29ac17++){_0x29e5b9+='%'+('00'+_0x5f4976['charCodeAt'](_0x29ac17)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x29e5b9);};a0_0x29d2['khGYaU']=_0x4b29a4,_0x427560=arguments,a0_0x29d2['KZIKjg']=!![];}var _0x1d351a=_0x34afcb[0x0],_0x222ebf=_0x29d206+_0x1d351a,_0x2363fc=_0x427560[_0x222ebf];return!_0x2363fc?(_0x18a000=a0_0x29d2['khGYaU'](_0x18a000),_0x427560[_0x222ebf]=_0x18a000):_0x18a000=_0x2363fc,_0x18a000;},a0_0x29d2(_0x427560,_0x392450);}for(var z=0x1;z<=0x1e;z++)console[a0_0x52e2d9(0xfe)](o(z));var t=e['j'];export{t as MyFizzBuzz};
```

<details>
<summary>Prettierでフォーマット</summary>

```js:dist/main.mjs
function a0_0x34af() {
  var _0x4e7f4f = [
    "Bg9N",
    "rML6EKj1ENO",
    "mty2odiXmMHYDxfpsW",
    "ENWTvez2wW",
    "qNv6EG",
    "mZqWmde4ngvMuuT3ua",
    "W7NdKWxcJ8kJW7ddQCozqLDMqCoi",
    "WP89WPzmoCk+W4VdUq",
    "W6FdMtFcKurpb8oy",
    "q8kJW5VdKGnStmk/yh1BW6u",
    "sSkJW5dcQM8oD8kvua",
    "y2fSBa",
    "mtm5ntuYoe1xEeHyDW",
    "WO3dImkTaSk5y2C",
    "dmo3WOaNWRX/W6SdW4ZdGmoxjSoM",
    "zCoMWO3cUNOfW4hdV3BdKSkeimk1",
    "W5BdPCoqrW",
    "odm5otG1B2nXq0XQ",
    "AGJdG8o6q8oMcG",
    "dSkwW4KyW796BWnVW6RcTdVcMa",
    "nZKYmdCXnu1MBNfqtq",
    "e8omWOOulcHPW5tdOKCLWOGTW7O",
    "qSovWOdcOw41sq",
    "ChjVDg90ExbL",
    "mtmYnZyWEvHzueT4",
    "AgfZt3DUuhjVCgvYDhK",
    "CCkwz8krWPVcSSkMsvSNW7LBEq",
    "mtmYqvrxveLb",
  ];
  a0_0x34af = function () {
    return _0x4e7f4f;
  };
  return a0_0x34af();
}
var a0_0x52e2d9 = a0_0x29d2;
(function (_0x27e270, _0x431b8a) {
  var a0_0x3a8c71 = {
      _0x339f6a: 0x107,
      _0x1ed6f2: "*uBi",
      _0x1b1ba5: "Alxw",
      _0x24a94c: "[bPt",
      _0x49e031: 0xfa,
      _0x2cfa25: 0x108,
      _0x52d0eb: 0xfc,
      _0x2e7e4e: "Hm6#",
      _0x269d24: 0x103,
      _0x450ebe: "C)!y",
    },
    _0x640f7a = a0_0x29d2,
    _0x5a23e2 = a0_0x81ec,
    _0x374c25 = _0x27e270();
  while (!![]) {
    try {
      var _0x42a377 =
        -parseInt(_0x5a23e2(a0_0x3a8c71._0x339f6a, a0_0x3a8c71._0x1ed6f2)) /
          0x1 +
        parseInt(_0x5a23e2(0x104, a0_0x3a8c71._0x1b1ba5)) / 0x2 +
        (parseInt(_0x5a23e2(0x110, a0_0x3a8c71._0x24a94c)) / 0x3) *
          (parseInt(_0x5a23e2(0x111, "3)Wi")) / 0x4) +
        (-parseInt(_0x640f7a(a0_0x3a8c71._0x49e031)) / 0x5) *
          (-parseInt(_0x5a23e2(a0_0x3a8c71._0x2cfa25, "*uBi")) / 0x6) +
        -parseInt(_0x5a23e2(a0_0x3a8c71._0x52d0eb, a0_0x3a8c71._0x2e7e4e)) /
          0x7 +
        (parseInt(_0x640f7a(a0_0x3a8c71._0x269d24)) / 0x8) *
          (parseInt(_0x5a23e2(0x101, a0_0x3a8c71._0x450ebe)) / 0x9) +
        (parseInt(_0x5a23e2(0x106, "*vjj")) / 0xa) *
          (-parseInt(_0x5a23e2(0x10d, "ToH@")) / 0xb);
      if (_0x42a377 === _0x431b8a) break;
      else _0x374c25["push"](_0x374c25["shift"]());
    } catch (_0x196fed) {
      _0x374c25["push"](_0x374c25["shift"]());
    }
  }
})(a0_0x34af, 0x6de0e);
function a0_0x81ec(_0x427560, _0x392450) {
  var _0x34afcb = a0_0x34af();
  return (
    (a0_0x81ec = function (_0x29d206, _0x64a2f5) {
      _0x29d206 = _0x29d206 - 0xf7;
      var _0x18a000 = _0x34afcb[_0x29d206];
      if (a0_0x81ec["dDhxHo"] === undefined) {
        var _0x4b29a4 = function (_0x502722) {
          var _0x5f4976 =
            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=";
          var _0x29e5b9 = "",
            _0x3a53ad = "";
          for (
            var _0xc48135 = 0x0, _0x589c4f, _0x8ea0ba, _0x29ac17 = 0x0;
            (_0x8ea0ba = _0x502722["charAt"](_0x29ac17++));
            ~_0x8ea0ba &&
            ((_0x589c4f =
              _0xc48135 % 0x4 ? _0x589c4f * 0x40 + _0x8ea0ba : _0x8ea0ba),
            _0xc48135++ % 0x4)
              ? (_0x29e5b9 += String["fromCharCode"](
                  0xff & (_0x589c4f >> ((-0x2 * _0xc48135) & 0x6))
                ))
              : 0x0
          ) {
            _0x8ea0ba = _0x5f4976["indexOf"](_0x8ea0ba);
          }
          for (
            var _0x16c2e0 = 0x0, _0x1e315d = _0x29e5b9["length"];
            _0x16c2e0 < _0x1e315d;
            _0x16c2e0++
          ) {
            _0x3a53ad +=
              "%" +
              ("00" + _0x29e5b9["charCodeAt"](_0x16c2e0)["toString"](0x10))[
                "slice"
              ](-0x2);
          }
          return decodeURIComponent(_0x3a53ad);
        };
        var _0x81ecb6 = function (_0x25f510, _0x167739) {
          var _0x251988 = [],
            _0x331f29 = 0x0,
            _0x54a607,
            _0x5bded8 = "";
          _0x25f510 = _0x4b29a4(_0x25f510);
          var _0x4ea153;
          for (_0x4ea153 = 0x0; _0x4ea153 < 0x100; _0x4ea153++) {
            _0x251988[_0x4ea153] = _0x4ea153;
          }
          for (_0x4ea153 = 0x0; _0x4ea153 < 0x100; _0x4ea153++) {
            (_0x331f29 =
              (_0x331f29 +
                _0x251988[_0x4ea153] +
                _0x167739["charCodeAt"](_0x4ea153 % _0x167739["length"])) %
              0x100),
              (_0x54a607 = _0x251988[_0x4ea153]),
              (_0x251988[_0x4ea153] = _0x251988[_0x331f29]),
              (_0x251988[_0x331f29] = _0x54a607);
          }
          (_0x4ea153 = 0x0), (_0x331f29 = 0x0);
          for (
            var _0x1390d6 = 0x0;
            _0x1390d6 < _0x25f510["length"];
            _0x1390d6++
          ) {
            (_0x4ea153 = (_0x4ea153 + 0x1) % 0x100),
              (_0x331f29 = (_0x331f29 + _0x251988[_0x4ea153]) % 0x100),
              (_0x54a607 = _0x251988[_0x4ea153]),
              (_0x251988[_0x4ea153] = _0x251988[_0x331f29]),
              (_0x251988[_0x331f29] = _0x54a607),
              (_0x5bded8 += String["fromCharCode"](
                _0x25f510["charCodeAt"](_0x1390d6) ^
                  _0x251988[
                    (_0x251988[_0x4ea153] + _0x251988[_0x331f29]) % 0x100
                  ]
              ));
          }
          return _0x5bded8;
        };
        (a0_0x81ec["yPSrbW"] = _0x81ecb6),
          (_0x427560 = arguments),
          (a0_0x81ec["dDhxHo"] = !![]);
      }
      var _0x1d351a = _0x34afcb[0x0],
        _0x222ebf = _0x29d206 + _0x1d351a,
        _0x2363fc = _0x427560[_0x222ebf];
      return (
        !_0x2363fc
          ? (a0_0x81ec["JnryCH"] === undefined && (a0_0x81ec["JnryCH"] = !![]),
            (_0x18a000 = a0_0x81ec["yPSrbW"](_0x18a000, _0x64a2f5)),
            (_0x427560[_0x222ebf] = _0x18a000))
          : (_0x18a000 = _0x2363fc),
        _0x18a000
      );
    }),
    a0_0x81ec(_0x427560, _0x392450)
  );
}
var r = {
    d: (_0x8ea0ba, _0x29ac17) => {
      var a0_0x455f78 = { _0xae08bc: 0xf7 },
        _0x1ac94d = a0_0x81ec;
      for (var _0x16c2e0 in _0x29ac17)
        r["o"](_0x29ac17, _0x16c2e0) &&
          !r["o"](_0x8ea0ba, _0x16c2e0) &&
          Object[_0x1ac94d(a0_0x455f78._0xae08bc, "4^Bz")](
            _0x8ea0ba,
            _0x16c2e0,
            { enumerable: !0x0, get: _0x29ac17[_0x16c2e0] }
          );
    },
    o: (_0x1e315d, _0x25f510) =>
      Object[a0_0x52e2d9(0xf9)][a0_0x52e2d9(0xfb)][a0_0x52e2d9(0x109)](
        _0x1e315d,
        _0x25f510
      ),
  },
  e = {};
function o(_0x167739) {
  var a0_0x589daf = { _0x144bff: 0x10e, _0x2656af: 0x102 },
    _0x43a6ab = a0_0x81ec,
    _0x577482 = a0_0x52e2d9;
  return _0x167739 % 0xf == 0x0
    ? _0x577482(0xff)
    : _0x167739 % 0x3 == 0x0
    ? _0x43a6ab(a0_0x589daf._0x144bff, "h7^Z")
    : _0x167739 % 0x5 == 0x0
    ? _0x577482(a0_0x589daf._0x2656af)
    : _0x167739;
}
r["d"](e, { j: () => o });
function a0_0x29d2(_0x427560, _0x392450) {
  var _0x34afcb = a0_0x34af();
  return (
    (a0_0x29d2 = function (_0x29d206, _0x64a2f5) {
      _0x29d206 = _0x29d206 - 0xf7;
      var _0x18a000 = _0x34afcb[_0x29d206];
      if (a0_0x29d2["KZIKjg"] === undefined) {
        var _0x4b29a4 = function (_0x81ecb6) {
          var _0x502722 =
            "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=";
          var _0x5f4976 = "",
            _0x29e5b9 = "";
          for (
            var _0x3a53ad = 0x0, _0xc48135, _0x589c4f, _0x8ea0ba = 0x0;
            (_0x589c4f = _0x81ecb6["charAt"](_0x8ea0ba++));
            ~_0x589c4f &&
            ((_0xc48135 =
              _0x3a53ad % 0x4 ? _0xc48135 * 0x40 + _0x589c4f : _0x589c4f),
            _0x3a53ad++ % 0x4)
              ? (_0x5f4976 += String["fromCharCode"](
                  0xff & (_0xc48135 >> ((-0x2 * _0x3a53ad) & 0x6))
                ))
              : 0x0
          ) {
            _0x589c4f = _0x502722["indexOf"](_0x589c4f);
          }
          for (
            var _0x29ac17 = 0x0, _0x16c2e0 = _0x5f4976["length"];
            _0x29ac17 < _0x16c2e0;
            _0x29ac17++
          ) {
            _0x29e5b9 +=
              "%" +
              ("00" + _0x5f4976["charCodeAt"](_0x29ac17)["toString"](0x10))[
                "slice"
              ](-0x2);
          }
          return decodeURIComponent(_0x29e5b9);
        };
        (a0_0x29d2["khGYaU"] = _0x4b29a4),
          (_0x427560 = arguments),
          (a0_0x29d2["KZIKjg"] = !![]);
      }
      var _0x1d351a = _0x34afcb[0x0],
        _0x222ebf = _0x29d206 + _0x1d351a,
        _0x2363fc = _0x427560[_0x222ebf];
      return (
        !_0x2363fc
          ? ((_0x18a000 = a0_0x29d2["khGYaU"](_0x18a000)),
            (_0x427560[_0x222ebf] = _0x18a000))
          : (_0x18a000 = _0x2363fc),
        _0x18a000
      );
    }),
    a0_0x29d2(_0x427560, _0x392450)
  );
}
for (var z = 0x1; z <= 0x1e; z++) console[a0_0x52e2d9(0xfe)](o(z));
var t = e["j"];
export { t as MyFizzBuzz };
```

</details>


文字列FizzとBuzzをexport以外からは消せました。書かれたコードがFizzBuzzだと分かっているので

>   return _0x167739 % 0xf == 0x0
    ? _0x577482(0xff)
    : _0x167739 % 0x3 == 0x0
    ? _0x43a6ab(a0_0x589daf._0x144bff, "h7^Z")
    : _0x167739 % 0x5 == 0x0
    ? _0x577482(a0_0x589daf._0x2656af)
    : _0x167739;

関数がこの部分だとギリギリわかりますが、他人の書いたコードだと読めそうにないですね。

# 4B. Loaderで難読化する

```diff:webpack.config.js
const resolve = require('path').resolve;
+ const WebpackObfuscator = require('webpack-obfuscator');

module.exports = {
  mode: "production",
  entry: "./src/index.ts",
  output: {
    path: resolve(__dirname, "dist"),
    library: {
      type: 'module',
    },
  },
  experiments: {
    outputModule: true,
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: "ts-loader",
      },
+     {
+       test: /\.ts$/,
+       enforce: 'post',
+       use: { 
+         loader: WebpackObfuscator.loader, 
+         options: {
+           stringArrayCallsTransform: true,
+           stringArrayEncoding: [
+             'base64',
+             'rc4'
+           ],
+           stringArrayThreshold: 1,
+         },
+       },
+     },
    ],
  },
  resolve: {
    extensions: [".ts"],
  },
};
```

```
[/Users/horyu/nandoku]
npx webpack
asset main.mjs 4.81 KiB [emitted] [javascript module] [minimized] (name: main)
runtime modules 396 bytes 2 modules
orphan modules 5.02 KiB [orphan] 1 module
./src/index.ts + 1 modules 9.86 KiB [built] [code generated]
webpack 5.74.0 compiled successfully in 2018 ms
[/Users/horyu/nandoku]
```

```js:dist/main.mjs
var r={d:(t,n)=>{for(var o in n)r.o(n,o)&&!r.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:n[o]})},o:(r,t)=>Object.prototype.hasOwnProperty.call(r,t)},t={};function n(){var r=["iSoSy0julYqucSoPWQqV","mJvswxrKzLu","oG/cUt5iWOyV","nZq2mte2tKjMvurf","eqrqWQNdLmkacKpdKCk4WRVdJG","qtZcPKSgW45tvJxcKe4","W4vXl8kyWRi4W6Od","mtHVsLP3BwS","W57dVcFcSCkmWOK7W5RdSg8JWPZcTa","mtyYmJa2EKrMsxPM","oLhdPgiwW6fBW7LRWRdcV352","phtcPmkQWOpcTte","rML6EG","mZnMz1vfCMW","rML6EKj1ENO","tCoaothcLmo6WP7dJCkcBSkQvW","W6hcKCoKxmk5W7SeW59OAuNdJW","mZGWmda3EML3q091","vSkTkae","tCobAw/dS8knWOldIq","W7qKWPXueCorWQFdRmkKWPddM8kQ","nZG4mtjmuvzAEuO","oLpdR2KFW6irW6PmWQRcIg8"];return(n=function(){return r})()}function o(r,t){var e=n();return o=function(t,n){var a=e[t-=406];if(void 0===o.YHmEHX){var c=function(r){for(var t,n,o="",e="",a=0,c=0;n=r.charAt(c++);~n&&(t=a%4?64*t+n:n,a++%4)?o+=String.fromCharCode(255&t>>(-2*a&6)):0)n="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=".indexOf(n);for(var i=0,d=o.length;i<d;i++)e+="%"+("00"+o.charCodeAt(i).toString(16)).slice(-2);return decodeURIComponent(e)},i=function(r,t){var n,o,e=[],a=0,i="";for(r=c(r),o=0;o<256;o++)e[o]=o;for(o=0;o<256;o++)a=(a+e[o]+t.charCodeAt(o%t.length))%256,n=e[o],e[o]=e[a],e[a]=n;o=0,a=0;for(var d=0;d<r.length;d++)a=(a+e[o=(o+1)%256])%256,n=e[o],e[o]=e[a],e[a]=n,i+=String.fromCharCode(r.charCodeAt(d)^e[(e[o]+e[a])%256]);return i};o.pNBkqx=i,r=arguments,o.YHmEHX=!0}var d=e[0],u=t+d,f=r[u];return f?a=f:(void 0===o.DilKOg&&(o.DilKOg=!0),a=o.pNBkqx(a,n),r[u]=a),a},o(r,t)}function e(r,t){var o=n();return e=function(t,n){var a=o[t-=406];if(void 0===e.itPBJh){var c=function(r){for(var t,n,o="",e="",a=0,c=0;n=r.charAt(c++);~n&&(t=a%4?64*t+n:n,a++%4)?o+=String.fromCharCode(255&t>>(-2*a&6)):0)n="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=".indexOf(n);for(var i=0,d=o.length;i<d;i++)e+="%"+("00"+o.charCodeAt(i).toString(16)).slice(-2);return decodeURIComponent(e)};e.bxYWOn=c,r=arguments,e.itPBJh=!0}var i=o[0],d=t+i,u=r[d];return u?a=u:(a=e.bxYWOn(a),r[d]=a),a},e(r,t)}function a(r){var t=o,n=e;return r%15==0?n(420):r%3==0?n(418):r%5==0?t(424,"P@wc"):r}function c(r,t){var n=f();return c=function(t,o){var e=n[t-=220];if(void 0===c.rPyxjC){var a=function(r){for(var t,n,o="",e="",a=0,c=0;n=r.charAt(c++);~n&&(t=a%4?64*t+n:n,a++%4)?o+=String.fromCharCode(255&t>>(-2*a&6)):0)n="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=".indexOf(n);for(var i=0,d=o.length;i<d;i++)e+="%"+("00"+o.charCodeAt(i).toString(16)).slice(-2);return decodeURIComponent(e)};c.CAMjuE=a,r=arguments,c.rPyxjC=!0}var i=n[0],d=t+i,u=r[d];return u?e=u:(e=c.CAMjuE(e),r[d]=e),e},c(r,t)}r.d(t,{j:()=>a}),function(r,t){for(var a=e,c=o,i=n();;)try{if(149509==-parseInt(c(417,"XULK"))/1*(parseInt(a(415))/2)+parseInt(a(423))/3+-parseInt(c(411,"jFpD"))/4+-parseInt(a(407))/5*(parseInt(c(426,"7(*G"))/6)+parseInt(a(409))/7+-parseInt(c(406,"P@wc"))/8*(parseInt(a(413))/9)+-parseInt(c(414,"dSt)"))/10*(-parseInt(a(419))/11))break;i.push(i.shift())}catch(r){i.push(i.shift())}}();var i=c;function d(r,t){var n=f();return d=function(t,o){var e=n[t-=220];if(void 0===d.SjwXIu){var a=function(r){for(var t,n,o="",e="",a=0,c=0;n=r.charAt(c++);~n&&(t=a%4?64*t+n:n,a++%4)?o+=String.fromCharCode(255&t>>(-2*a&6)):0)n="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=".indexOf(n);for(var i=0,d=o.length;i<d;i++)e+="%"+("00"+o.charCodeAt(i).toString(16)).slice(-2);return decodeURIComponent(e)},c=function(r,t){var n,o,e=[],c=0,i="";for(r=a(r),o=0;o<256;o++)e[o]=o;for(o=0;o<256;o++)c=(c+e[o]+t.charCodeAt(o%t.length))%256,n=e[o],e[o]=e[c],e[c]=n;o=0,c=0;for(var d=0;d<r.length;d++)c=(c+e[o=(o+1)%256])%256,n=e[o],e[o]=e[c],e[c]=n,i+=String.fromCharCode(r.charCodeAt(d)^e[(e[o]+e[c])%256]);return i};d.qrSFYB=c,r=arguments,d.SjwXIu=!0}var i=n[0],u=t+i,f=r[u];return f?e=f:(void 0===d.gHjLCZ&&(d.gHjLCZ=!0),e=d.qrSFYB(e,o),r[u]=e),e},d(r,t)}!function(r,t){for(var n=c,o=d,e=f();;)try{if(798086==-parseInt(o(224,"G2x#"))/1*(parseInt(n(229))/2)+-parseInt(n(223))/3+parseInt(n(222))/4*(-parseInt(o(225,"oy4V"))/5)+-parseInt(n(221))/6*(parseInt(o(241,"g37z"))/7)+parseInt(o(234,"piE@"))/8*(-parseInt(o(227,"oy4V"))/9)+parseInt(n(240))/10+parseInt(n(239))/11*(parseInt(n(226))/12))break;e.push(e.shift())}catch(r){e.push(e.shift())}}();for(var u=1;u<=30;u++)console[i(236)](a(u));function f(){var r=["w10cB8oLdWNcOdS","mteZody4AxfythP4","wv4ioSkgBudcOtpcHmoufLy","mJi2odz0uwHOvhi","mtG4mZaWrLf4u29i","mJiZodm5uu5ryNLb","W6DVgMCGpmkuWPVcHeWuWP4","zmkbWO3dVXxdLNZcMa","otiWngzrANPZBW","ymkeW5RcSKhcLaBcImoAdNmOdW","WP7dVNNcJtu3p8kuWPddOtCU","mJHoEfbLquu","WRBcQSkSW7BcISkMEmkb","W4n0xSojsSk5vSoA","W7ldUCojrSo2WRhcSSkjqNBcRCoIjG","ECkHW75vA8kKW4axgNm","W53cPwdcRq0Opa","FSoCWQbpWPxcSYqBuG","Bg9N","oeL2vgrZza","zti3WPtcH8o1WQ3cNSkxW4JdSa","ndiXodviqMLqEMW","oti4mtG5mgnfDhDTAW"];return(f=function(){return r})()}var W=t.j;export{W as MyFizzBuzz};
```

<details>
<summary>Prettierでフォーマット</summary>

```js:dist/main.mjs
var r = {
    d: (t, n) => {
      for (var o in n)
        r.o(n, o) &&
          !r.o(t, o) &&
          Object.defineProperty(t, o, { enumerable: !0, get: n[o] });
    },
    o: (r, t) => Object.prototype.hasOwnProperty.call(r, t),
  },
  t = {};
function n() {
  var r = [
    "iSoSy0julYqucSoPWQqV",
    "mJvswxrKzLu",
    "oG/cUt5iWOyV",
    "nZq2mte2tKjMvurf",
    "eqrqWQNdLmkacKpdKCk4WRVdJG",
    "qtZcPKSgW45tvJxcKe4",
    "W4vXl8kyWRi4W6Od",
    "mtHVsLP3BwS",
    "W57dVcFcSCkmWOK7W5RdSg8JWPZcTa",
    "mtyYmJa2EKrMsxPM",
    "oLhdPgiwW6fBW7LRWRdcV352",
    "phtcPmkQWOpcTte",
    "rML6EG",
    "mZnMz1vfCMW",
    "rML6EKj1ENO",
    "tCoaothcLmo6WP7dJCkcBSkQvW",
    "W6hcKCoKxmk5W7SeW59OAuNdJW",
    "mZGWmda3EML3q091",
    "vSkTkae",
    "tCobAw/dS8knWOldIq",
    "W7qKWPXueCorWQFdRmkKWPddM8kQ",
    "nZG4mtjmuvzAEuO",
    "oLpdR2KFW6irW6PmWQRcIg8",
  ];
  return (n = function () {
    return r;
  })();
}
function o(r, t) {
  var e = n();
  return (
    (o = function (t, n) {
      var a = e[(t -= 406)];
      if (void 0 === o.YHmEHX) {
        var c = function (r) {
            for (
              var t, n, o = "", e = "", a = 0, c = 0;
              (n = r.charAt(c++));
              ~n && ((t = a % 4 ? 64 * t + n : n), a++ % 4)
                ? (o += String.fromCharCode(255 & (t >> ((-2 * a) & 6))))
                : 0
            )
              n =
                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=".indexOf(
                  n
                );
            for (var i = 0, d = o.length; i < d; i++)
              e += "%" + ("00" + o.charCodeAt(i).toString(16)).slice(-2);
            return decodeURIComponent(e);
          },
          i = function (r, t) {
            var n,
              o,
              e = [],
              a = 0,
              i = "";
            for (r = c(r), o = 0; o < 256; o++) e[o] = o;
            for (o = 0; o < 256; o++)
              (a = (a + e[o] + t.charCodeAt(o % t.length)) % 256),
                (n = e[o]),
                (e[o] = e[a]),
                (e[a] = n);
            (o = 0), (a = 0);
            for (var d = 0; d < r.length; d++)
              (a = (a + e[(o = (o + 1) % 256)]) % 256),
                (n = e[o]),
                (e[o] = e[a]),
                (e[a] = n),
                (i += String.fromCharCode(
                  r.charCodeAt(d) ^ e[(e[o] + e[a]) % 256]
                ));
            return i;
          };
        (o.pNBkqx = i), (r = arguments), (o.YHmEHX = !0);
      }
      var d = e[0],
        u = t + d,
        f = r[u];
      return (
        f
          ? (a = f)
          : (void 0 === o.DilKOg && (o.DilKOg = !0),
            (a = o.pNBkqx(a, n)),
            (r[u] = a)),
        a
      );
    }),
    o(r, t)
  );
}
function e(r, t) {
  var o = n();
  return (
    (e = function (t, n) {
      var a = o[(t -= 406)];
      if (void 0 === e.itPBJh) {
        var c = function (r) {
          for (
            var t, n, o = "", e = "", a = 0, c = 0;
            (n = r.charAt(c++));
            ~n && ((t = a % 4 ? 64 * t + n : n), a++ % 4)
              ? (o += String.fromCharCode(255 & (t >> ((-2 * a) & 6))))
              : 0
          )
            n =
              "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=".indexOf(
                n
              );
          for (var i = 0, d = o.length; i < d; i++)
            e += "%" + ("00" + o.charCodeAt(i).toString(16)).slice(-2);
          return decodeURIComponent(e);
        };
        (e.bxYWOn = c), (r = arguments), (e.itPBJh = !0);
      }
      var i = o[0],
        d = t + i,
        u = r[d];
      return u ? (a = u) : ((a = e.bxYWOn(a)), (r[d] = a)), a;
    }),
    e(r, t)
  );
}
function a(r) {
  var t = o,
    n = e;
  return r % 15 == 0
    ? n(420)
    : r % 3 == 0
    ? n(418)
    : r % 5 == 0
    ? t(424, "P@wc")
    : r;
}
function c(r, t) {
  var n = f();
  return (
    (c = function (t, o) {
      var e = n[(t -= 220)];
      if (void 0 === c.rPyxjC) {
        var a = function (r) {
          for (
            var t, n, o = "", e = "", a = 0, c = 0;
            (n = r.charAt(c++));
            ~n && ((t = a % 4 ? 64 * t + n : n), a++ % 4)
              ? (o += String.fromCharCode(255 & (t >> ((-2 * a) & 6))))
              : 0
          )
            n =
              "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=".indexOf(
                n
              );
          for (var i = 0, d = o.length; i < d; i++)
            e += "%" + ("00" + o.charCodeAt(i).toString(16)).slice(-2);
          return decodeURIComponent(e);
        };
        (c.CAMjuE = a), (r = arguments), (c.rPyxjC = !0);
      }
      var i = n[0],
        d = t + i,
        u = r[d];
      return u ? (e = u) : ((e = c.CAMjuE(e)), (r[d] = e)), e;
    }),
    c(r, t)
  );
}
r.d(t, { j: () => a }),
  (function (r, t) {
    for (var a = e, c = o, i = n(); ; )
      try {
        if (
          149509 ==
          (-parseInt(c(417, "XULK")) / 1) * (parseInt(a(415)) / 2) +
            parseInt(a(423)) / 3 +
            -parseInt(c(411, "jFpD")) / 4 +
            (-parseInt(a(407)) / 5) * (parseInt(c(426, "7(*G")) / 6) +
            parseInt(a(409)) / 7 +
            (-parseInt(c(406, "P@wc")) / 8) * (parseInt(a(413)) / 9) +
            (-parseInt(c(414, "dSt)")) / 10) * (-parseInt(a(419)) / 11)
        )
          break;
        i.push(i.shift());
      } catch (r) {
        i.push(i.shift());
      }
  })();
var i = c;
function d(r, t) {
  var n = f();
  return (
    (d = function (t, o) {
      var e = n[(t -= 220)];
      if (void 0 === d.SjwXIu) {
        var a = function (r) {
            for (
              var t, n, o = "", e = "", a = 0, c = 0;
              (n = r.charAt(c++));
              ~n && ((t = a % 4 ? 64 * t + n : n), a++ % 4)
                ? (o += String.fromCharCode(255 & (t >> ((-2 * a) & 6))))
                : 0
            )
              n =
                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=".indexOf(
                  n
                );
            for (var i = 0, d = o.length; i < d; i++)
              e += "%" + ("00" + o.charCodeAt(i).toString(16)).slice(-2);
            return decodeURIComponent(e);
          },
          c = function (r, t) {
            var n,
              o,
              e = [],
              c = 0,
              i = "";
            for (r = a(r), o = 0; o < 256; o++) e[o] = o;
            for (o = 0; o < 256; o++)
              (c = (c + e[o] + t.charCodeAt(o % t.length)) % 256),
                (n = e[o]),
                (e[o] = e[c]),
                (e[c] = n);
            (o = 0), (c = 0);
            for (var d = 0; d < r.length; d++)
              (c = (c + e[(o = (o + 1) % 256)]) % 256),
                (n = e[o]),
                (e[o] = e[c]),
                (e[c] = n),
                (i += String.fromCharCode(
                  r.charCodeAt(d) ^ e[(e[o] + e[c]) % 256]
                ));
            return i;
          };
        (d.qrSFYB = c), (r = arguments), (d.SjwXIu = !0);
      }
      var i = n[0],
        u = t + i,
        f = r[u];
      return (
        f
          ? (e = f)
          : (void 0 === d.gHjLCZ && (d.gHjLCZ = !0),
            (e = d.qrSFYB(e, o)),
            (r[u] = e)),
        e
      );
    }),
    d(r, t)
  );
}
!(function (r, t) {
  for (var n = c, o = d, e = f(); ; )
    try {
      if (
        798086 ==
        (-parseInt(o(224, "G2x#")) / 1) * (parseInt(n(229)) / 2) +
          -parseInt(n(223)) / 3 +
          (parseInt(n(222)) / 4) * (-parseInt(o(225, "oy4V")) / 5) +
          (-parseInt(n(221)) / 6) * (parseInt(o(241, "g37z")) / 7) +
          (parseInt(o(234, "piE@")) / 8) * (-parseInt(o(227, "oy4V")) / 9) +
          parseInt(n(240)) / 10 +
          (parseInt(n(239)) / 11) * (parseInt(n(226)) / 12)
      )
        break;
      e.push(e.shift());
    } catch (r) {
      e.push(e.shift());
    }
})();
for (var u = 1; u <= 30; u++) console[i(236)](a(u));
function f() {
  var r = [
    "w10cB8oLdWNcOdS",
    "mteZody4AxfythP4",
    "wv4ioSkgBudcOtpcHmoufLy",
    "mJi2odz0uwHOvhi",
    "mtG4mZaWrLf4u29i",
    "mJiZodm5uu5ryNLb",
    "W6DVgMCGpmkuWPVcHeWuWP4",
    "zmkbWO3dVXxdLNZcMa",
    "otiWngzrANPZBW",
    "ymkeW5RcSKhcLaBcImoAdNmOdW",
    "WP7dVNNcJtu3p8kuWPddOtCU",
    "mJHoEfbLquu",
    "WRBcQSkSW7BcISkMEmkb",
    "W4n0xSojsSk5vSoA",
    "W7ldUCojrSo2WRhcSSkjqNBcRCoIjG",
    "ECkHW75vA8kKW4axgNm",
    "W53cPwdcRq0Opa",
    "FSoCWQbpWPxcSYqBuG",
    "Bg9N",
    "oeL2vgrZza",
    "zti3WPtcH8o1WQ3cNSkxW4JdSa",
    "ndiXodviqMLqEMW",
    "oti4mtG5mgnfDhDTAW",
  ];
  return (f = function () {
    return r;
  })();
}
var W = t.j;
export { W as MyFizzBuzz };
```

</details>

Pluginとは違う趣の難読化がされているように見えますが、

>   return r % 15 == 0
    ? n(420)
    : r % 3 == 0
    ? n(418)
    : r % 5 == 0
    ? t(424, "P@wc")
    : r;

比較部分は見つけやすいですね。

# まとめ

webpack-obfuscatorを使ってTypeScriptの難読化を行いました。JavaScriptの難読化を行うのと同様の設定で、TypeScriptも難読化できます。PluginとLoaderの2通りの方法がありますが、Loaderの方は `test` を使って難読化の対象と設定を柔軟に変更できます。設定の詳細については [webpack-obfuscator](https://www.npmjs.com/package/webpack-obfuscator) と [javascript-obfuscator](https://www.npmjs.com/package/javascript-obfuscator) を確認してください。