🗂

Viteでpolyfillを追加する方法

2022/05/02に公開

もともとParcel 2を利用していましたが、自分のプロジェクトではReactのLazy importをするとHMRが働かないことがあり、Viteも気になっていたため移行することにしました。
Parcelではpolyfillも自動で追加してくれていたので、気にしてなかったのですが、Viteでは自分で追加する必要があるようです。

私の場合は、csv-parse というライブラリをブラウザで使っており、それが内部で streamprocessなどを参照していました。

まず、esbuildのpolyfillを追加するプラグインが必要です。
@esbuild-plugins/node-globals-polyfill, @esbuild-plugins/node-modules-polyfill

yarn add --dev @esbuild-plugins/node-globals-polyfill @esbuild-plugins/node-modules-polyfill

それをViteのconfigに紐づけてあげることで、Polyfillできます。

vite.config.ts
/* eslint-disable import/no-extraneous-dependencies */
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { NodeGlobalsPolyfillPlugin } from '@esbuild-plugins/node-globals-polyfill'
import * as path from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      'src/': path.join(__dirname, 'src/'),
      stream: 'rollup-plugin-node-polyfills/polyfills/stream',
      _stream_duplex: 'rollup-plugin-node-polyfills/polyfills/readable-stream/duplex',
      _stream_passthrough: 'rollup-plugin-node-polyfills/polyfills/readable-stream/passthrough',
      _stream_readable: 'rollup-plugin-node-polyfills/polyfills/readable-stream/readable',
      _stream_writable: 'rollup-plugin-node-polyfills/polyfills/readable-stream/writable',
      _stream_transform: 'rollup-plugin-node-polyfills/polyfills/readable-stream/transform'
    }
  },
  optimizeDeps: {
    esbuildOptions: {
      define: {
        global: 'globalThis'
      },
      // Enable esbuild polyfill plugins
      // https://medium.com/@ftaioli/using-node-js-builtin-modules-with-vite-6194737c2cd2
      plugins: [
        NodeGlobalsPolyfillPlugin({
          process: true,
          buffer: true
        })
      ]
    }
  },
  build: {
    target: 'esnext'
  }
})

こちらの記事がとても参考になります。その他のpolyfillを追加する場合など、以下を参考にするといいと思います。
https://medium.com/@ftaioli/using-node-js-builtin-modules-with-vite-6194737c2cd2

ただ、自分の場合はこれだけでは動かなくて Buffer を追加する必要がありました。
Bufferのpolyfillを追加するには、vite.config.tsではなく直接コードに追加する必要があるようです。

これをトップレベルのファイルにimportさせることで解決できました。

polyfill.ts
import { Buffer } from 'buffer'

// for csv-parse polyfill
// https://github.com/vitejs/vite/discussions/2785
globalThis.Buffer = Buffer

https://github.com/vitejs/vite/discussions/2785

Discussion