QwikCityでSupabase(Cannot bundle Node.js built-in "stream"の解消)

2023/08/27に公開

TL;DR

  1. 以下のコマンドを実行してパッケージをインストールする。
npm install assert buffer events stream-http https-browserify punycode stream-browserify url util browserify-zlib
  1. vite.config.jsに以下の行を追加する。
vite.config.js
export default defineConfig(() => {
  return {
    build: {
      rollupOptions: {
        output: {
          manualChunks: {
            supabase: ["@supabase/supabase-js"],
          },
        },
      },
    },
    resolve: {
      alias: {
        assert: "assert",
        buffer: "buffer",
        events: "events",
        http: "stream-http",
        https: "https-browserify",
        punycode: "punycode",
        stream: "stream-browserify",
        url: "url",
        util: "util",
        zlib: "browserify-zlib",
      },
    },
    // ...
  };
});

背景

先日mizchiさんがQwik/QwikCityを推しているのを見て、すぐに試してみることにしました。「最強」なんて言われたら、否応なしに飛びつきたくなってしまうのが人の性です。
https://zenn.dev/mizchi/articles/micro-frontend-qwik

mizchiさんは「まずは薄く使え」と言われてましたが、最強ならまるごと使ってみたくなるじゃないですか。そこでフロントエンドにはがっつりQwikCity、データベースにはいつものようにSupabaseを使うことにしました。ところが、ビルドするとエラーが出ます。どうやら、@supabase/supabase-jsで使われているNode.js組み込みAPIをQwikCityがサポートしていないようです。

[commonjs--resolver]  Cannot bundle Node.js built-in "stream" imported from "node_modules/.pnpm/@supabase+node-fetch@2.6.13/node_modules/@supabase/node-fetch/lib/index.mjs". Consider disabling ssr.noExternal or remove the built-in dependency.
error during build:
RollupError: Cannot bundle Node.js built-in "stream" imported from "node_modules/.pnpm/@supabase+node-fetch@2.6.13/node_modules/@supabase/node-fetch/lib/index.mjs". Consider disabling ssr.noExternal or remove the built-in dependency.
    at error (ROOT_DIR/node_modules/.pnpm/rollup@3.28.1/node_modules/rollup/dist/es/shared/node-entry.js:2287:30)
    at Object.error (ROOT_DIR/node_modules/.pnpm/rollup@3.28.1/node_modules/rollup/dist/es/shared/node-entry.js:25268:20)
    at Object.resolveId (ROOT_DIR/node_modules/.pnpm/vite@4.4.9_@types+node@20.5.6/node_modules/vite/dist/node/chunks/dep-df561101.js:28193:34)
    at Object.handler (ROOT_DIR/node_modules/.pnpm/vite@4.4.9_@types+node@20.5.6/node_modules/vite/dist/node/chunks/dep-df561101.js:48234:19)
    at ROOT_DIR/node_modules/.pnpm/rollup@3.28.1/node_modules/rollup/dist/es/shared/node-entry.js:25461:40
    at async PluginDriver.hookFirstAndGetPlugin (ROOT_DIR/node_modules/.pnpm/rollup@3.28.1/node_modules/rollup/dist/es/shared/node-entry.js:25361:28)
    at async resolveId (ROOT_DIR/node_modules/.pnpm/rollup@3.28.1/node_modules/rollup/dist/es/shared/node-entry.js:24035:26)
    at async ModuleLoader.resolveId (ROOT_DIR/node_modules/.pnpm/rollup@3.28.1/node_modules/rollup/dist/es/shared/node-entry.js:24449:15)
    at async Object.resolveId (ROOT_DIR/node_modules/.pnpm/vite@4.4.9_@types+node@20.5.6/node_modules/vite/dist/node/chunks/dep-df561101.js:7890:15)
    at async PluginDriver.hookFirstAndGetPlugin (ROOT_DIR/node_modules/.pnpm/rollup@3.28.1/node_modules/rollup/dist/es/shared/node-entry.js:25361:28)

そこで対応するNode.js組み込みAPIをbrowserifyのブラウザ互換ライブラリで書き換えていきます。幸い、browserifyのGithubレポジトリに対応ライブラリが全て載っていました。
https://github.com/browserify/browserify

対応ライブラリをインストールした後はvite.config.jsでエイリアスを設定して、Node.jsの組み込みAPIが呼び出された時にbrowserifyを参照させます。

これで十分動くようにはなるのですが、ビルド後のJSが大きすぎると文句を言われるので、@supabase/supabase-jsを参照するファイルをまとめておくようにしておきます。

(!) Some chunks are larger than 500 kBs after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.

実はこれでもRollupビルド時には警告を吐くのですが、まあ、Viteビルドが終わればJSファイルが全て500KBより小さくなるのでいいでしょう。

過去記事

ChatGPT/OpenAI APIシリーズ
https://zenn.dev/niwatoro/articles/51f22ab69e0c9b
https://zenn.dev/niwatoro/articles/180f6185c382bb

Discussion