美文网首页
(new)压缩js/css、chunk分离

(new)压缩js/css、chunk分离

作者: codingQi | 来源:发表于2019-05-28 19:58 被阅读0次

    参考文档:webpack打包体积优化(超详细)

    1. 使用分析器webpack-bundle-analyzer(可视化大小的webpack输出文件与互动缩放树形图。)
      安装:npm i -D webpack-bundle-analyzer
      配置:
    const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
    
    plugins: [
        new BundleAnalyzerPlugin({
             analyzerPort: 8081
        })
    ],
    

    打包运行:npm run build,结果如下:可见,包都很小,是因为现在只是脚手架,使用到的包很少。

    1. 压缩js
      (1)使用uglifyjs-webpack-plugin打包一直报错,最后就换了一下插件,结果打包成功,因此,可能是这个插件的版本和webpack的版本不兼容吧。
      (2)安装npm i -D terser-webpack-plugin,并在pro里配置:
      这里只做了一般的配置,更多配置查看npm库terser-webpack-plugin
    optimization: {
            minimizer: [
                // 压缩js
                new TerserPlugin({
                    cache: true,
                    parallel: true,
                    sourceMap: false,
                    terserOptions: {
                        ecma: undefined,
                        warnings: false,
                        parse: {},
                        compress: {
                            drop_debugger: true, // 删除 debugger
                            drop_console: true, // 删除 console
                        },
                        mangle: true, // 不跳过错误的名称
                        module: false,
                        output: null,
                        toplevel: false,
                        nameCache: null,
                        ie8: false,
                        keep_classnames: undefined,
                        keep_fnames: false,
                        safari10: true,
                    },
                })
           ]
    }
    
    1. 压缩css(配置参考
      (1)安装npm i -D optimize-css-assets-webpack-plugin
      (2)在pro里配置如下:
              new OptimizeCssAssetsPlugin({
                    assetNameRegExp: /\.css\.*(?!.*map)/g, // 注意不要写成 /\.css$/g
                    cssProcessor: require('cssnano'),
                    cssProcessorOptions: {
                        // 使用安全模式,避免 cssnano 重新计算 z-index
                        safe: true,
    
                        // 默认不移除许可证注释,这里移除所有
                        discardComments: { removeAll: true },
    
                        // cssnano通过移除注释、空白、重复规则、过时的浏览器前缀以及做出其他的优化来工作,一般能减少至少 50% 的大小
                        // cssnano 集成了autoprefixer的功能
                        // 会使用到autoprefixer进行无关前缀的清理
                        // 因此这里关闭autoprefixer功能
                        // 使用postcss的autoprefixer功能
                        autoprefixer: false,
                    },
                    canPrint: true
              })
    
    1. 分离:将antd之类的第三方库从主要的包里分离出来,打包后的chunk前缀名为vendor。
      注意:
      (1)设置css/js的chunkFilename,设置为[id]——vendor前缀不生效,设置为[name]——生效;
      (2)若不设置css/js的chunkFilename,并且不配置cacheGroups,则会默认添加前缀为vendor~app
      配置如下:splitChunks配置参考
    // chunks: 'all',表示显示块的范围,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),默认为all
        optimization: {
           splitChunks: {
                chunks: 'all',
                cacheGroups: { // 缓存组默认将node_modules中的模块拆分带一个叫做vendors的代码块中
                    vendor: {
                        test: /node_modules/,
                        name: 'vendor', // 决定打包的chunk前缀名
                        chunks: 'initial',
                        enforce: true,
                    },
                },
            }
        }
    
    1. 附pro的完整配置
    const path = require('path');
    const webpack = require('webpack');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const CleanWebpackPlugin = require('clean-webpack-plugin');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const HtmlWebpackIncludeAssetsPlugin = require('html-webpack-include-assets-plugin');
    const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
    const TerserPlugin = require('terser-webpack-plugin');
    const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
    
    module.exports = {
        entry: {
            app: path.resolve(__dirname, '../src/index.js')
        },
        output: {
            filename: 'public/js/[name].[hash:8].js',
            chunkFilename: 'public/js/[name].[hash:8].chunk.js',
            path: path.resolve(__dirname, '../dist'),
            publicPath: '/' // 构建资源存放路径(绝对路径)
        },
        optimization: {
            minimizer: [
                // 压缩js
                new TerserPlugin({
                    cache: true,
                    parallel: true,
                    sourceMap: false,
                    terserOptions: {
                        ecma: undefined,
                        warnings: false,
                        parse: {},
                        compress: {
                            drop_debugger: true, // 删除 debugger
                            drop_console: true, // 删除 console
                        },
                        mangle: true, // 不跳过错误的名称
                        module: false,
                        output: null,
                        toplevel: false,
                        nameCache: null,
                        ie8: false,
                        keep_classnames: undefined,
                        keep_fnames: false,
                        safari10: true,
                    },
                }),
                new OptimizeCssAssetsPlugin({
                    assetNameRegExp: /\.css\.*(?!.*map)/g, // 注意不要写成 /\.css$/g
                    cssProcessor: require('cssnano'),
                    cssProcessorOptions: {
                        // 使用安全模式,避免 cssnano 重新计算 z-index
                        safe: true,
    
                        // 默认不移除许可证注释,这里移除所有
                        discardComments: { removeAll: true },
    
                        // cssnano通过移除注释、空白、重复规则、过时的浏览器前缀以及做出其他的优化来工作,一般能减少至少 50% 的大小
                        // cssnano 集成了autoprefixer的功能
                        // 会使用到autoprefixer进行无关前缀的清理
                        // 关闭autoprefixer功能
                        // 使用postcss的autoprefixer功能
                        autoprefixer: false,
                    },
                    canPrint: true
                })
            ],
            splitChunks: {
                chunks: 'all', // 表示显示块的范围,有三个可选值:initial(初始块)、async(按需加载块)、all(全部块),默认为all
                cacheGroups: { // 缓存组默认将node_modules中的模块拆分带一个叫做vendors的代码块中
                    vendor: {
                        test: /node_modules/,
                        name: 'vendor', // 决定打包的chunk前缀名
                        chunks: 'initial',
                        enforce: true,
                    },
                },
            }
        },
        module: {
            rules: [
                {
                    test: /\.js|jsx$/,
                    use: [{
                        loader: 'babel-loader'
                    }],
                    exclude: /node_modules/
                },
                {
                    test: /\.(css|less)$/,
                    exclude: /node_modules/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        {
                            loader: 'css-loader',
                            options: {
                                modules: true,
                                localIdentName: '[name]_[local]_[hash:8]'
                            }
                        },
                        'postcss-loader',
                        {
                            loader: 'less-loader',
                            options: {
                                javascriptEnabled: true
                            }
                        }
                    ]
                },
                {
                    test: /\.(css|less)$/,
                    include: /node_modules/,
                    use: [
                        MiniCssExtractPlugin.loader,
                        'css-loader',
                        'postcss-loader',
                        {
                            loader: 'less-loader',
                            options: {
                                javascriptEnabled: true
                            }
                        }
                    ]
                },
                {
                    test: /\.(png|svg|jpe?g|gif)$/i,
                    use: [
                        {
                            loader: 'file-loader',
                            options: {
                                outputPath: 'public/images/',
                                name: '[name].[hash:8].[ext]'
                            }
                        },
                        {
                            loader: 'image-webpack-loader' // 对图片的压缩使用相应的默认配置
                        }
                    ]
                },
                {
                    test: /\.(woff|woff2|eot|ttf|otf)$/,
                    use: [
                        {
                            loader: 'file-loader',
                            options: {
                                outputPath: 'public/font/',
                                name: '[name].[hash:8].[ext]'
                            }
                        }
                    ]
                }
            ]
        },
        plugins: [
            new CleanWebpackPlugin(['public', 'index.html'], {
                root: path.resolve(__dirname, '../dist'),
                exclude: ['dll'] // clean时,不删除dll文件夹
            }),
            new HtmlWebpackPlugin({
                template: path.resolve(__dirname, '../public/index.html'),
                filename: 'index.html'
            }),
            new MiniCssExtractPlugin({
                filename: 'public/css/[name].[hash:8].css',
                chunkFilename: 'public/css/[id].[hash:8].chunk.css'
            }),
            // webpack读取到vendor的manifest文件对于vendor的依赖不会进行编译打包
            new webpack.DllReferencePlugin({
                manifest: require(path.resolve(__dirname, '../dist/public/dll/vendor-manifest.json'))
            }),
            // 将第三方打包文件vendor.dll.js动态添加进html里
            new HtmlWebpackIncludeAssetsPlugin({
                assets: ['public/dll/vendor.dll.js'],
                append: false // false 在其他资源的之前添加 true 在其他资源之后添加
            }),
            new BundleAnalyzerPlugin({
                analyzerPort: 8081
            })
        ],
        resolve: {
            alias: {
                pages: path.resolve(__dirname, '../src/pages'),
                components: path.resolve(__dirname, '../src/components'),
                assets: path.resolve(__dirname, '../src/assets'),
                utils: path.resolve(__dirname, '../src/utils')
            }
        }
    };
    
    

    这些配置已经ok,后面需要写页面代码进行测试,并查看这些配置所提升的地方。
    注意:后面还需要对页面路由的跳转进行测试和配置。

    相关文章

      网友评论

          本文标题:(new)压缩js/css、chunk分离

          本文链接:https://www.haomeiwen.com/subject/upsktctx.html