背景
最近自己整了一个基于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.jsmodule.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.jsconst 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项目优化打包文件体积的过程
原文地址:https://www.cnblogs.com/haimianxiubaobao/p/10566799.html