如何在项目中合理配置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>,但会保留这些文件
  • \] 选中的单位进行 `tree shaking`

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

相关推荐
好好学习啊天天向上40 分钟前
CFD,GPU加速效果,FUN3D GPU移植加速效果2
javascript·opencv·webpack
问道飞鱼1 天前
【前端知识】前端项目不同构建模式的差异
前端·webpack·构建·开发模式·生产模式
Rabi'2 天前
编译ATK源码
前端·webpack·node.js
紫小米2 天前
webpack详解和实操
前端·webpack·node.js
karshey2 天前
【前端】svelte支持scss,包管理器是webpack
前端·webpack·scss
转转技术团队4 天前
基于微前端 qiankun 多实例保活的工程实践
前端·javascript·前端工程化
Roc.Chang4 天前
终极指南:解决 Vue 项目中 “regenerator-runtime/runtime“ 缺失报错
前端·javascript·vue.js·webpack·前端工程
Maxkim5 天前
一文读懂 Chrome CRX📦:你需要了解的核心知识点
前端·前端工程化