Snowpackの@snowpack/plugin-optimizeとmodulepreload

UI開発者 古川

snowpack@2.11.1がリリースされました。今回のUpdateに@snowpack/plugin-optimizeという新しいプラグインが追加されています。

今回はこのプラグインの使い方と、このプラグインに備わっている<link rel="modulepreload">の自動挿入について紹介します。

@snowpack/plugin-optimizeのインストールと設定

すでにSnowpackが導入されているプロジェクトに@snowpack/plugin-optimizeを以下のコマンドで導入します。

npm install --save-dev @snowpack/plugin-optimize

続いてsnowpack.config.jsonに以下を追加します。オプションの詳細はパッケージの説明を参照してください。

{
  "plugins": [
    ["@snowpack/plugin-optimize", { /* options */ }]
  ]
}

HTML・CSS・JavaScriptのminifyとJSトランスパイル

@snowpack/plugin-optimizeは、HTMLMinifierでHTML、CSSOでCSS、esbuildでJSをそれぞれminifyします。プラグインを1つインストールするだけでおのおの整形できるのは便利ですね。個々の機能はデフォルトで有効化されているため、無効化する場合はオプションで設定を行います。

{
  "plugins": [
    ["@snowpack/plugin-optimize", {
        "minifyHTML": false, // 無効化する場合はfalseを設定する
        "minifyCSS": false,
        "MinifyJS": false
    }]
  ]
}

また、esbuildを利用したトランスパイルも利用可能です。オプションのtargetにブラウザのバージョンか、ES6以上のECMAScriptのバージョンを設定します。

{
  "plugins": [
    ["@snowpack/plugin-optimize", {
        "target": ["chrome85", "firefox81"]
    }]
  ]
}

targetに設定する値についての詳細はesbuildのREADMEを参照してください。

<link rel="modulepreload">

各リソースのminifyやJSトランスパイルに加え、@snowpack/plugin-optimizeには<link rel="modulepreload">を使ったES Modulesのプリロードの自動実装も備わっています。SnowpackはJavaScriptの読み込みにES Modulesを採用しており、オプションのpreloadModulesを有効化すると、利用しているモジュールや依存関係にあるスクリプトを<link rel="modulepreload">で自動挿入します。

<link rel="modulepreload">はResource Hintsの1つで、記述することでES Modulesを先行してロードするようブラウザに伝えることができます。

<head>
  <link rel="modulepreload" href="/web_modules/module-hoge.js">
  <link rel="modulepreload" href="/web_modules/module.js">
</head>
<body>
  <!-- ... -->
  <script type="module" src="/js/app.js">
</body>

この機能はデフォルトで無効化されているため、有効化する場合は以下のようにオプションを設定します。

{
  "plugins": [
    ["@snowpack/plugin-optimize", {
        "preloadModules": true
    }]
  ]
}

<link rel="modulepreload">と似ているResource Hintsの機能でrel="preload"があります。しかし、ES Modulesを<link rel="preload" as="script">で読み込もうとした場合、いくつかの問題が存在します

例えば、<link rel="preload" as="script">ではコードはコンパイルされず、モジュールとしてではなく単なるスクリプトとしてキャッシュされます。そして実際にモジュールが読み込まれる段階で解析やコンパイルを行います。しかし<link rel="modulepreload">を利用すれば、ブラウザはプリフェッチされたファイルがモジュールだと認識するため、プリフェッチした段階でモジュールの解析およびコンパイルを行います。

<link rel="modulepreload">は現在Google Chrome最新版、Microsoft Edge最新版で対応しています。

まとめ

ES Modulesはすでにモダンブラウザで利用が可能なため、開発環境の選択肢としてSnowpackを本格的に導入検討できるのではないでしょうか。今後もSnowpackの動向に注目していきたいです。