webpack-提升打包构建速度-减少代码体积

333 阅读3分钟

构建打包速度

HotModuleReplacement

  1. 为什么?

    HotModuleReplacement只编译所修改的模块,webpack默认将所有模块全部重新打包

  2. 是啥?

    HotModuleReplacement(HMR):在程序运行中,替换、添加或者删除模块,而无需重新加载整个页面

  3. 用法

devServer: {
   host: "localhost", // 启动服务器域名
   port: "3000", // 启动服务器端口号
   open: true, // 是否自动打开浏览器
   hot:true //开启(HMR,webpack5默认为true)
   
}

热加载JS文件

if (module.hot){
    module.hot.accept('./js/count')
}

实际开发中使用vue-loader或者react-loader进行HMR

OneOf

  1. 为啥?

    打包所有文件都会经过loader处理,哪怕没有命中的正则也要过一遍,速度比较慢

  2. 是啥?

    一旦命中一个loader,不会继续向下匹配

  3. 用法

module: {
 rules: [
     {
         oneOf: [
             {
                 // 用来匹配 .css 结尾的文件
                 test: /.css$/,
                 // use 数组里面 Loader 执行顺序是从右到左
                 use: [MiniCssExtractPlugin.loader, "css-loader", {
                     loader: "postcss-loader",
                     options: {
                         postcssOptions: {
                             plugins: ['postcss-preset-env']
                         }
                     }
                 }],
             },
             {
                 test: /.less$/,
                 use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],
             },
             {
                 test: /.js$/,
                 exclude: /node_modules/, // 排除node_modules代码不编译
                 loader: "babel-loader",
             },
         ]
     }
 ],
},

生产模式依旧是这么配置

Include/Exclude

  1. 为啥?

    有些文件我们在打包的时候并不需要进行编译(比如:node_modules)

  2. 是啥?

    include:只处理指定文件

    exclude:排除文件不进行处理

  3. 用法:

{
    test: /.js$/,
    //exclude: /node_modules/, // 排除node_modules代码不编译
    include: path.resolve(__dirname,'../src'), //只处理src文件
    loader: "babel-loader",
},

include与exclude 二选一,不能同时存存在,只针对JS文件(样式没必要)

Cache缓存

  1. 为啥?

    每次进行打包操作都需要经过Eslint检查和Babel编译,速度较慢,我们可以缓存之前的Eslint检查和Babel编译结果,这样第二次打包速度就会很快了。

  2. 是啥?

    是缓存(对Eslint和Babel编译结果进行缓存),只针对第二次......

  3. 使用

{
    test: /.js$/,
    //exclude: /node_modules/, // 排除node_modules代码不编译
    include: path.resolve(__dirname,'../src'), //只处理src文件
    loader: "babel-loader",
    options: {
        cacheDirectory:true, //开启babel缓存
        cacheCompression:false //关闭缓存文件压缩

    }
},
plugins: [
    new ESLintWebpackPlugin({
        // 指定检查文件的根目录
        context: path.resolve(__dirname, "../src"),
        cache: true, //开启缓存
        exclude:"node_modules" //默认值
    })
],

Thead

  1. 为啥?

    项目变大,打包速度越来越慢,开启多线程同时处理js文件

  2. 是啥?

    多线程打包:开启电脑的多个线程干同一件事

  3. 用法:

  • 获取CPU核心数
const os = require('os') //node.js核心模块直接使用

const threads = os.cpus().length //cpu核心数
  • 安装loader npm i thread-loader -D
  • 使用:

JS Babel开启多线程(thread-loader必须在babel-loader之前)

{
    test: /.js$/,
    //exclude: /node_modules/, // 排除node_modules代码不编译
    include: path.resolve(__dirname, '../src'), //只处理src文件
    use: [
        {
            loader: "thread-loader", //开启多线程
            options: {
                workers:threads
            }
        },
        {
            loader: "babel-loader",
            options: {
                cacheDirectory: true, //开启babel缓存
                cacheCompression: false //关闭缓存文件压缩

            }
        }
    ]
},

ESlint开启多线程

new ESLintWebpackPlugin({
    // 指定检查文件的根目录
    context: path.resolve(__dirname, "../src"),
    cache: true,
    exclude: "node_modules", //默认值
    threads
}),

压缩 JavaScript

const TerserPlugin = require('terser-webpack-plugin')

optimization: {
    minimize: true,
    minimizer: [
        //css压缩
        new CssMinimizerPlugin(),
        //多线程
        new TerserPlugin({
            parallel: threads
        })
    ]
},

webpack5 默认安装terser-webpack-plugin 但是如果你需要自定义配置依旧需要安装

减少代码体积

Tree Shaking

  1. 为什么?

开发所定义的一些工具函数库或者第三方函数库或者组件库,不进行处理就会引入整个库但是我们可能使用的是极小部分功能。整个库打包进去,体积太大

  1. 是什么?

用于移除Javscript中没有使用的代码

  1. 如何使用: 默认开启,无需配置

Babel

  1. 为什么?

Babel 为编译的每个文件都插入了辅助代码,使代码体积过大,避免公共方法的重复引用,需要将这些辅助代码作为一个独立模块,避免重复引入。

  1. 是什么? @babel/plugin-transform-runtime: 禁用了 Babel 自动对每个文件的 runtime 注入,而是引入 @babel/plugin-transform-runtime 并且使所有辅助代码从这里引用。

  2. 咋用?

    • 安装 npm i @babel/plugin-transform-runtime -D
    • 配置
{
    test: /.js$/,
    //exclude: /node_modules/, // 排除node_modules代码不编译
    include: path.resolve(__dirname, '../src'), //只处理src文件
    use: [
        {
            loader: "thread-loader", //开启多线程
            options: {
                workers: threads
            }
        },
        {
            loader: "babel-loader",
            options: {
                cacheDirectory: true, //开启babel缓存
                cacheCompression: false, //关闭缓存文件压缩
                plugins:["@babel/plugin-transform-runtime"] //减少代码体积
            }
        }
    ]
}

Image Minimizer

  1. 为啥?

项目图片较多,图片体积较大

  1. 是什么? 用来压缩图片的插件

  2. 咋用?

    • 下载包 npm i image-minimizer-webpack-plugin imagemin -D
    • 无损压缩npm install imagemin-gifsicle imagemin-jpegtran imagemin-optipng imagemin-svgo -D
    • 配置
const ImageMinimizerPlugin = require("image-minimizer-webpack-plugin");
   
optimization: {
   minimize: true,
   minimizer: [
       //css压缩
       new CssMinimizerPlugin(),
       //多线程
       new TerserPlugin({
           parallel: threads
       }),
       new ImageMinimizerPlugin({
           minimizer: {
               implementation: ImageMinimizerPlugin.imageminGenerate,
               options: {
                   plugins: [
                       ["gifsicle", { interlaced: true }],
                       ["jpegtran", { progressive: true }],
                       ["optipng", { optimizationLevel: 5 }],
                       [                           "svgo",                           {                               plugins: [                                   "preset-default",                                   "prefixIds",                                   {                                       name: "sortAttrs",                                       params: {                                           xmlnsOrder: "alphabetical",                                       },                                   },                               ],
                           },
                       ],
                   ],
               },
           },
       }),
   ]
},