如何在项目中合理配置Webpack

项目中配置 webpack 有三个目的,打包速度,打包体积,运行流畅度,速度指的是run build的时间,体积是指dist 的大小,流畅指的是打开页面是否不卡顿

打包速度

提升打包速度有以下方式,范围优化,多进程打包,利用缓存

测试打包速度利用speed-measure-webpack-plugin如:

js 复制代码
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
 plugins: [
    new VueLoaderPlugin(),
    new SpeedMeasurePlugin(),
    new HtmlWebpackPlugin({ template: "./public/index.html" }), //JS或者CSS文件可以自动引入到html中
  ],

范围优化

alias 配置路径别名,优化文件查找速度

javascript 复制代码
function pathResolve(dir) {
  return path.join(__dirname,dir)
}

resolve: {
  alias: {
    "@": pathResolve("src"),
    "page":pathResolve("src/page")
  },
},

extensions 文件扩展名配置,频率高的放在前面

javascript 复制代码
resolve: {
    extensions: [".js", ".css", ".vue"], //第一种配置后缀名
    extensions: [".vue", ".js", ".json", ".css"], //第二种配置后缀名
  },

modules 解析模块时应该搜索的目录

javascript 复制代码
 resolve: {
    // modules: ["node_modules", pathResolve("src")],
  },
javascript 复制代码
resolve: {
  modules: ["node_modules", pathResolve("src")],
},

externals 配置

配合 cdn 降低一些依赖打包构建

  • 不配置externals

安装 jquery

shell 复制代码
npm install jquery
javascript 复制代码
<template>
  <router-view></router-view>
</template>

<script>
import $ from 'jquery'
import {  cloneDeep } from "lodash";
export default {
  name: "App",
  mounted() {
    const aa = {
      ddd: () => {
        console.log(1111);
      },
    };
    console.log(cloneDeep(aa));

    console.log($('.app'))
  },
};
</script>

<style scoped></style>
  • 配置 externals
javascript 复制代码
externals: {
    jquery: 'jQuery',
  },
javascript 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script
      src="https://code.jquery.com/jquery-3.1.0.js"
      integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
      crossorigin="anonymous"
    ></script>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

noParse

防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中 不应该含有 <font style="color:rgb(43, 58, 66);">import</font>, <font style="color:rgb(43, 58, 66);">require</font>, <font style="color:rgb(43, 58, 66);">define</font> 的调用,或任何其他导入机制。忽略大型的 library 可以提高构建性能。

javascript 复制代码
module.exports = {
  //...
  module: {
    noParse: /jquery|lodash/,
  },
};

include/exclude

控制范围提高构建速度

  • **<font style="color:rgb(251, 112, 53);background-color:rgb(238, 238, 238);">include</font>**:符合条件的模块进行解析
  • **<font style="color:rgb(251, 112, 53);background-color:rgb(238, 238, 238);">exclude</font>**:排除符合条件的模块,不解析,优先级更高
javascript 复制代码
{ test: /\.js$/, exclude: /node_modules/,include: pathResolve('src'), loader: "babel-loader" },

IgnorePlugin

阻止为与正则表达式或过滤器函数匹配的 <font style="color:rgb(43, 58, 66);">import</font><font style="color:rgb(43, 58, 66);">require</font> 调用生成模块;

可以用于 momentjs 处理时区

多进程打包

thread-loader 使用时,需将此 loader 放置在其他 loader 之前。放置在此 loader 之后的 loader 会在一个独立的 worker 池中运行。

每个 worker 都是一个独立的 node.js 进程,其开销大约为 600ms 左右。同时会限制跨进程的数据交换。

请仅在耗时的操作中使用此 loader!

缓存

js 缓存

javascript 复制代码
{
  test: /\.js$/,
    exclude: /node_modules/,
    include: pathResolve("src"),
    use: [
    {
      loader: "babel-loader", // 开启多进程打包
      options: {
        cacheDirectory: true,
      },
    },
  ],
},

样式缓存

添加 cache-loader

javascript 复制代码
{
  test: /\.less$/,
    use: [
    "style-loader",
    "cache-loader",
    "css-loader",
    "less-loader",
  ],
    },

持久化缓存

webpack5 开启 cache 缓存模块

javascript 复制代码
module.exports = {
  //...
  cache: {
    type: 'memory',
  },
};

打包体积

测试打包体积利用<font style="color:#DF2A3F;">webpack-bundle-analyzer</font>,打包时会开启本地构建每个包的大小

javascript 复制代码
const BundleAnalyzerPlugin =
  require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
module.exports = {
    plugins: [
    new VueLoaderPlugin(),
    // new SpeedMeasurePlugin(),
    new BundleAnalyzerPlugin(),
    new HtmlWebpackPlugin({ template: "./public/index.html" }), //JS或者CSS文件可以自动引入到html中
  ],
}

CSS 压缩

powershell 复制代码
npm install css-minimizer-webpack-plugin --save-dev
javascript 复制代码
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
  optimization: {
    minimize: true, // 开启后会在开发环境生效
    minimizer: [
      // 添加 css 压缩配置
      new CssMinimizerPlugin(),
    ],
  },Ï
}

JS 压缩

webpack5 内置了terser-webpack-plugin插件,所以我们不需重复安装,直接引用就可以了,具体配置如下

powershell 复制代码
module.exports = {
  
  optimization: {
    minimize: true, // 开发环境开启才生效
    minimizer: [
      new TerserPlugin({})
    ]
  },
}

TREE SHAKING 摇树

打包时不将项目中引入未使用的代码打包进去,在 package.json 中开启 sideEffects

powershell 复制代码
{
  sideEffects:false/true/[]
}
  • true 所有文件都有副作用,全都不可 <font style="background-color:rgb(238, 238, 238);">tree-shaking</font>
  • false 有这些文件有副作用,所有其他文件都可以 <font style="background-color:rgb(238, 238, 238);">tree-shaking</font>,但会保留这些文件
  • [] 选中的单位进行 <font style="color:rgb(85, 85, 85);">tree shaking</font>

GZIP 压缩

在构建过程中生成Gzip文件,从而减少传输到客户端的数据大小,提高加载速度。

powershell 复制代码
npm install compression-webpack-plugin --save-dev
javascript 复制代码
const CompressionWebpackPlugin = require('compression-webpack-plugin')

module.exports = {
  // 其他配置...
  plugins: [
    new CompressionWebpackPlugin({
      filename: '[path][base].gz', // 输出的Gzip文件名格式
      algorithm: 'gzip', // 使用gzip算法
      test: /\.js$|\.css$|\.html$/, // 哪些文件需要进行压缩
      threshold: 10240, // 只有文件大小大于该值时才会被压缩,默认是10KB
      minRatio: 0.8, // 压缩率小于这个值的资源将不会被压缩
      deleteOriginalAssets: false // 是否删除原文件,默认为false
    })
  ],
  
};

运行流畅度

运行流畅度优化的目的就是提升首屏的加载速度,方式有降低首屏加载文件体积,首屏不需要的文件进行预加载或者按需加载

splitChunks 分包

首屏分包利用浏览器的并发请求来提高首屏包的加载速度,<font style="color:rgb(44, 44, 54);">splitChunks</font> 允许我们将公共模块、第三方库等拆分到单独的 chunk 文件中,从而实现更细粒度的代码分割和缓存策略。

javascript 复制代码
module.exports = {
  // 其他配置...
  optimization: {
    splitChunks: {
      chunks: 'all', // 对所有类型的chunk进行处理(包括异步和非异步)
      minSize: 20000, // 形成一个新chunk最小的文件大小(单位:字节)
      maxSize: 0, // 最大尺寸目标,超过该值会尝试再分割,默认为0表示不启用
      minChunks: 1, // 模块至少应被共享的次数(即最少引用了多少次)
      maxAsyncRequests: 30, // 按需加载的最大并行请求数
      maxInitialRequests: 30, // 入口点处的最大并行请求数
      automaticNameDelimiter: '~', // 文件名连接符
      name(module, chunks, cacheGroupKey) {
        return cacheGroupKey + '_' + chunks.map(chunk => chunk.name).join('~');
      }, // 自定义chunk名称生成规则
      cacheGroups: { // 缓存组配置
        vendors: {
          test: /[\\/]node_modules[\\/]/, // 匹配node_modules下的模块
          priority: -10, // 优先级,数值越大优先级越高
          filename: 'vendors.js', // 输出文件名
          enforce: true, // 强制分割,即使未达到minSize条件也进行分割
        },
        default: {
          minChunks: 2, // 模块至少被引用两次才会被提取
          priority: -20,
          reuseExistingChunk: true, // 如果当前chunk包含已从主bundle中拆分出的模块,则重用而不是创建新的chunk
        },
      },
    },
  },
};

图片懒加载

利用 prefetch 和 preload 来优化大图片加载过慢问题

  • prefetch (预获取):浏览器空闲的时候进行资源的拉取
  • preload (预加载):提前加载后面会用到的关键资源
javascript 复制代码
import( /* webpackPrefetch: true */ './img')
import(/* webpackPreload: true */ './img');

总结

webpack 优化的三个目的速度,体积,流畅度在很多大项目中都是十分必要的,不管后续如何优化都万变不离其宗

相关推荐
ZTStory1 天前
Webpack打包十六进制转十进制异常引发的白屏惨案
前端·javascript·webpack
捻tua馔...2 天前
归纳webpack
前端·webpack
还这么多错误?!2 天前
webpack打包要义
前端·webpack
厚礼蟹man2 天前
使用pnpm搭建你的monorepo三步走
前端·前端工程化
棋丶2 天前
Webpack和Vite的区别
前端·webpack·node.js
WebInfra2 天前
Build System 视角:重新认识前端打包工具的设计哲学
前端·设计模式·webpack
huaqianzkh3 天前
了解Webpack:现代前端开发的静态模块打包器
前端·webpack·node.js
来吧~5 天前
webpack常见优化方法
前端·webpack·node.js
柠檬豆腐脑5 天前
前端构建工具的发展和现状:Webpack、Vite和其他
前端·webpack·vite