webpack4项目从npm迁移至yarn后提示process is not defined报错
浏览器环境本身不存在Node.js原生的process全局变量,webpack4默认会自动注入对应polyfill、替换代码中的process引用,切换yarn后触发报错的核心原因是删除锁文件后依赖版本漂移,导致webpack内置的polyfill注入逻辑失效,和yarn本身的功能无关:
- yarn与npm的依赖版本解析、依赖扁平化策略存在差异,删除
package-lock.json后无版本锁约束,yarn会拉取符合semver范围的更高版本子依赖,部分webpack生态插件的小版本迭代会触发polyfill注入逻辑异常 - yarn与npm对peerDependencies的校验、安装逻辑不同,无锁状态下可能安装到版本不匹配的webpack相关子依赖,导致内置
DefinePlugin没有正确替换代码中的process引用。
1. 锁死核心构建依赖版本
先检查package.json中webpack、webpack-cli、webpack-dev-server、html-webpack-plugin等核心构建依赖的版本号,不要使用带^/~的模糊版本范围,直接锁死之前npm运行正常时的精确版本,示例:
{ "devDependencies": { "webpack": "4.46.0", "webpack-cli": "3.3.12", "html-webpack-plugin": "4.5.2" } }
修改完成后删除当前目录下的node_modules文件夹、yarn.lock文件,重新执行yarn install后再编译验证。
2. 显式配置webpack注入process polyfill
如果锁版本后问题仍存在,不要依赖webpack4的默认自动注入逻辑,手动在webpack配置中补全注入规则:
首先在配置文件顶部引入webpack:
const webpack = require('webpack')
然后在配置项中添加node规则与DefinePlugin配置:
module.exports = { // 其余原有配置保持不变 node: { process: true }, plugins: [ // 其余原有插件保持不变 new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'), 'process.browser': JSON.stringify(true) }) ] }
3. 强制对齐process polyfill引用
如果以上配置仍不生效,先执行yarn why process定位引用process的具体依赖,大概率是某个依赖被解析为Node端版本而非浏览器端版本,此时可以通过resolve别名强制所有process引用指向浏览器端polyfill:
首先安装polyfill依赖:
yarn add -D process
然后在webpack配置中添加别名:
module.exports = { // 其余原有配置保持不变 resolve: { alias: { process: 'process/browser' } } }
快速验证方法
如果需要快速确认问题是否由process缺失导致,可以在入口HTML的<head>标签最顶部添加全局mock代码,添加后报错消失即可确认是构建注入环节的问题:
<script> window.process = { env: { NODE_ENV: 'development' }, browser: true } </script>
注意生产环境需要将NODE_ENV值改为production,该方案仅用于快速验证,不推荐作为长期解决方案。
后续跨包管理器迁移时,不要直接删除原有锁文件重装依赖:从npm迁移到yarn时,在存在package-lock.json的目录下直接执行yarn import,yarn会根据package-lock.json记录的精确依赖版本生成yarn.lock,完全对齐npm环境下的依赖树,避免版本漂移引发的各类构建、运行时异常。
内容的提问来源于stack exchange,提问作者Álvaro

