やしログ

ビルドツール素振り(Snowpack編)

created: 2021/05/09
Snowpack を素振りしてみました。

Snowpack を使ったビルド設定をやってみる

ベースは ここ から。

まずはインストールします。

$ yarn add -D snowpack

snowpack init して、 snowpack.config.js を作成します。

$ yarn snowpack init

設定を追記します。(port は別に何でもよいのですが・・・w)

module.exports = {
+  mount: {
+    'public': { url: '/', static: true },
+    'src': { url: '/dist' }
+  },
   plugins: [
     /* ... */
   ],
+  devOptions: {
+    port: 2424
+  },
};

package.json を変更します。

"scripts": {
-    "start": "echo start",
+    "start": "snowpack dev",
     "build": "echo build",
     "test": "echo test"
   },

この状態で yarn start すると、以下のようなエラーが発生します。

$ yarn start
[24:38:47] [esinstall:css] /frontend-build-tools/snowpack/node_modules/css/lib/stringify/source-map-support.js
   Module "path" (Node.js built-in) is not available in the browser. Run Snowpack with --polyfill-node to fix.
[24:38:47] [esinstall:css] /frontend-build-tools/snowpack/node_modules/css/lib/stringify/source-map-support.js
   Module "fs" (Node.js built-in) is not available in the browser. Run Snowpack with --polyfill-node to fix.
[24:38:47] [esinstall:css] /frontend-build-tools/snowpack/node_modules/css/lib/stringify/source-map-support.js
   Module "fs" (Node.js built-in) is not available in the browser. Run Snowpack with --polyfill-node to fix.
[24:38:47] [esinstall:css] /frontend-build-tools/snowpack/node_modules/css/lib/stringify/source-map-support.js
   Module "path" (Node.js built-in) is not available in the browser. Run Snowpack with --polyfill-node to fix.
[24:38:47] [esinstall:css] fs?commonjs-external
   Module "fs" (Node.js built-in) is not available in the browser. Run Snowpack with --polyfill-node to fix.
[24:38:47] [esinstall:css] path?commonjs-external
   Module "path" (Node.js built-in) is not available in the browser. Run Snowpack with --polyfill-node to fix.
(node:81379) UnhandledPromiseRejectionWarning: Error: Install failed.
    at Object.install (/frontend-build-tools/snowpack/node_modules/snowpack/lib/index.js:44201:23)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async Object.installPackages (/frontend-build-tools/snowpack/node_modules/snowpack/lib/index.js:54309:25)
    at async inProgressBuilds.add.priority (/frontend-build-tools/snowpack/node_modules/snowpack/lib/index.js:54709:64)
    at async run (/frontend-build-tools/snowpack/node_modules/snowpack/lib/index.js:46988:29)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:81379) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:81379) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

エラー文にある通り、 packageOptions.polyfillNode を true にすると対処できるのですが、このオプションの説明の最後にこのような記述があります。

When source="remote", Node.js polyfills are always provided. Configuring this option is only supported in source="local" mode.

この説明にある sourcepackageOptions.source のことを指していて、アプリケーションで必要な npm packages をどこから参照するか指定するオプションになっています。

  • local: ローカルの node_modules/ ディレクトリから読み込む。他のビルドツールと同じ、一般的な挙動です。
  • remote: Snowpack が提供する CDN (つまり Skypack )から読み込む。 Snowpack 特有の機能です。

source オプションの値によって、指定できる packageOptions に違いがあります。おそらく v3 から新しく加わったオプションなのでしょうか...?(未確認)

今は v2 との後方互換性など諸々の事情から source="local" がデフォルトになっていますが、 Snowpack の思惑として、将来的にはデフォルトが source="remote" に移っていくのではないかと思います(個人の意見です)。そのため、Snowpack を利用する上で source オプションの挙動を把握しておくことは重要だと思いました。

先のエラーの対処に話を戻すと、 packageOptions.source オプションは デフォルトで local になっている ため、 packageOptions.polyfillNode を指定することができます。従ってこれを true にすることで、 fspath などに polyfill が効いてビルドできるようになる、ということでした。

production 向けには、ソースマップの出力だけ試してみました。

   devOptions: {
     port: 2424
   },
+  buildOptions: {
+   sourcemap: true  // experimental option
+ },
};
"scripts": {
     "start": "snowpack dev",
-    "build": "echo build",
+    "build": "snowpack build",
     "test": "echo test"
   },

buildOptions.sourcemap は experimental でしたが、一応ソースマップを出力できることは確認できました。

まとめ

Snowpack が将来的に実現したい「バンドルの必要ない世界」と、足元の「バンドルが必要な世界」との兼ね合いから、どうしても設定が分かりにくくなっている面があると感じました。 Snowpack の目指す方向性としては期待が持てるので(めちゃめちゃ時間がかかりそうだけど...)、今後どう発展していくか気になります。

ここまでの結果は下記に置いています。