如何在项目中合理配置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 优化的三个目的速度,体积,流畅度在很多大项目中都是十分必要的,不管后续如何优化都万变不离其宗

相关推荐
小纯洁w6 小时前
Webpack 的 require.context 和 Vite 的 import.meta.glob 的详细介绍和使用
前端·webpack·node.js
海盗强13 小时前
Webpack打包优化
前端·webpack·node.js
祈澈菇凉19 小时前
如何优化 Webpack 的构建速度?
前端·webpack·node.js
懒羊羊我小弟1 天前
常用 Webpack Plugin 汇总
前端·webpack·npm·node.js·yarn
祈澈菇凉2 天前
Webpack的持久化缓存机制具体是如何实现的?
前端·webpack·gulp
懒羊羊我小弟3 天前
Webpack 基础入门
前端·webpack·rust·node.js·es6
刽子手发艺3 天前
Selenium+OpenCV处理滑块验证问题
opencv·selenium·webpack
懒羊羊我小弟3 天前
常用Webpack Loader汇总介绍
前端·webpack·node.js
真的很上进5 天前
【1.8w字深入解析】从依赖地狱到依赖天堂:pnpm 如何革新前端包管理?
java·前端·vue.js·python·webpack·node.js·reactjs
SuperherRo6 天前
信息收集-Web应用&JS架构&URL提取&数据匹配&Fuzz接口&WebPack分析&自动化
javascript·webpack·自动化·fuzz