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

使用Webpack与React开发Chrome扩展时热重载出现unsafe-eval CSP错误的解决方案

解决Chrome扩展Manifest V3 + webpack-dev-server热重载的unsafe-eval CSP错误

这个问题我之前开发Manifest V3扩展时也碰到过,核心矛盾是webpack开发模式下默认用eval生成模块代码,但Manifest V3的默认内容安全策略(CSP)严格禁止unsafe-eval,而生产构建时webpack会自动切换到不依赖eval的编译逻辑,所以生产环境能正常运行。下面给你两种实用的解决方案:

方法一:修改webpack devtool配置,避免使用eval

最简单的方式是调整webpack的devtool选项,选择不包含eval的source map类型,彻底规避CSP限制。

在你的webpack.config.ts中添加devtool配置:

module.exports = {
  // ... 其他已有配置
  devtool: 'inline-cheap-module-source-map', // 开发阶段推荐,兼顾编译速度和调试体验
  // ...
};

可选的替代值还有:

  • source-map:生成独立的source map文件,编译速度稍慢但调试信息最完整
  • cheap-module-source-map:比inline-cheap-module-source-map少了行内映射,编译速度更快一点

这些选项都不会生成包含eval的代码,完美适配Manifest V3的安全规则,同时保留开发所需的source map调试能力。

方法二:开发模式下临时调整Manifest的CSP(仅用于开发)

如果需要保留eval相关的devtool(比如追求极致的开发编译速度),可以在开发时给manifest临时添加允许unsafe-eval的CSP规则,但绝对不能在生产环境使用(Chrome商店会直接拒绝审核)。

我们可以通过webpack的CopyPlugin动态修改manifest.json,只在开发模式下注入宽松的CSP规则:

修改webpack.config.ts为函数形式,根据mode判断环境:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");

module.exports = (env, argv) => {
  const isDevelopment = argv.mode === "development";

  return {
    entry: {
      index: "./extension/index.tsx",
      background: "./extension/background.ts",
    },
    output: {
      filename: "[name].js",
      path: path.resolve(__dirname, "dist"),
      clean: true,
    },
    module: {
      rules: [
        { test: /\.tsx?$/, use: "ts-loader" },
        { test: /\.css$/, use: ["style-loader", "css-loader", "postcss-loader"] },
      ],
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: "./assets/index.html",
        filename: "index.html",
        chunks: ["index"],
      }),
      new CopyPlugin({
        patterns: [
          {
            from: "extension/manifest.json",
            to: "[name][ext]",
            transform(content) {
              if (!isDevelopment) return content;
              // 开发模式下添加允许unsafe-eval的CSP
              const manifest = JSON.parse(content.toString());
              manifest.content_security_policy = {
                extension_pages: "script-src 'self' 'unsafe-eval'; object-src 'self';",
              };
              return JSON.stringify(manifest, null, 2);
            },
          },
          { from: "assets/images", to: "images/" },
        ],
      }),
      new ForkTsCheckerWebpackPlugin(),
    ],
    devServer: {
      devMiddleware: { writeToDisk: true },
    },
    optimization: {
      minimizer: [new TerserPlugin({ extractComments: false })],
    },
    // 可选:如果用方法一,在这里添加devtool
    // devtool: 'inline-cheap-module-source-map',
  };
};

这样配置后,开发模式下生成的manifest会自动带上允许unsafe-eval的CSP,生产模式则保持原有的安全规则。

额外注意事项

  • 你的devServer中writeToDisk: true的配置是正确的,因为Chrome扩展需要读取本地磁盘上的文件,不能用webpack-dev-server的内存文件系统。
  • 如果要启用模块热替换(HMR),还需要额外配置HotModuleReplacementPlugin,但上述两种方法已经能解决基础的自动刷新热重载问题。

内容的提问来源于stack exchange,提问作者ronaldo_w

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 18:58:16