乐趣区

关于javascript:学习-Webpack5-之路优化篇

一、前言

从 0 到 1 学习的敌人可参考前置学习文章:

  • 学习 Webpack5 之路(根底篇)
  • 学习 Webpack5 之路(实际篇)

前置文章 学习 Webpack5 之路(根底篇)对 webpack 的概念做了简略介绍,学习 Webpack5 之路(实际篇)则从配置着手,用 webpack 搭建了一个 SASS + TS + React 的我的项目。

本篇将从优化开发体验、放慢编译速度、减小打包体积、放慢加载速度 4 个角度登程,介绍如何对 webpack 我的项目进行优化。

本文依赖的 webpack 版本信息如下:

  • webpack-cli@4.7.2
  • webpack@5.46.0

二、优化效率工具

在优化开始之前,须要做一些筹备工作。

装置以下 webpack 插件,帮忙咱们剖析优化效率:

  • progress-bar-webpack-plugin:查看编译进度;
  • speed-measure-webpack-plugin:查看编译速度;
  • webpack-bundle-analyzer:打包体积剖析。

1. 编译进度条

一般来说,中型我的项目的首次编译工夫为 5-20s,没个进度条等得多焦急,通过 progress-bar-webpack-plugin 插件查看编译进度,不便咱们把握编译状况。

装置:

npm i -D progress-bar-webpack-plugin

webpack.common.js 配置形式如下:

const chalk = require("chalk");
const ProgressBarPlugin = require("progress-bar-webpack-plugin");
module.exports = {
  plugins: [
    // 进度条
    new ProgressBarPlugin({format: `  :msg [:bar] ${chalk.green.bold(":percent")} (:elapsed s)`,
    }),
  ],
};

贴心的为进度百分比增加了加粗和绿色高亮态款式。

蕴含内容、进度条、进度百分比、耗费工夫,进度条成果如下:

2. 编译速度剖析

优化 webpack 构建速度,首先须要晓得是哪些插件、哪些 loader 耗时长,不便咱们针对性的优化。

通过 speed-measure-webpack-plugin 插件进行构建速度剖析,能够看到各个 loader、plugin 的构建时长,后续可针对耗时 loader、plugin 进行优化。

装置:

npm i -D speed-measure-webpack-plugin

webpack.dev.js 配置形式如下:

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
module.exports = smp.wrap({// ...webpack config...});

蕴含各工具的构建耗时,成果如下:

留神:这些灰色文字的款式,是因为我在 vscode 终端运行的,导致有色彩的字体都显示为灰色,换个终端就好了,如 iTerm2。

3. 打包体积剖析

同样,优化打包体积,也须要先剖析各个 bundle 文件的占比大小,来进行针对优化。

应用 webpack-bundle-analyzer 查看打包后生成的 bundle 体积剖析,将 bundle 内容展现为一个便捷的、交互式、可缩放的树状图模式。帮忙咱们剖析输入后果来查看模块在何处完结。

装置:

npm i -D webpack-bundle-analyzer

webpack.prod.js 配置形式如下:

const BundleAnalyzerPlugin =
  require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
module.exports = {
  plugins: [
    // 打包体积剖析
    new BundleAnalyzerPlugin(),],
};

蕴含各个 bundle 的体积剖析,成果如下:

三、优化开发体验

1. 自动更新

自动更新 指的是,在开发过程中,批改代码后,无需手动再次编译,能够主动编译代码更新编译后代码的性能。

webpack 提供了以下几种可选形式,实现自动更新性能:

  1. webpack’s Watch Mode
  2. webpack-dev-server
  3. webpack-dev-middleware

webpack 官网举荐的形式是  webpack-dev-server,在 学习 Webpack5 之路(实际篇)– DevServer 章节 曾经介绍了 webpack-dev-server  帮忙咱们在代码发生变化后主动编译代码实现 自动更新 的用法,在这里不反复赘述。

这是针对开发环境的优化,批改 webpack.dev.js 配置。

2. 热更新

热更新 指的是,在开发过程中,批改代码后,仅更新批改局部的内容,无需刷新整个页面。

2.1 批改 webpack-dev-server 配置

应用 webpack 内置的 HMR 插件,更新 webpack-dev-server 配置。

webpack.dev.js 配置形式如下:

module.export = {
  devServer: {
    contentBase: "./dist",
    hot: true, // 热更新
  },
};

2.2 引入 react-refresh-webpack-plugin

应用 react-refresh-webpack-plugin 热更新 react 组件。

装置:

npm install -D @pmmmwh/react-refresh-webpack-plugin react-refresh

webpack.dev.js 配置形式如下:

const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");

module.exports = {
  plugins: [new webpack.HotModuleReplacementPlugin(),
    new ReactRefreshWebpackPlugin(),],
};

遇到的问题:

配置了 SpeedMeasurePlugin 后,热更新就有效了,会提醒 runtime is undefined

解决方案:

仅在剖析构建速度时关上 SpeedMeasurePlugin 插件,这里咱们先敞开 SpeedMeasurePlugin 的应用,来查看热更新成果。

最终成果:

更新 react 组件代码时,无需刷新页面,仅更新组件局部。

四、放慢构建速度

1. 更新版本

1.1 webpack 版本

应用最新的 webpack 版本,通过 webpack 本身的迭代优化,来放慢构建速度。

这一点是十分无效的,如 webpack5 较于 webpack4,新增了长久化缓存、改良缓存算法等优化,webpack5 新个性可查看 参考资料。

1.2 包管理工具版本

将  Node.js、package 管理工具(例如  npm  或者  yarn)更新到最新版本,也有助于进步性能。较新的版本可能建设更高效的模块树以及进步解析速度。

本文依赖的版本信息如下:

  • webpack@5.46.0
  • node@14.15.0
  • npm@6.14.8

2. 缓存

2.1 cache

通过配置 webpack 长久化缓存 cache: filesystem,来缓存生成的 webpack 模块和 chunk,改善构建速度。

简略来说,通过 cache: filesystem 能够将构建过程的 webpack 模板进行缓存,大幅晋升二次构建速度、打包速度,当构建忽然中断,二次进行构建时,能够间接从缓存中拉取,可提速 90% 左右。

webpack.common.js 配置形式如下:

module.exports = {
  cache: {type: "filesystem", // 应用文件缓存},
};

引入缓存后,首次构建工夫将减少 15%,二次构建工夫将缩小 90%,成果如下:

2.2 dll ❌

在 webpack 官网构建性能 中看到对于 dll 的介绍:

dll 能够为更改不频繁的代码生成独自的编译后果。能够进步应用程序的编译速度。

我灰溜溜的开始寻找 dll 的相干配置阐明,太简单了,接着找到了一个辅助配置 dll 的插件 autodll-webpack-plugin,后果下面间接写了 webpack5 开箱即用的长久缓存是比 dll 更优的解决方案。

所以,不必再配置 dll 了,下面介绍的 cache 显著更香。

2.3 cache-loader ❌

没错,cache-loader 也不须要引入了,下面的 cache 曾经帮忙咱们缓存了。

3. 缩小 loader、plugins

每个的 loader、plugin 都有其启动工夫。尽量少地应用工具,将非必须的 loader、plugins 删除。

3.1 指定 include

为 loader 指定 include,缩小 loader 利用范畴,仅利用于起码数量的必要模块,。

webpack 构建性能文档

rule.exclude 能够排除模块范畴,也可用于缩小 loader 利用范畴.

webpack.common.js 配置形式如下:

module.exports = {
  rules: [
    {test: /\.(js|ts|jsx|tsx)$/,
      include: paths.appSrc,
      use: [
        {
          loader: "esbuild-loader",
          options: {
            loader: "tsx",
            target: "es2015",
          },
        },
      ],
    },
  ],
};

定义 loader 的 include 后,构建工夫将缩小 12%,成果如下:

3.2 治理资源

应用 webpack 资源模块 (asset module) 代替旧的 assets loader(如  file-loader/url-loader/raw-loader  等),缩小 loader 配置数量。

配置形式如下:

module.exports = {
  rules: [
    {test: /\.(png|svg|jpg|jpeg|gif)$/i,
      include: [paths.appSrc],
      type: "asset/resource",
    },
  ],
};

引入资源模块后,构建工夫将缩小 7%,成果如下:

4. 优化 resolve 配置

resolve 用来配置 webpack 如何解析模块,可通过优化 resolve 配置来笼罩默认配置项,缩小解析范畴。

4.1 alias

alias 能够创立  import  或  require  的别名,用来简化模块引入。

webpack.common.js 配置形式如下:

module.exports = {
  resolve: {
    alias: {"@": paths.appSrc, // @ 代表 src 门路},
  },
};

4.2 extensions

extensions 示意须要解析的文件类型列表。

依据我的项目中的文件类型,定义 extensions,以笼罩 webpack 默认的 extensions,放慢解析速度。

因为 webpack 的解析程序是从左到右,因而要将应用频率高的文件类型放在左侧,如下我将 tsx 放在最左侧。

webpack.common.js 配置形式如下:

module.exports = {
  resolve: {extensions: [".tsx", ".js"], // 因为我的我的项目只有这两种类型的文件,如果有其余类型,须要增加进去。},
};

4.3 modules

modules 示意 webpack 解析模块时须要解析的目录。

指定目录可放大 webpack 解析范畴,放慢构建速度。

webpack.common.js 配置形式如下:

module.exports = {modules: ["node_modules", paths.appSrc],
};

4.4 symlinks

如果我的项目不应用 symlinks(例如  npm link  或者  yarn link),能够设置  resolve.symlinks: false,缩小解析工作量。

webpack.common.js 配置形式如下:

module.exports = {
    resolve: {symlinks: false,},
}

优化 resolve 配置后,构建工夫将缩小 1.5%,成果如下:

5. 多过程

上述能够看到 sass-loader 的构建工夫有 1.56s,占据了整个构建过程的 60%,那么有没有办法来放慢 sass-loader 的构建速度呢?

能够通过多过程来实现,试想将 sass-loader 放在一个独立的 worker 池中运行,就不会妨碍其余 loader 的构建了,能够大大放慢构建速度。

5.1 thread-loader

通过 thread-loader 将耗时的 loader 放在一个独立的 worker 池中运行,放慢 loader 构建速度。

装置:

npm i -D thread-loader

webpack.common.js 配置形式如下:

module.exports = {
  rules: [
    {test: /\.module\.(scss|sass)$/,
      include: paths.appSrc,
      use: [
        "style-loader",
        {
          loader: "css-loader",
          options: {
            modules: true,
            importLoaders: 2,
          },
        },
        {
          loader: "postcss-loader",
          options: {
            postcssOptions: {plugins: [["postcss-preset-env"]],
            },
          },
        },
        {
          loader: "thread-loader",
          options: {workerParallelJobs: 2,},
        },
        "sass-loader",
      ].filter(Boolean),
    },
  ],
};

webpack 官网 提到 node-sass  中有个来自 Node.js 线程池的阻塞线程的 bug。当应用  thread-loader  时,须要设置  workerParallelJobs: 2

因为 thread-loader 引入后,须要 0.6s 左右的工夫开启新的 node 过程,本我的项目代码量小,可见引入 thread-loader 后,构建工夫反而减少了 0.19s。

因而,咱们应该仅在十分耗时的 loader 前引入 thread-loader。

成果如下:

5.2 happypack ❌

happypack 同样是用来设置多线程,然而在 webpack5 就不要再应用 happypack 了,官网也曾经不再保护了,举荐应用上文介绍的 thread-loader。

6. 辨别环境

在 学习 Webpack5 之路(实际篇)– 模式(mode)章节 曾经介绍了 webpack 的不同模式的内置优化。

在开发过程中,切忌在开发环境应用生产环境才会用到的工具,如在开发环境下,应该排除 [fullhash]/[chunkhash]/[contenthash] 等工具。

同样,在生产环境,也应该防止应用开发环境才会用到的工具,如 webpack-dev-server 等插件。

7. 其余

7.1 devtool

不同的  devtool  设置,会导致性能差别。

在大多数状况下,最佳抉择是  eval-cheap-module-source-map

具体辨别可至 webpack devtool 查看。

webpack.dev.js 配置形式如下:

export.module = {devtool: 'eval-cheap-module-source-map',}

7.2 输入后果不携带门路信息

默认 webpack 会在输入的 bundle 中生成门路信息,将门路信息删除可小幅晋升构建速度。

module.exports = {
    output: {pathinfo: false,},
    };
}

四、减小打包体积

1. 代码压缩

体积优化第一步是压缩代码,通过 webpack 插件,将 JS、CSS 等文件进行压缩。

1.1 JS 压缩

应用  TerserWebpackPlugin  来压缩 JavaScript。

webpack5 自带最新的  terser-webpack-plugin,无需手动装置。

terser-webpack-plugin 默认开启了 parallel: true 配置,并发运行的默认数量:os.cpus().length - 1,本文配置的 parallel 数量为 4,应用多过程并发运行压缩以进步构建速度。

webpack.prod.js 配置形式如下:

const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: 4,
        terserOptions: {
          parse: {ecma: 8,},
          compress: {
            ecma: 5,
            warnings: false,
            comparisons: false,
            inline: 2,
          },
          mangle: {safari10: true,},
          output: {
            ecma: 5,
            comments: false,
            ascii_only: true,
          },
        },
      }),
    ],
  },
};

体积减小 10%,成果如下:

1.1 ParallelUglifyPlugin ❌

你可能有听过 ParallelUglifyPlugin 插件,它能够帮忙咱们多过程压缩 JS,webpack5 的 TerserWebpackPlugin 默认就开启了多过程和缓存,无需再引入 ParallelUglifyPlugin。

1.2 CSS 压缩

应用 CssMinimizerWebpackPlugin 压缩 CSS 文件。

和 optimize-css-assets-webpack-plugin 相比,css-minimizer-webpack-plugin 在 source maps 和 assets 中应用查问字符串会更加精确,而且反对缓存和并发模式下运行。

CssMinimizerWebpackPlugin 将在 Webpack 构建期间搜寻 CSS 文件,优化、压缩 CSS。

装置:

npm install -D css-minimizer-webpack-plugin

webpack.prod.js 配置形式如下:

const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

module.exports = {
  optimization: {
    minimizer: [
      new CssMinimizerPlugin({parallel: 4,}),
    ],
  },
};

因为 CSS 默认是放在 JS 文件中,因而本示例是基于下章节将 CSS 代码拆散后的成果。

2. 代码拆散

代码拆散可能把代码拆散到不同的 bundle 中,而后能够按需加载或并行加载这些文件。代码拆散能够用于获取更小的 bundle,以及管制资源加载优先级,能够缩短页面加载工夫。

2.1 抽离反复代码

SplitChunksPlugin  插件开箱即用,能够将公共的依赖模块提取到已有的入口 chunk 中,或者提取到一个新生成的 chunk。

webpack 将依据以下条件主动拆分 chunks:

  • 新的 chunk 能够被共享,或者模块来自于  node_modules  文件夹;
  • 新的 chunk 体积大于 20kb(在进行 min+gz 之前的体积);
  • 当按需加载 chunks 时,并行申请的最大数量小于或等于 30;
  • 当加载初始化页面时,并发申请的最大数量小于或等于 30;
    通过 splitChunks 把 react 等公共库抽离进去,不反复引入占用体积。

留神:切记不要为 cacheGroups 定义固定的 name,因为 cacheGroups.name 指定字符串或始终返回雷同字符串的函数时,会将所有常见模块和 vendor 合并为一个 chunk。这会导致更大的初始下载量并减慢页面加载速度。

webpack.prod.js 配置形式如下:

module.exports = {
  splitChunks: {
    // include all types of chunks
    chunks: "all",
    // 反复打包问题
    cacheGroups: {
      vendors: {
        // node_modules 里的代码
        test: /[\\/]node_modules[\\/]/,
        chunks: "all",
        // name: 'vendors', 肯定不要定义固定的 name
        priority: 10, // 优先级
        enforce: true,
      },
    },
  },
};

将公共的模块独自打包,不再反复引入,成果如下:

2.2 CSS 文件拆散

MiniCssExtractPlugin 插件将 CSS 提取到独自的文件中,为每个蕴含 CSS 的 JS 文件创建一个 CSS 文件,并且反对 CSS 和 SourceMaps 的按需加载。

装置:

npm install -D mini-css-extract-plugin

webpack.common.js 配置形式如下:

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {plugins: [new MiniCssExtractPlugin()],
  module: {
    rules: [
      {test: /\.module\.(scss|sass)$/,
        include: paths.appSrc,
        use: [
          "style-loader",
          isEnvProduction && MiniCssExtractPlugin.loader, // 仅生产环境
          {
            loader: "css-loader",
            options: {
              modules: true,
              importLoaders: 2,
            },
          },
          {
            loader: "postcss-loader",
            options: {
              postcssOptions: {plugins: [["postcss-preset-env"]],
              },
            },
          },
          {
            loader: "thread-loader",
            options: {workerParallelJobs: 2,},
          },
          "sass-loader",
        ].filter(Boolean),
      },
    ],
  },
};

留神:MiniCssExtractPlugin.loader 要放在 style-loader 前面。

成果如下:

2.3 最小化 entry chunk

通过配置 optimization.runtimeChunk = true,为运行时代码创立一个额定的 chunk,缩小 entry chunk 体积,进步性能。

webpack.prod.js 配置形式如下:

module.exports = {
    optimization: {runtimeChunk: true,},
    };
}

成果如下:

3. Tree Shaking(摇树)

摇树,顾名思义,就是将枯黄的落叶摇下来,只留下树上活的叶子。枯黄的落叶代表我的项目中未援用的无用代码,活的树叶代表我的项目中理论用到的源码。

3.1 JS

JS Tree Shaking 将 JavaScript 上下文中的未援用代码(Dead Code)移除,通过  package.json  的  "sideEffects"  属性作为标记,向 compiler 提供提醒,表明我的项目中的哪些文件是 “pure(纯正 ES2015 模块)”,由此能够平安地删除文件中未应用的局部。

Dead Code 个别具备以下几个特色:

  • 代码不会被执行,不可达到;
  • 代码执行的后果不会被用到;
  • 代码只会影响死变量(只写不读)。

3.1.1 webpack5 sideEffects

通过 package.json 的  "sideEffects"  属性,来实现这种形式。

{
  "name": "your-project",
  "sideEffects": false
}

需注意的是,当代码有副作用时,须要将 sideEffects 改为提供一个数组,增加有副作用代码的文件门路:

{
  "name": "your-project",
  "sideEffects": ["./src/some-side-effectful-file.js"]
}

增加 TreeShaking 后,未援用的代码,将不会被打包,成果如下:

3.1.2 对组件库援用的优化

webpack5 sideEffects 只能革除无副作用的援用,而有副作用的援用则只能通过优化援用形式来进行 Tree Shaking

1. lodash

相似 import {throttle} from 'lodash' 就属于有副作用的援用,会将整个 lodash 文件进行打包。

优化形式是应用 import {throttle} from 'lodash-es' 代替 import {throttle} from 'lodash',lodash-es 将 Lodash 库导出为 ES 模块,反对基于 ES modules 的 tree shaking,实现按需引入。

2. ant-design

ant-design 默认反对基于 ES modules 的 tree shaking,对于 js 局部,间接引入  import {Button} from 'antd'  就会有按需加载的成果。

如果我的项目中仅引入少部分组件,import {Button} from 'antd' 也属于有副作用,webpack 不能把其余组件进行 tree-shaking。这时能够 放大援用范畴,将引入形式批改为 import {Button} from 'antd/lib/button' 来进一步优化。

3.2 CSS

上述对 JS 代码做了 Tree Shaking 操作,同样,CSS 代码也须要摇摇树,打包时把没有用的 CSS 代码摇走,能够大幅缩小打包后的 CSS 文件大小。

应用 purgecss-webpack-plugin 对 CSS Tree Shaking。

装置:

npm i purgecss-webpack-plugin -D

因为打包时 CSS 默认放在 JS 文件内,因而要联合 webpack 拆散 CSS 文件插件 mini-css-extract-plugin 一起应用,先将 CSS 文件拆散,再进行 CSS Tree Shaking。

webpack.prod.js 配置形式如下:

const glob = require("glob");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const PurgeCSSPlugin = require("purgecss-webpack-plugin");
const paths = require("paths");

module.exports = {
  plugins: [
    // 打包体积剖析
    new BundleAnalyzerPlugin(),
    // 提取 CSS
    new MiniCssExtractPlugin({filename: "[name].css",
    }),
    // CSS Tree Shaking
    new PurgeCSSPlugin({paths: glob.sync(`${paths.appSrc}/**/*`, {nodir: true}),
    }),
  ],
};

下面为了测试 CSS 压缩成果,我引入了大量有效 CSS 代码,因而 Tree Shaking 成果也非常明显,成果如下:

3. CDN

上述是对 webpack 配置的优化,另一方面还能够通过 CDN 来减小打包体积。

这里引入 CDN 的首要目标为了缩小打包体积,因而仅仅将一部分大的动态资源手动上传至 CDN,并批改本地引入门路。下文的放慢加载速度,将介绍另一种 CDN 优化伎俩。

将大的动态资源上传至 CDN:

  • 字体:压缩并上传至 CDN;
  • 图片:压缩并上传至 CDN。

五、放慢加载速度

1. 按需加载

通过 webpack 提供的 import() 语法 动静导入 性能进行代码拆散,通过按需加载,大大晋升网页加载速度。

应用形式如下:

export default function App() {
  return (
    <div>
      hello react 111
      <Hello />
      <button onClick={() => import("lodash")}> 加载 lodash</button>
    </div>
  );
}

成果如下:

2. 浏览器缓存

浏览器缓存,就是进入某个网站后,加载的动态资源被浏览器缓存,再次进入该网站后,将间接拉取缓存资源,放慢加载速度。

webpack 反对依据资源内容,创立 hash id,当资源内容发生变化时,将会创立新的 hash id。

配置 JS bundle hash,webpack.common.js 配置形式如下:

module.exports = {
  // 输入
  output: {
    // 仅在生产环境增加 hash
    filename: ctx.isEnvProduction
      ? "[name].[contenthash].bundle.js"
      : "[name].bundle.js",
  },
};

配置 CSS bundle hash,webpack.prod.js 配置形式如下:

module.exports = {
  plugins: [
    // 提取 CSS
    new MiniCssExtractPlugin({filename: "[hash].[name].css",
    }),
  ],
};

配置 optimization.moduleIds,让公共包 splitChunks 的 hash 不因为新的依赖而扭转,缩小非必要的 hash 变动,webpack.prod.js 配置形式如下:

module.exports = {
  optimization: {moduleIds: "deterministic",},
};

通过配置 contenthash/hash,浏览器缓存了未改变的文件,仅从新加载有改变的文件,大大放慢加载速度。

3. CDN

将所有的动态资源,上传至 CDN,通过 CDN 减速来晋升加载速度。

webpack.common.js 配置形式如下:

export.modules = {
output: {publicPath: ctx.isEnvProduction ? 'https://xxx.com' : '', // CDN 域名},
}

六、优化前后比照

在仓库代码仅 webpack 配置不同的状况下,查看优化前后比照。

  • [优化前 github 地址]()
  • [优化后 github 地址]()

1. 构建速度

类型 首次构建 未修改内容二次构建 批改内容二次构建
优化前 2.7s 2.7s 2.7s
优化后 2.7s 0.5s 0.3s

2. 打包体积

类型 体积大小
优化前 250 kb
优化后 231 kb

七、总结

从上章节 [优化前后比照] 可知,在小型我的项目中,增加过多的优化配置,作用不大,反而会因为额定的 loader、plugin 减少构建工夫。

在放慢构建工夫方面,作用最大的是配置 cache,可大大放慢二次构建速度。

在减小打包体积方面,作用最大的是压缩代码、拆散反复代码、Tree Shaking,可最大幅度减小打包体积。

在放慢加载速度方面,按需加载、浏览器缓存、CDN 成果都很显著。

本篇就介绍到这儿啦,有更好的 webpack 优化形式欢送评论区通知我哦~

本文源码:

  • webpack Demo2 优化前
  • webpack Demo2 优化后

心愿能对你有所帮忙,感激浏览~

别忘了点个赞激励一下我哦,笔芯 ❤️

参考资料

  • Tree-Shaking 性能优化实际 – 原理篇
  • Tree-Shaking 性能优化实际 – 实际篇
  • 三十分钟把握 Webpack 性能优化
  • 玩转 webpack,使你的打包速度晋升 90%
  • 带你深度解锁 Webpack 系列(优化篇)
  • Webpack 5 中的新个性
  • 辛辛苦苦学会的 webpack dll 配置,可能曾经过期了

欢送关注凹凸实验室博客:aotu.io

或者关注凹凸实验室公众号(AOTULabs),不定时推送文章。

退出移动版