amCharts の pdfmake を webpack の externals に指定する

# amCharts の pdfmake を webpack の externals に指定する

amCharts を React のプロジェクトに使用したところ、 GitHub Actions にて以下のようなエラーが発生

```bash
{file path} is {file size} MB, and won't be precached. Configure maximumFileSizeToCacheInBytes to change this limit.
```

構成は以下の通り

```json:package.json
{
  "dependencies": {
    "@amcharts/amcharts4": "^4.9.35",
    "webpack": "4.43.0"
  },
}
```

## amCharts 配下の pdfmake が原因？

- amCharts にて `maximumFileSizeToCacheInBytes` での問題が発生する旨の issue  
  [Dependency sizes #569 - amCharts/amCharts4](https://github.com/amcharts/amcharts4/issues/569)

上記によると amCharts で使用の `pdfmake` などが `maximumFileSizeToCacheInBytes` を超過しているとのこと

## ビルドのファイルサイズの確認

[source-map-explorer](https://www.npmjs.com/package/source-map-explorer) で確認

- 当初 `npm run build -- --stats` にてファイルサイズを取得しようとしたが  
  廃止されていたとのことで `source-map-explorer` を使用に切替  
  [How to build bundle-stats.json in create react app? - stackoverflow](https://stackoverflow.com/questions/58112616/how-to-build-bundle-stats-json-in-create-react-app)

![pdfmake.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116435/46fca468-9d82-71a7-8a20-5e9742be66b7.png)

確かに pdfmake (ほかに xlsx) のサイズが大きいことを確認

## webpack の externals を指定によりビルドに含まないように・・・

前述の [Dependency sizes #569 - amCharts/amCharts4](https://github.com/amcharts/amcharts4/issues/569) にて、
webpack の `externals` を指定することによりビルドから除外できるとあったので再度ビルド

```js:webpack.exterals
    externals: {
      pdfmake: 'pdfmake',
      xlsx: 'xlsx',
      canvg: 'canvg',
    },
```

再確認したところ以下にて、

![pdfmake-not-excluded.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116435/a0b78647-f9d0-07d9-8af8-bf1c72a4ca36.png)

減っていない・・・

### externals を関数で指定する

前述の issue をよく見たところ、 `externals` の関数形式での指定を行うとよいとのこと

```js:webpack.externals.function
    externals: [
      /(xlsx|canvg)/,
      function (context, request, callback) {
        if (/(pdfmake)/.test(request)) {
          return callback(null, 'commonjs ' + request);
        }
        callback();
      },
    ],
```

こちらの記述は公式のドキュメントにもありました。
[Large file sizes - Using Webpack - amCharts 4 Documentation](https://www.amcharts.com/docs/v4/getting-started/integrations/using-webpack/#Large_file_sizes)

```js:webpack.externals.function.official
  externals: function (context, request, callback) {
    if (/xlsx|canvg|pdfmake/.test(request)) {
      return callback(null, "commonjs " + request);
    }
    callback();
  }
```

これを適用して再試行

```bash:compile-error
chunk runtime-main [entry]
Cannot convert undefined or null to object
```

なんかエラーが・・・

### pdfmake の記述を詳細にする必要がある？

`externals` の指定をいじってみていたところ、 `pdfmake` 以外の `xlsx` などは記述通りで除外されることを確認
そこで `source-map-explorer` の出力を見直してみていたところ、 `pdfmake` の表示には `xlsx` と差異があることに気づく

![pdfmake.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116435/8ed6372a-6eac-fb0e-c23c-3f29a473e424.png)

![xlsx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116435/64898f36-2cc1-848f-1f0c-7f2831266fc4.png)

これ `externals` の正規表現に変更を加えないといけないのかと思い、以下のように

```js:webpack.externals.function.pdfmake-detailed
    externals: function (context, request, callback) {
      if (/xlsx|canvg|pdfmake[/]build|[.]internal[/]pdfmake/.test(request)) {
        return callback(null, 'commonjs ' + request);
      }
      callback();
    },
```

- 表示される `pdfmake` の 2 種類である以下に合致するように変更
    - `pdfmake/build/pdfmake.js`
    - `src/.internal/pdfmake/vfs_fonts.ts`

再度実行し・・・正常に終了
`source-map-explorer` にて確認したところ、

![pdfmake-excluded.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116435/108e46c3-f007-e1da-20a9-1070ce8e6021.png)

やったぜ。
`pdfmake` がなくなっていることを確認

しかしなんとなく設定していた Jest により GitHub Actions はこけていたところでいったん終了

・・・と思ったら `vfs_fonts` のほうはしっかり残留してしまっていた・・・

![vfs_fonts.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116435/7885eec8-bf20-45e4-3ca3-24f2fdde7469.png)

とりあえず有効となった記述について

```js:webpack.externals.function.pdfmake-detailed-valid
    externals: function (context, request, callback) {
      if (/xlsx|canvg|pdfmake[/]build/.test(request)) {
        return callback(null, 'commonjs ' + request);
      }
      callback();
    },
```

## Jest のエラーについて

Angular でも発生した事例
[SyntaxError: Unexpected token 'export' with jest in Angular 9 project #2471 - amCharts/amCharts4](https://github.com/amcharts/amcharts4/issues/2471)

```bash:jest-error
    Details:

    ～\node_modules\@amcharts\amcharts4\charts.js:7
    export { GaugeChartDataItem, GaugeChart } from "./.internal/charts/types/GaugeChart";     
    ^^^^^^

    SyntaxError: Unexpected token 'export'
```

[Using amCharts with Jest - amCharts 4 Documentation](https://www.amcharts.com/docs/v4/getting-started/using-typescript-or-es6/#Using_amCharts_with_Jest)

>
- amCharts が svg 使っているけど Jest では svg 対応していないよ
- [use Puppeteer with Jest](https://jestjs.io/docs/en/puppeteer)