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

Webpack 4 + Create React App环境下如何移除打包代码中的new Function以符合严格CSP要求

解决Webpack 4 + Create React App中CSP违反的new Function生成问题

我完全懂你的痛点——严格CSP下new Function确实是个棘手的坎,还不能用unsafe-eval绕过,必须从Webpack的生成逻辑根源入手解决。下面是几个经过验证的方案,按优先级排序:

1. 确保globalObject配置彻底生效

你已经设置了globalObject: 'window',但在Create React App(CRA)中,默认Webpack配置被封装,直接修改可能没完全覆盖。得通过自定义配置工具确保这个设置落地:

  • 安装react-app-rewired和customize-cra作为开发依赖
  • 在项目根目录创建config-overrides.js,添加以下代码:
const { override, adjustWebpackConfig } = require('customize-cra');

module.exports = override(
  adjustWebpackConfig((webpackConfig) => {
    // 强制全局对象为window,消除Webpack的全局对象 fallback 逻辑
    webpackConfig.output.globalObject = 'window';
    // 加强node环境模拟的禁用
    webpackConfig.node = {
      ...webpackConfig.node,
      global: false,
      __dirname: false,
      __filename: false,
    };
    return webpackConfig;
  })
);
  • 修改package.json中的启动/打包脚本,把react-scripts替换为react-app-rewired:
"scripts": {
  "start": "react-app-rewired start",
  "build": "react-app-rewired build",
  "test": "react-app-rewired test"
}

这个配置直接告诉Webpack:我们的运行环境是浏览器,全局对象就是window,不需要再生成那段带new Function的兼容代码。

2. 直接替换Webpack运行时的不安全逻辑

如果上面的配置还没完全解决,可以通过自定义Webpack插件,直接替换生成的运行时代码里的问题片段:
在config-overrides.js中添加自定义插件:

const { override, addWebpackPlugin, adjustWebpackConfig } = require('customize-cra');

class ReplaceUnsafeRuntimePlugin {
  apply(compiler) {
    compiler.hooks.compilation.tap('ReplaceUnsafeRuntimePlugin', (compilation) => {
      compilation.hooks.runtimeModule.tap('ReplaceUnsafeRuntimePlugin', (module) => {
        // 定位包含new Function的runtime模块
        if (module.source().includes("new Function(\"return this\")")) {
          // 替换为直接指向window的安全代码
          const newSource = module.source().replace(
            /try { n = n || new Function\("return this"\)\(\); } catch \(e\) { "object" == typeof window && \(n = window\); }/,
            "n = window;"
          );
          module._source = {
            source: () => newSource,
            size: () => newSource.length,
          };
        }
      });
    });
  }
}

module.exports = override(
  addWebpackPlugin(new ReplaceUnsafeRuntimePlugin()),
  adjustWebpackConfig((webpackConfig) => {
    webpackConfig.output.globalObject = 'window';
    webpackConfig.node.global = false;
    return webpackConfig;
  })
);

这个插件会在Webpack生成运行时代码时,把那段不安全的fallback逻辑直接替换成n = window;,彻底消除new Function的使用。

3. 排查第三方依赖的潜在问题

有时候第三方依赖也会生成new Function或eval代码(比如某些国际化库、动态样式库),可以这样排查:

  • 打包后搜索生成的chunk文件,定位new Function的来源
  • 用webpack-bundle-analyzer分析bundle,找到包含该代码的依赖包
  • 替换为符合CSP规范的替代库,或者联系依赖作者修复问题

关于polyfill的思路

你提到的polyfill思路其实和上面的方案一致:这段代码原本是为了兼容不同环境的全局对象获取,我们直接给Webpack提供一个确定的、安全的全局对象实现(即window),这相当于用浏览器环境的“专属实现”替代了Webpack的通用fallback逻辑,完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.01 02:24:11