workbox-webpack-plugin 的 InjectManifest 仅适用于 `devtoolModuleFilenameTemplate: 'file:///[absolute-resource-path]'`

workbox-webpack-plugin's InjectManifest only works with `devtoolModuleFilenameTemplate: 'file:///[absolute-resource-path]'`

我想使用 workbox-webpack-plugin 来包含我自己的 service worker。但是,除非我使用输出选项 devToolModuleFilenameTemplate,否则使用 InjectManifest 不起作用。 似乎 library: "[name]" 是与 workbox-webpack-plugin 组合的失败配置。为什么在使用 library: "[name]" 选项时必须设置 devToolModuleFilenameTemplate

重现错误的最小项目

https://gitlab.com/d.kuhnke/workbox-webpack-plugin-problem

NPM 依赖项

  "devDependencies": {
    "ts-loader": "^8.1.0",
    "webpack": "^5.31.2",
    "webpack-cli": "^4.6.0",
    "webpack-merge": "^5.7.3",
    "workbox-webpack-plugin": "^6.1.2"
  }

配置失败 (webpack.common.js / webpack.prod.js)

const path = require('path');
const { InjectManifest } = require('workbox-webpack-plugin');

module.exports = {
    entry: {
        Test: './src/index.js'
    },
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist'),
        library: "[name]", // this is the line which makes problems
        clean: true,
    },
    plugins: [
        new InjectManifest({
            swSrc: './src/test-offline-worker.js'
        }),
    ],
    watchOptions: {
        ignored: ['dist', '**/node_modules']
    },
    mode: 'development',
    devtool: 'source-map', // production source map
};

工作配置(webpack.dev.js

const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');

const path = require('path');

module.exports = merge(common, {
    output: { // InjectManifest only works with this setting
        devtoolModuleFilenameTemplate: 'file:///[absolute-resource-path]'  // map to source with absolute file path not webpack:// protocol
    },
});

配置失败的错误消息

PS C:\Users\USERNAME\dev\git\personal\webpack-problem> npm run build:prod

> webpack-problem@1.0.0 build:prod
> webpack --config webpack.prod.js

asset Test.bundle.js 618 bytes [compared for emit] (name: Test) 1 related asset
asset test-offline-worker.js 300 bytes [emitted] 1 related asset
./src/index.js 1 bytes [built] [code generated]

ERROR in Invalid URL: webpack://[name]/./src/test-offline-worker.js

webpack 5.31.2 compiled with 1 error in 104 ms
npm ERR! code 1
npm ERR! path C:\Users\USERNAME\dev\git\personal\webpack-problem
npm ERR! command failed
npm ERR! command C:\Windows\system32\cmd.exe /d /s /c webpack --config webpack.prod.js

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\USERNAME\scoop\persist\nodejs\cache\_logs21-04-12T14_28_43_806Z-debug.log

更新 (2021-05-18)

正如 Jeff Posnick 所解释的,问题是缺少替换占位符字符串 [name]。解决方案/解决方法是将 output.devtoolNamespace 设置为常量值,如 here.

所述

这里有几件事在起作用。

首先,当 output.library 设置为 '[name]' 时,webpack 的 sourcemap 生成器似乎无法正常工作,与 Workbox 无关:

如果您从“失败的配置”示例中注释掉 InjectManifest 插件,那么它将生成一个源映射,其中包含:

{"sources":["webpack://[name]/./src/index.js"], ...}

我认为这也不成立。它不会触发编译错误,但它不是预期的输出。这将是向 webpack 团队提出的问题。

其次,当您将 InjectManifest 插件添加到生成库输出的编译时,我想不出一个有效的用例。使用 InjectManfest 创建的 service worker 应该预缓存给定编译的输出,但与此同时,使用 output.library 设置的编译输出意味着其他人将拉取的可重用库来自他们自己的代码库,即适合在 npm 上发布的东西。将 service worker 与该库或类似的东西一起运送是没有意义的。