React18 + Webpack5 polyfills问题 Module not found: Error: Can't resolve 'buffer'

398 阅读2分钟

起因:webpack5取消了对nodejs的自动polyfills,而我们的项目新增代码依赖node的crypto库

错误信息

Module not found: Error: Can't resolve 'buffer' in 'E:....\node_modules.pnpm\asn1.js@4.10.1\node_modules\asn1.js\lib\asn1\base'                  
webpack < 5 used to include polyfills for node.js core modules by default

Did you mean './buffer'?       

由于需要更改webpack配置,存在两种方案

  1. 放弃react-script,使用react-app-rewired与customize-cra或其他库用于重写webpack的配置
  2. eject项目配置,这将把所有的配置文件和依赖(包括 Webpack、Babel 等)直接暴露到项目中,允许开发者完全控制这些配置

我这里由于项目已经进行到一半,使用第一种方案

安装

pnpm install buffer stream-browserify crypto-browserify vm-browserify process

pnpm install react-app-rewired customize-cra --save-dev

在根目录添加config-overrides.js文件

const { override, addWebpackResolve,addWebpackPlugin,addWebpackModuleRule } = require('customize-cra');
const webpack = require('webpack');
module.exports = override(
    addWebpackResolve({
        fallback: {
            "crypto": require.resolve('crypto-browserify'),
            "stream": require.resolve("stream-browserify"),
            "vm": require.resolve("vm-browserify"),
            "process": require.resolve("process/browser")
        }
    }),
    addWebpackPlugin(
        new webpack.ProvidePlugin({
            process: 'process/browser', // 确保 process 变量在全局范围内可用
        }),
    ),

);

连锁错误:

Module not found: Error: Can't resolve 'process/browser' in 'E:....\node_modules.pnpm@reduxjs+toolkit@2.1.0_react-redux@9.1.0_react@18.2.0\node_modu
les@reduxjs\toolkit\dist'
Did you mean 'browser.js'?

在以下链接找到解决办法

github.com/react-dnd/r…

主要是加上这一句

"process/browser": require.resolve("process/browser")

完整解决方案

const { override, addWebpackResolve,addWebpackPlugin,addWebpackModuleRule } = require('customize-cra');
const webpack = require('webpack');
module.exports = override(
    addWebpackResolve({
        fallback: {
            "crypto": require.resolve('crypto-browserify'),
            "stream": require.resolve("stream-browserify"),
            "vm": require.resolve("vm-browserify"),
            "process/browser": require.resolve("process/browser")
            
        }
    }),
    addWebpackPlugin(
        new webpack.ProvidePlugin({
            process: 'process/browser', 
            // 在你的整个应用中,无论哪里需要process变量(尤其是在那些依赖于Node.js环境变量的库中)
            // webpack都会自动提供process/browser这个模块
        }),
    ),

);

能解决问题的原因可能是

当你将配置改为 "process/browser": require.resolve("process/browser") 后,实际上你是在告诉 Webpack:“当遇到需要解析 process/browser 这一具体请求时,这里是它的具体实现位置”。这种方式明确指定了请求的模块和对应的解析路径,避免了解析的不确定性,从而解决了问题。