webpack基础配置及优化

webpack优化小结

  1. 生成runtime文件:runtimeChunk :true
  2. 多进程构建:parallel: true
  3. 源代码映射:devTool:'source-map'
  4. 懒加载(预加载):webpackChunkPrefetch、webpackChunkPreLoad
  5. 拆分包:splitChunks
  6. 热更新
  7. treeShaking(先标记,后删除)
  8. 资源压缩:compress
  9. 小文件转为DataUrl(base64)方式,减少请求次数

webpack打包时间和内存分析

打包时间
       插件 SpeedMeasurePlugin
       https://www.npmjs.com/package/speed-measure-webpack-plugin
  

内存分析    
       插件webpack-bundle-analyzer      
       https://v4.webpack.docschina.org/guides/code-splitting/#bundle-%E5%88%86%E6%9E%90-bundle-analysis-
       https://www.npmjs.com/package/webpack-bundle-analyzer
 
  

const path = require('path')
const htmlWebpackPlugin = require('html-webpack-plugin')
const {VueLoaderPlugin} = require('vue-loader')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const { DefinePlugin } = require('webpack')
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const PurgeCSSPlugin = require('purgecss-webpack-plugin')
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const CompressionPlugin = require("compression-webpack-plugin");
var InlineChunkHtmlPlugin = require('inline-chunk-html-plugin');
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const webpack = require('webpack')
const smp = new SpeedMeasurePlugin();
module.exports = smp.wrap({
    mode:'development',
    entry:{
        //多入口
        main:'./src/main.js',
        index:'./src/index.js'
    },
    devTool:'source-map',
    output:{
        filename:'js/[name].bundle.js',
        path:path.resolve(__dirname,'build'),
        chunkFilename:'js/chunk_[name].js',//这里的name受optimization里的chunkIds影响,或者使用魔法注释可以重新命名import(/*webpackChunkName:'title'*/'./title')
        //publicPath:'https://abc.cnd.com',//给打包好的js前面加cdn地址
        //assetModuleFilename:"img/[name].[hash:6][ext]"//asset配置
    },
    /**
     * 第三方扩展设置,防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖
     * https://v4.webpack.docschina.org/configuration/externals/#externals
     */
    externals:{
        lodash:'-',//排除lodash,不要打包,需要在script里加lodash的cnd地址,优点:可以及时更新第三方代码
    },
    /**
     * 配置模块解析规则
     * https://webpack.docschina.org/configuration/resolve/#root
     */
    resolve:{
        extensions:[".js",".json",".ts",".jsx",".vue"],//按顺序解析这些后缀名,没有写后缀时默认补全
        alias:{
            '@':path.resolve(__dirname,'src')//@代表的目录,在文件里可以用'@components/list'
        },
        // mainFields: ['browser', 'module', 'main']
        //在我们 import * as Upstream from 'upstream' 时,这实际上会从包的package.json里的 browser 属性解析文件
    },
    optimization:{
        /**
         * https://webpack.docschina.org/guides/code-splitting/#splitchunksplugin
         * webpackChunkPrefetch:true  // 浏览器闲置时/加载完成后 加载
         * webpackChunkPreLoad:true  // 立即(并行)加载
         */
        usedExports:true,//标记没用到的函数,结合TerserPlugin来删除没有的代码 
        minimize:true,//告知 webpack 使用 TerserPlugin 或其它在 optimization.minimizer定义的插件压缩 bundle
        minimizer:[
            /**
             * 对js代码进行压缩的工具(将变量变成a\b\o)
             * https://webpack.docschina.org/plugins/terser-webpack-plugin/  
             * 参数:https://github.com/terser/terser
             */
            new TerserPlugin({
                cache: true,//启用文件缓存
                parallel: true,//使用多进程构建
                sourceMap: true, //启用源代码映射
                terserOptions: {
                  // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
                },
                extractComments:false,//省略中间产生的注释文件
              }),
        ],
        runtimeChunk :true,//做长期缓存,生成一个runtime文件
        chunkIds:'natural',//natural-文件按自然数命名&排序(影响缓存),named-按名称命名,deterministic-根据文件内容生成hash命名,
        splitChunks:{//把动态导入(import)的包拆出来,
            chunks:'initial',//all,async 对同步导入生效还是异步,还是全部
            minSize:20000,//拆完包后的最小体积,小于这个体积就不拆
            maxSize:20000,//体积大于则个值则进行拆分
            minChunks:1,//至少引用几次则进行拆分
            cacheGroups:{//拆包的过程中进行分组
                vendors:{
                    test:/[\\/]node_modules[\\/]/,
                    filename:'js/[id]_vender.js',//把第三方库都放在vender.js里
                    priority:-10,//优先级
                }
            }
        }
    },
    devServer:{
        port:8000,
        hot:true,//热更新
        hotOnly:true,
        open:false,
        compress:true,//基础压缩,gzip
        proxy:{
            '/api':{//标记
                target:'https://api.github.com/',//
                pathRewrite:{"^/api":""},//对api做重写
                changeOrigin:true,//修改请求头里的host字段
            
            }
        }
    },
    plugins:[
        new CleanWebpackPlugin(),//自动删除打包后目录下的文件
        new htmlWebpackPlugin({//该插件为你生成一个 HTML 文件
            // filename:'build.html'
            title:'myAppTitle',
            template:'./public/index.html'//使用自己的html模板
        }),//默认生成index.html文件并引入打包后的js文件
        new VueLoaderPlugin(),
        new DefinePlugin({//在 编译时 将代码中的变量替换为其他值或表达式
            BASE_URL:'"./"'
        }),
        new CopyWebpackPlugin({
            patterns:[
                {
                    from:'public',
                    //to: 省略to就会使用output里的path
                    globOptions:{
                        ignore:['**/index.html']//省略的文件,**/表示从from下开始查找
                    }
              }
            ]
        }),
        /**
         * 将css代码提取到单独的文件中 
         * https://webpack.docschina.org/plugins/mini-css-extract-plugin/
         */
        new MiniCssExtractPlugin({
            filename:'css/[name].[hash:8].css'
        }),
        /**
         * 对css文件进行压缩
         * https://webpack.docschina.org/plugins/css-minimizer-webpack-plugin/
         */
        new CssMinimizerPlugin(),
        new webpack.optimize.ModuleConcatenationPlugin(),//scope hoisting 仅适用于es module,对模块有优化功能
         /**
          * css文件的tree shaking配置
          * https://www.npmjs.com/package/purgecss-webpack-plugin
          * 注意:注释掉的代码的样式不会被删除
          */
        new PurgeCSSPlugin({
             //需要告诉他对哪些css进行处理
            paths: glob.sync(`${path.resolve(__dirname,'./src')}/**/*`,  { nodir: true }),
            safelist:function(){//安全列表
                return {
                    standard:['body','html']//树摇的时候不会把这两个样式摇掉
                }
            }
        }),
        new CompressionPlugin({
            test:/\.(js)$/,
            minRation:0.2,//压缩比例
            threshold:0,//体积大于多少就压缩
            algorithm:'gzip',//压缩算法
        }),//压缩资源,test.js->test.js.gz
        new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime.*\.js/]),//将运行时文件注入到html文件中,优点:不用单独请求runtime文件
    ],
    module:{
        rules:[
            {
                test:/\.css$/,
                use:[MiniCssExtractPlugin.loader, "css-loader"],
                //use:['style-loader','css-loader'] 要抽离css文件用MiniCssExtractPlugin.loader代替style-loader
                sideEffects:true,
            },
            {
                test:/\.less$/,
                use:['style-loader',
                    {
                        loader:'css-loader',
                        options:{
                            importLoaders:2//在工作中可以往前找一个loader
                        }
                    },
                    'postcss-loader',
                    'less-loader'//从上往下,从右往左
                ]
            },
            {
                test:/\.(jpe?g|png|gif|svg)$/,
                type:'asset',
                generator:{
                    filename:'img/[name].[hash:6][ext]'
                }
            },
            {
                test:/\.js$/,
                use:[{
                    loader:'babel-loader',
                    options:{
                        presets:[
                            '@babel/preset-env'
                        ]
                    }
                }]
            },
            {
                test:/\.(woff2?|ttf)$/,
                type:'asset/resource',
                generator:{
                    filename:'font/[name].[hash:6][ext]'
                }
            },
            {
                test:/\.jsx$/,
                use:['babel-loader']
            },
            {
                test:/\.ts$/,
                use:['babel-loader']
            },
            {
                test:/\.vue$/,
                use:['vue-loader']
            }
        ]
    }
})
/**
postcss-preset-env 转换css的功能的集合
browerlistsrc  对需要加前缀的代码进行处理,需要在browerlistsrc设置规则,服务于js、css的兼容的筛选条件
 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值