记一次webpack4+react+antd项目优化打包文件体积的过程
Posted 海绵休宝宝
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次webpack4+react+antd项目优化打包文件体积的过程相关的知识,希望对你有一定的参考价值。
背景
最近自己整了一个基于webpack4和react开发的博客demo项目,一路整下来磕磕碰碰但也实现了功能,就准备发到阿里云上面去看看,借用了同事的阿里云小水管服务器,配置完成之后首页加载花了十几秒,打开控制台network查看资源,打包的js体积有将近6M,及其影响访问体验,于是就开始了优化的路。
原因和解决方法
在webpack的配置文件中,对公共js做了抽取,分别会打包出react-verdor.js和antd-verdor.js,优化前的antd-verdor足足有4m大小,估计是把antd组件全部加载下来了,顺着这个思路查找解决方案。
optimization.splitChunks: { chunks: \'all\', cacheGroups: { "react-vendor": { test: (module) => (/react/.test(module.context) || /redux/.test(module.context) || /classnames/.test(module.context) || /prop-types/.test(module.context)), priority: 3, reuseExistingChunk: false }, "antd-vendor": { // || /[\\\\/]node_modules[\\\\/]/.test(module.context) test: (module) => (/antd/.test(module.context)), priority: 2, reuseExistingChunk: false }, } }
antd官方推荐按需加载,我开始也是根据官方推荐做的,在.babelrc做如下配置
{ "plugins": [ ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }] ] }
不过事实是打包文件有4M,那肯定是配置错了,继续查找别的配置方法,终于找到一个管用的,在webpack配置文件中做如下配置(本质上还是自己太菜,不理解.babelrc)
{ test: /\\.(js|jsx)/, use: { loader:\'babel-loader\', options: { presets: ["env", "react", \'stage-0\'], plugins: [ [\'import\', [{ libraryName: \'antd\', style: true }]] ] } }, include: resolve(\'src\') },
配置完成后进行打包,体积明显变小了,antd-vendor.js的大小变成200多K。antd按需引入的问题解决后,看别的文件还是挺大的,于是决定把REACT中的组件也做成按需加载的方式,拆分更多的js出来,这里使用了react-loadable实现,拆分完成之后继续打包,发现部分子js的体积明显过大,继续查找原因。
在浏览器中跳转到对应的页面查看加载的js,查看js文件中的注释,发现有两个第三方插件被我全部import进来了了,其实我永不到那么多,分别是
//修改前 import crypto from (\'crypto\') module.exports = { MD5_SUFFIX: \'sskjtxdywdddzyjknn\', md5: function (pwd) { let md5 = crypto.createHash(\'md5\'); return md5.update(pwd).digest(\'hex\') }, } //修改后 const md5 = require("crypto-js/md5") module.exports = { MD5_SUFFIX: \'sskjtxdywdddzyjknn\', md5: function (pwd) { return md5.update(pwd).digest(\'hex\') }, }
解决引入highlightjs后文件的过大的的思路和上面类似,我选择了直接加载hightlightjs保留核心功能后的压缩代码,size只有30k,而之前的默认import后的size有将近1M
还能优化吗
前面发现的问题不外乎是由第三方库造成的,解决了前面的问题后,此时的js体积已经从之前的6M降到1.8M了。那么还能继续通过webpack配置来优化打包后的文件大小吗?抱着这个疑问继续查找解决方案,最后决定试一试这个文章说明的方法
https://zhuanlan.zhihu.com/p/36280323
一顿操作下来打包出来的文件只减小了30K,最后再放上配置文件js的完整代码,希望能有大佬提出建议,非常
//webpack.base.config.js module.exports = { /*entry: { app: \'./src/index.jsx\', },*/ output: { publicPath: process.env.NODE_ENV === config.prod.ENV ? config.prod.assetsPublicPath : config.dev.assetsPublicPath }, resolve: { extensions: [\'.js\', \'.jsx\', \'.json\'], alias: { \'@components\': path.resolve(__dirname, \'../src/components\'), \'@\': resolve(\'src\'), } }, module: { rules: [ { test: /\\.(js|jsx)/, use: { loader: \'babel-loader\', options: { presets: ["env", "react", \'stage-0\'], plugins: [ [\'import\', [{ libraryName: \'antd\', style: true }]] ] } }, include: resolve(\'src\') }, { test: /\\.(png|jpe?g|gif|svg)(\\?.*)?$/, loader: \'url-loader\', options: { limit: 10000, name: assetsPath(\'img/[name].[ext]\') } }, { test: /\\.(mp4|webm|ogg|mp3|wav|flac|aac)(\\?.*)?$/, loader: \'url-loader\', options: { limit: 10000, name: assetsPath(\'media/[name].[ext]\') } }, { test: /\\.(woff2?|eot|ttf|otf)(\\?.*)?$/, loader: \'url-loader\', options: { limit: 10000, name: assetsPath(\'font/[name].[ext]\') } }, { test: /\\.css$/, use: [{ loader: \'style-loader\' }, { loader: "css-loader", options: { name: "[path][name].[ext]", } }] }, { test: /\\.less$/, exclude: /node_modules/, use: [ MiniCssExtractPlugin.loader, \'css-loader\', \'less-loader\', ] }, { test: /\\.less$/, include: /node_modules/, use: [ MiniCssExtractPlugin.loader, \'css-loader\', { \'loader\': \'less-loader\', options: { javascriptEnabled: true } } ] } ] }, plugins: [ new MiniCssExtractPlugin({ filename: \'[name].css\' }), new LodashModuleReplacementPlugin ] } //webpack.prod.config.js const webpackConfig = merge(baseWebpackConfig, { entry: { app: \'./src/index.jsx\', }, mode: \'production\', devtool: false, output: { path: config.prod.assetsRoot, filename: assetsPath(\'js/[name].[chunkhash].js\'), chunkFilename: assetsPath(\'js/[name].[chunkhash].js\'), }, plugins: [ new htmlWebpackPlugin({ filename: \'index.html\', title: pkg.description, template: path.resolve(__dirname, \'../index.html\'), inject: true, minify: { removeComments: true, collapseWhitespace: true, removeRedundantAttributes: true, useShortDoctype: true, removeEmptyAttributes: true, removeStyleLinkTypeAttributes: true, keepClosingSlash: true, minifyJS: true, minifyCSS: true, minifyURLs: true, }, }), new CopyWebpackPlugin([ { from: path.resolve(__dirname, \'../src/static\'), to: config.prod.assetsSubDirectory, } ]) ], optimization: { minimizer: [ new UglifyJsPlugin(), new OptimizeCSSAssetsPlugin(), new TerserPlugin({ terserOptions: { parse: { ecma: 8, }, compress: { ecma: 5, warnings: false, comparisons: false, inline: 2, }, mangle: { safari10: true, }, output: { ecma: 5, comments: false, ascii_only: true, }, }, // Use multi-process parallel running to improve the build speed // Default number of concurrent runs: os.cpus().length - 1 parallel: true, // Enable file caching cache: true, sourceMap: false, }), ], splitChunks: { chunks: \'all\', cacheGroups: { "react-vendor": { test: (module) => (/react/.test(module.context) || /redux/.test(module.context) || /classnames/.test(module.context) || /prop-types/.test(module.context)), priority: 3, reuseExistingChunk: false }, "antd-vendor": { // || /[\\\\/]node_modules[\\\\/]/.test(module.context) test: (module) => (/antd/.test(module.context)), priority: 2, reuseExistingChunk: false }, } } } })
感谢!
以上是关于记一次webpack4+react+antd项目优化打包文件体积的过程的主要内容,如果未能解决你的问题,请参考以下文章