You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取webpack输出文件列表并在PWA的service worker中使用

解决方案

问题根因

你当前导出了两个webpack配置数组,webpack会并行执行这两个配置的构建流程。frontend配置的资源清单要等整个构建流程收尾才会写入磁盘,而此时serviceworker配置的依赖解析步骤早就执行完了,自然找不到还未生成的page-files.json。第二次构建能成功是因为读取到了上一次构建残留的旧清单,会存在资源版本不一致的隐患。

方案1:调整构建顺序(最易改)

把两个配置拆分到独立文件,串行执行构建:

  1. 把原配置拆为webpack.frontend.js和webpack.sw.js两个配置文件
  2. 修改package.json的构建脚本:
{
  "scripts": {
    "build": "webpack --config webpack.frontend.js && webpack --config webpack.sw.js"
  }
}

该方案可以复用你现有的导入逻辑,无需修改业务代码。

方案2:直接注入资源列表(最可靠)

通过DefinePlugin直接把资源列表注入到serviceworker代码中,完全避免读取磁盘文件:
修改后的webpack.config.js如下:

const path = require('path');
const webpack = require('webpack');
const WebpackAssetsManifest = require('webpack-assets-manifest');

// 存储页面资源列表
let pageAssets = [];

const frontend = {
    mode: "development",
    entry: {
        page:"./src/page/page.tsx",
    },
    devtool: 'inline-source-map',
    output: {
        path: path.resolve(__dirname, 'dist'),
    },
    module: {
        rules: [
            {
                test: /\.html?$|\.png$/,
                type: "asset/resource",
                generator: {
                    filename: "[name][ext]",
                },
            },
            {
                test: /\.tsx?$/,
                loader: "ts-loader",
                exclude: /node_modules/,
            },
            {
                test: /\.json$/,
                type: "asset/resource",
                exclude: /node_modules/,
            }
        ],
    },
    resolve: {
        extensions: [".html", ".tsx", ".ts", ".js"],
    },
    plugins: [
        new WebpackAssetsManifest({
            output: "page-files.json",
            writeToDisk: true,
            // 构建完成后把资源列表存入变量
            done: (manifest) => {
                pageAssets = Object.values(manifest.toJSON());
            }
        }),
    ]
};

const serviceworker = {
    mode: "development",
    entry: {
        serviceworker: "./src/serviceworker/serviceworker.ts",
    },
    devtool: 'inline-source-map',
    output: {
        path: path.resolve(__dirname, 'dist'),
    },
    module: {
        rules: [
            {
                test: /\.html?$|\.png$/,
                type: "asset/resource",
                generator: {
                    filename: "[name][ext]",
                },
            },
            {
                test: /\.tsx?$/,
                loader: "ts-loader",
                exclude: /node_modules/,
            },
            {
                test: /\.json$/,
                resourceQuery: /link/,
                type: "asset/resource",
                exclude: /node_modules/,
            },
            {
                test: /\.json$/,
                resourceQuery: /str/,
                type: "asset/source",
                exclude: /node_modules/,
            }
        ],
    },
    resolve: {
        extensions: [".html", ".tsx", ".ts", ".js"],
    },
    plugins: [
        // 把资源列表作为全局常量注入
        new webpack.DefinePlugin({
            PAGE_ASSETS: JSON.stringify(pageAssets)
        })
    ]
};

module.exports = [frontend, serviceworker];

然后直接在serviceworker.ts中使用常量即可,无需导入json文件:

console.log(PAGE_ASSETS);

方案3:使用workbox插件(最推荐)

workbox-webpack-plugin是webpack官方维护的PWA构建插件,会自动收集所有构建资源并注入到serviceworker中,无需自己维护资源清单逻辑,适配各种缓存策略,完全避免当前遇到的问题。

内容的提问来源于stack exchange,提问作者Colonel Thirty Two

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 05:18:01