Webpack 3.x生产环境打包内含测试文件及Enzyme/Jest问题求助
我之前也碰到过一模一样的情况——生产bundle里混进了测试代码和Enzyme、Jest,折腾了大半天终于搞定。结合你的配置,给你几个针对性的解决方案:
1. 先搞清楚测试代码是怎么被引入的
首先得确认哪些业务模块不小心引入了测试文件,不然光靠排除规则可能治标不治本。推荐用webpack-bundle-analyzer插件生成可视化依赖树,一眼就能看到测试文件的来源:
- 安装插件:
npm install webpack-bundle-analyzer --save-dev - 在你的Webpack配置里添加:
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; // ... 其他配置 plugins: [ // 已有的插件... new BundleAnalyzerPlugin() ]
运行打包命令后,浏览器会自动打开一个页面,展示bundle里所有文件的依赖关系,你能直接找到__snapshots__、test-util这些测试文件是被哪个业务文件引入的,然后去删掉对应的import语句。
2. 修正babel-loader的排除规则,覆盖所有测试文件
你当前的exclude规则漏掉了常见的测试文件后缀(比如.test.js、.spec.js)和可能的__tests__目录。调整成下面这样:
module: { rules: [ { test: /\.js$/, exclude: [ /node_modules/, /__tests__/, // 排除测试目录 /__snapshots__/, // 排除快照目录 /test-util/, // 排除测试工具目录 /\.test\.js$/, // 排除所有.test.js结尾的文件 /\.spec\.js$/ // 排除所有.spec.js结尾的文件 ], loader: 'babel-loader' }, // ... 其他loader规则 ] }
注意:这里的exclude是告诉babel-loader不要转译这些文件,但如果这些文件已经被业务代码引入了,Webpack还是会把它们打包进去。所以这一步要和第一步配合,先删掉不必要的import。
3. 用IgnorePlugin彻底排除测试库和未被发现的测试文件
如果确认业务代码里不需要Enzyme、Jest,但它们还是被打包进来,可以用Webpack的IgnorePlugin直接忽略对这些库的引用:
plugins: [ new UglifyJsPlugin(), new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.stringify(process.env.NODE_ENV), } }), // 忽略Jest和Enzyme相关库 new webpack.IgnorePlugin(/^jest$/), new webpack.IgnorePlugin(/^enzyme$/), new webpack.IgnorePlugin(/^enzyme-adapter-react-16$/), // 忽略所有__tests__目录下的js文件 new webpack.IgnorePlugin(/__tests__\/.+\.js$/) ]
这个插件会直接阻止Webpack打包任何匹配到的模块,不管它们有没有被引入。
4. 最后检查入口文件和业务代码
仔细检查你的src/index.js以及所有业务组件,有没有不小心引入测试文件或者测试库的代码——比如开发时写的调试代码里import了test-util的工具函数,或者某个组件里残留了测试相关的import。把这些代码删掉或者注释掉(生产环境别留)。
验证结果
打包完成后,你可以用命令行检查bundle.js里是否还有测试相关内容:
grep -E "enzyme|jest|__snapshots__" build/bundle.js
如果没有输出,就说明已经彻底排除了。
内容的提问来源于stack exchange,提问作者Develoger

