1年ほど前に、workbox-webpack-plugin v2 で PWA の設定を行いました。
webpack v3 から v4 へアップデートするにあたって、workbox-webpack-plugin の version を確認したところ、v2 から v3 へアップデートしていたので、そちらもアップデートを実施しました。

実施したことを記載します。


前提

  • アップデート前の workbox 関連パッケージの状況
    workbox-sw と、workbox-webpack-plugin使用しています。

    % npm outdated | grep workbox
    workbox-sw                    2.1.3    2.1.3       3.6.3  mutter.monotalk.xyz
    workbox-webpack-plugin        2.1.3    2.1.3       3.6.3  mutter.monotalk.xyz
    

  • アップデート対象のアプリの workbox の使い
    workbox-webpack-plugin を generateSW で使用しています。
    自前で workbox を使った処理は実装しておらず、自動生成された ServieWorker で Cache 機能のみ使用しています。


アップデート

以下、手順でアップデートしました。

  • package.json の更新

      "devDependencies": {
        ..
        "workbox-sw": "^3.6.3",
        "workbox-webpack-plugin": "^3.6.3"
        ..
    }
    

  • npm コマンドの実行

    npm install
    
    added 26 packages from 13 contributors and updated 5 packages in 22.332s
    


対応方針

Migrate from Workbox v2 to v3  |  Workbox  |  Google Developers には、workbox-webpack-plugin について以下の記載があります。

  • APIが、GenerateSWとInjectManifestの2つのクラスに別れた。

  • webpack ビルドに含まれていないアセットがなければ、globPatterns の設定は不要になった。

しかし内容がよく理解できなかったので、とりあえずビルドしてみて発生したエラーに対処していく方針としました。


発生したエラーと対処した内容

以下、発生したエラーと対象した内容を記載します。

  • TypeError: WorkboxPlugin is not a constructor
    workbox-webpack-plugin v2 では、WorkboxPlugin を インスタンス化して使用する作りでしたが、workbox-webpack-plugin v3 では、GenerateSW をインスタンス化して使うようになりました。
    Example を貼り付けますが、以下のような記載になります。

    // Inside of webpack.config.js:
    const {GenerateSW} = require('workbox-webpack-plugin');
    
    module.exports = {
      // Other webpack config...
      plugins: [
        // Other plugins...
        new GenerateSW({
          option: 'value',
        })
      ]
    };
    

  • ValidationError: child “runtimeCaching” fails because [“runtimeCaching” at position 0 fails because [“cacheName” is not a supported parameter., “cacheExpiration” is not a supported parameter.]]
    これは、runtimeCaching記載方法が変更になったので発生しました。
    無効な設定があると、ビルドが失敗するようになっているようです。
    options 内に、cacheName を移動しました。

  • ValidationError: child “runtimeCaching” fails because [“runtimeCaching” at position 0 fails because [child “options” fails because [“cacheExpiration” is not a supported parameter.]]]
    cacheExpiration キー名が expirationなっているようです。
    キー名を変更して対応しました。

  • WARNING in You’re using the following Workbox configuration options: [globDirectory, globPatterns]. In Workbox v3 and later, this is usually not needed. Please see https://goo.gl/EQ4Rhm for more info.
    globDirectory、globPattern は v3 では 大抵の場合、いらないという警告になります。
    これはマイグレーションガイドに記載があった内容ですね。
    workbox-webpack-plugin の v3 からは precache-manifestいうファイルを生成するようになり、このファイルが空気を読んで Cache が必要なファイルを読み込んでくれます。
    precache-manifest生成内容を見る限り、削除して問題なさそうでしたので、globDirectory、globPattern の指定を削除しました。

  • WARNING in One of the glob patterns doesn’t match any files. Please remove or fix the following
    globDirectory、globPattern の設定で マッチするファイルがなかった場合に出力される警告です。

    WARNING in One of the glob patterns doesn't match any files. Please remove or fix the following: {
      "globDirectory": "/xxxxxx",
      "globPattern": "static/webpack_bundles/*.png",
      "globIgnores": [
        "**/node_modules/**/*"
      ]
    }
    
    globDirectory、globPattern の記載を削除したことで警告は出力されなくなりました。


エラーにはならなかったが、調整したところ

エラーにはなりませんでしたが、もともと ServiceWorker の出力ディレクトリを、swDest: distBase + "/templates/CacheWorker.js"指定していました。
Webpack でビルドしたリソースの出力先 と ServiceWorker の出力先が一致しないと precache-manifest の importScripts のパスが実際にファイルの存在するパスになりません。 このため、publicPath を指定して importScripts の出力パスを変更しました。

    output: {
        path: distBase + "/static/webpack_bundles/",
        library: "Main",
        filename: "[name]-[hash].js",
        publicPath: "/static/webpack_bundles/"
    },


気になった設定、機能

エラーが解消して、うまく動作しました。
v3 のドキュメントを確認したところ、特に設定は不要でしたが、個人的に興味深い設定が幾つかありましたので記載します。
* importWorkboxFrom
default が cdn の設定になっていて、cdn の場合は Google Cloud Storage 上の JavaScript ファイルを importScripts するようになります。

  • importScripts
    v2 だと、指定できなかった気がします。GenerateSW で importScripts するスクリプトを指定できるようになりました。

  • offlineGoogleAnalytics
    true にすると、workbox.googleAnalytics 初期化を行うコードを追加してくれます。

  • manifestTransforms
    __precacheManifest記載される URL の 変更ルールを実装できます。

v2 から結構進化しており、v4 が現在 beta版で2019 年 じゅうには beta が取れそうな気もします。
個人的に今後の機能追加が楽しみに思います。
v4 Milestone


webpack.config.js の修正差分

以下のようになりました。変更箇所のみ抜粋します。

  • GenerateSW を使用する

    -const WorkboxPlugin = require("workbox-webpack-plugin");
    +const {GenerateSW} = require('workbox-webpack-plugin');
    

  • publicPath の設定

         output: {
             path: distBase + "/static/webpack_bundles/",
             library: "Main",
    -        filename: "[name]-[hash].js"
    +        filename: "[name]-[hash].js",
    +        publicPath: "/static/webpack_bundles/"
         },
    

  • GenerateSW を使用する、options に設定するキー値の変更

    -        new WorkboxPlugin({
    -            globDirectory: distBase,
    -            globPatterns: [
    -                "static/js/**/*.js",
    -                "static/css/**/*.css",
    -                "static/webpack_bundles/*.png"
    -            ],
    +        new GenerateSW({
                 runtimeCaching: [
                     {
                         urlPattern: /\/api\/v2\/.+/,
                         handler: "networkFirst",
    -                    "cacheName": "api",
    -                    "cacheExpiration": {
    -                        "maxAgeSeconds": 60 * 60 * 24, "maxEntries": 20
    -                    },
                         options: {
    +                        expiration: {
    +                            maxAgeSeconds: 60 * 60 * 24, 
    +                            maxEntries: 20
    +                        },
    +                        cacheName: "api",
                             cacheableResponse: {
                                 statuses: [0, 200]
                             }
    


参考

以下、作業実施時に参考にした記事になります。

以上です。

コメント