webpack 5 项目中遇到的坑(持续更新)

5,488 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

前段时间用 webpack 5搭建了一个 Reacttypescript 的脚手架,来作为公司项目的基础脚手架,在实际的使用中还是遇到了很多坑的,需要总结和记录一下。

我是这样搭建React+TS的通用webpack脚手架的(阶段一)

我是这样搭建React+TS的通用webpack脚手架的(阶段二)

1、BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.

错误信息

image.png

解决方案

webpack.base.config.js中加上

module.exports = {
    resolve: {
	alias: {
	  crypto: false,
	  stream: false,
	  assert: false,
	  http: false,
	  https: false
	}
    }
}
// 具体加哪个,根据报错信息判断

2、Can't resolve 'react/jsx-runtime' in './node_modules/xxx'

错误信息

Can't resolve 'react/jsx-runtime' in './node_modules/xxx'

解决方案

webpack.base.config.js中加上

module.exports = {
    resolve: {
	alias: {
            //...
            'react/jsx-runtime': require.resolve('react/jsx-runtime')
	}
    }
}

3、process is not defined webpack

错误信息

process is not defined webpack

解决方案

由于 webpack 5不再为 Node.js 变量包含 polyfill,要避免在前端使用相关 API,说明文档:webpack.js.org/migrate/5/#…

因此,如果遇到依赖包有 process 等字段时,就会出现这个报错。 很多答案会给你一个答案是

//webpack.base.config.js

module.exports = {
    plugins: [ 
        //...
        new webpack.ProvidePlugin({ 
            process: 'process/browser', 
        }), 
    ],
}    

但这会导致一个新的报错:

Cannot find module "process/browser"

因此,正确答案应该是:

module.exports = {
    plugins: [ 
        //...
        new webpack.ProvidePlugin({ 
            process: 'process/browser.js', 
        }), 
    ],
}    

4、Uncaught ReferenceError: Buffer is not defined

错误信息

Uncaught ReferenceError: Buffer is not defined

解决方案

module.exports = {
    plugins: [ 
        //...
        new webpack.ProvidePlugin({ 
            //...
            Buffer: ['buffer', 'Buffer']
        }), 
    ],
}  

5、webpack-dev-server hmr 模块热更新失效

问题描述

在使用 webpack-dev-server 的新的运行命令 webpack serve 后,项目的 hmr 模块热更新失效了。每次修改 js、css 文件后只能通过 window.reload() 来查看更改。

解决方案

使用 react-refresh-webpack-plugin 插件

yarn add --dev @pmmmwh/react-refresh-webpack-plugin react-refresh
//webpack.dev.config.js
//...
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')

module.exports = merge(baseConfig, {
    devServer: {
        //...
        hot: true
    },
    //...,
    plugins: [
      ...baseConfig.plugins,
      new ReactRefreshWebpackPlugin()
    ],
})
// .babelrc
{
    "plugins": ["react-refresh/babel"]
}

6、开启 React Router 的 Browser router 模式

关于 React Router 的 BrowserRouterHashRouter 的模式可以参阅官方文档:v5.reactrouter.com/web/api/Bro…

这里需要修改一下webpack devServer配置:

//webpack.dev.config.js
module.exports = merge(baseConfig, {
    //...
    devServer: {
        //...
        historyApiFallback: true
    }
})

然后修改一下打包后的 publicPath

//webpack.base.config.js

module.exports = {
    output: {
        //...
        publicPath: '/'
    }
}