webpack
作为前端目前使用最广泛的打包工具,在面试中也是经常会被问到的。
比较常见的面试题包括:
webpack
性能优化?webpack
来回答)webpack
的性能优化比较多,我们可以对其进行分类:
exclude
、cache-loader
等)大多数情况下,我们会更加侧重于 第一种,因为这对线上的产品影响更大。
虽然在大多数情况下,webpack
都帮我们做好了该有的性能优化:
mode
为 production
或者 development
时,默认 webpack
的配置信息;本章,就让我们来学习一下 webpack
性能优化的更多细节
代码分离(Code Spliting) 是 webpack
一个非常重要的特性,它主要的目的是将代码剥离到不同的 bundle
中,之后我们可以按需加载,或者并行加载这些文件。
什么意思呢?举个例子:
webpack
将项目中的所有代码都打包到 一个 index.js
文件中(假如这个文件有 10M
)10M
的 index.js
文件全部下载解析执行后页面才会开始渲染。10M/s
,那么光是去下载这个 index.js
文件会花去 1s
。(这 1s
中内页面是白屏的)webpack
将项目中的所有代码都打包到是 多个 js
文件中(我们假设每个文件都为 1M
)1M
的 index.js
文件下载就只需要 0.1s
了,至于其它的文件,可以选择需要用到它们时候加载或者和 index.js
文件并行的下载通过以上的例子,相信大家应该能理解 代码分离 的好处了,那么在 webpack
如何能实现代码分离呢?
webpack
常用的代码分离方式有三种:
entry
配置手动分离代码;EntryDependencies
或者 SplitChunksPlugin
去重和分离代码:这是迄今为止最简单直观的分离代码的方式。不过,这种方式手动配置较多,并有一些隐患,我们将会解决这些问题。
先来看看如何从 main bundle
中分离 another module
(另一个模块)
创建一个小的 demo
:
npm
,然后在本地安装 webpack
、webpack-cli
、loadsh
shellmkdir webpack-demo cd webpack-demo npm init -y npm install webpack webpack-cli lodash --save-dev
src/index.js
:jsimport _ from "lodash";
console.log(_);
src/another-module.js
:jsimport _ from 'lodash';
console.log(_);
webpack.config.js
:const path = require("path"); module.exports = { mode: "development", entry: "./src/index.js", output: { path: path.resolve(__dirname, "dist"), filename: "main.js", }, };
package.json
中添加命令:json"scripts": {
"build": "webpack"
},
shellnpm run build
可以看到此时生成了一个 554KB
的 main.js
文件
接下来我们从 main bundle
中分离出 another module
(另一个模块)
webpack.config.js
diffconst path = require("path");
module.exports = {
mode: "development",
- entry: './src/index',
+ entry: {
+ index: './src/index',
+ another: './src/another-module.js'
+ },
output: {
path: path.resolve(__dirname, "dist"),
- filename: "main.js",
+ filename: "[name].main.js",
},
};
我们发现此时已经成功打包出 another.bundle.js
和 index.bundle.js
两个文件了,但是文件的大小似乎有些问题,怎么两个都是 554KB
?
正如前面提到的,这种方式存在一些隐患:
chunk
之间包含一些重复的模块,那些重复模块都会被引入到各个 bundle
中。以上两点中,第一点对我们的示例来说无疑是个问题,因为之前我们在 ./src/index.js
中也引入过 lodash
,这样就在两个 bundle
中造成重复引用。在下一小节我们将移除重复的模块。
在通过多入口分离代码的方式中,我们可以通过配置 dependOn
这个选项来解决重复模块的问题,它的原理就是从两个文件中抽出一个共享的模块,然后再让这两个模块依赖这个共享模块。
webpack.config.js
配置文件:diff const path = require('path');
module.exports = {
mode: 'development',
entry: {
- index: './src/index.js',
- another: './src/another-module.js',
+ index: {
+ import: './src/index.js',
+ dependOn: 'shared',
+ },
+ another: {
+ import: './src/another-module.js',
+ dependOn: 'shared',
+ },
+ shared: ['lodash'],
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
可以看到 index.mian.js
和 another.mian.js
中重复引用的部分被抽离成了 shared.main.js
文件,且 index.mian.js
和 another.mian.js
文件大小也变小了。
另外一种分包的模式是 splitChunks
,它底层是使用 SplitChunksPlugin
来实现的:
SplitChunksPlugin
插件可以将公共的依赖模块提取到已有的入口chunk
中,或者提取到一个新生成的chunk
。
因为该插件 webpack
已经默认安装和集成,所以我们并 不需要单独安装和直接使用该插件;只需要提供 SplitChunksPlugin
相关的配置信息即可
webpack
提供了 SplitChunksPlugin
默认的配置,我们也可以手动来修改它的配置:
chunks
仅仅针对于异步(async
)请求,我们可以设置为 initial
或者 all
,1.1.2
的基础上修改 webpack.cofig.js
:diff const path = require('path');
module.exports = {
mode: 'development',
entry: {
index: './src/index.js',
another: './src/another-module.js',
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
+ optimization: {
+ splitChunks: {
+ chunks: 'all',
+ },
+ },
};
使用 optimization.splitChunks
配置选项之后,现在应该可以看出,index.bundle.js
和 another.bundle.js
中已经移除了重复的依赖模块。需要注意的是,插件将 lodash
分离到单独的 chunk
,并且将其从 main
bundle
中移除,减轻了大小。
除了 webpack
默认继承的 SplitChunksPlugin
插件,社区中也有提供一些对于代码分离很有帮助的 plugin
和 loader
,比如:
mini-css-extract-plugin
: 用于将 CSS 从主应用程序中分离。关于 optimization.splitChunks
文档上有很详细的记载,我这里讲你叫几个常用的:
1. Chunks:
async
initial
,表示对通过的代码进行处理all
表示对同步和异步代码都进行处理2. minSize
:
minSize
,那么这个包就不会拆分;3. maxSize
:
4. cacheGroups:
lodash
在拆分之后,并不会立即打包,而是会等到有没有其他符合规则的包一起来打包;test
属性:匹配符合规则的包;name
属性:拆分包的 name
属性;filename
属性:拆分包的名称,可以自己使用 placeholder
属性;webpack.config.js
jsconst path = require("path");
module.exports = {
mode: "development",
entry: {
index: "./src/index.js",
another: "./src/another-module.js",
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
},
optimization: {
splitChunks: {
chunks: "all",
// 拆分包的最小体积
// 如果一个包拆分出来达不到 minSize,那么这个包就不会拆分(会被合并到其他包中)
minSize: 100,
// 将大于 maxSize 的包,拆分成不小于 minSize 的包
maxSize: 10000,
// 自己对需要拆包的内容进行分组
cacheGroups: {
自定义模块的name: {
test: /node_modules/,
filename: "[name]_vendors.js",
},
},
},
},
};
另外一个代码拆分的方式是动态导入时,webpack
提供了两种实现动态导入的方式:
ECMAScript
中的 import()
语法来完成,也是目前推荐的方式;webpack
遗留的 require.ensure
,目前已经不推荐使用;动态 import
使用最多的一个场景是懒加载(比如路由懒加载)
接着从 1.1.2
小节代码的基础上修改:
webpack.confg.js
:jsconst path = require("path");
module.exports = {
entry: "./src/index.js",
mode: "development",
entry: {
index: "./src/index.js",
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
},
};
删除 src/another-module.js
文件
修改 src/index.js
,不再使用 statically import
(静态导入) lodash
,而是通过 dynamic import
(动态导入) 来分离出一个 chunk
:
jsconst logLodash = function () {
import("lodash").then(({ default: _ }) => {
console.log(_);
});
};
logLodash();
之所以需要 default
,是因为 webpack 4
在导入 CommonJS
模块时,将不再解析为 module.exports
的值,而是为 CommonJS
模块创建一个 artificial namespace
对象。
由于 import()
会返回一个 promise
,因此它可以和 async
函数一起使用。下面是如何通过 async
函数简化代码:
jsconst logLodash = async function () {
const { default: _ } = await import("lodash");
console.log(_);
};
logLodash();
因为动态导入通常是一定会打包成独立的文件的,所以并不会再 cacheGroups
中进行配置;
它的命名我们通常会在 output
中,通过 chunkFilename
属性来命名:
webpack.config.js
diffconst path = require("path");
module.exports = {
entry: "./src/index.js",
mode: "development",
entry: {
index: "./src/index.js",
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
+ chunkFilename: "chunk_[name].js""
},
};
如果对打包后的 [name]
不满意,还可以通过 magic comments
(魔法注释)来修改:
1, 修改 src/index.js
:
jsconst logLodash = async function () {
const { default: _ } = await import(/*webpackChunkName: 'lodash'*/ "lodash");
console.log(_);
};
logLodash();
CDN
称之为 内容分发网络(Content Delivery Network 或 Content Distribution Network
,缩写:CDN
)
在开发中,我们使用 CDN
主要是两种方式:
CDN
服务器,用户所有资源都是通过 CDN
服务器加载的;CDN
服务器上;如果所有的静态资源都想要放到 CDN
服务器上,我们需要购买自己的 CDN
服务器;
Google
等都可以购买 CDN
服务器;publicPath
,在打包时添加上自己的 CDN
地址;1.3.1
的基础上安装 HtmlWebpackPlugin
插件:shellnpm install --save-dev html-webpack-plugin
webpack.config.js
文件:diffconst path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
mode: "development",
entry: {
index: "./src/index.js",
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
chunkFilename: "chunk_[name].js",
+ publicPath: "https://yejiwei.com/cdn/",
},
plugins: [new HtmlWebpackPlugin()],
};
可以发现我们打包后的 script
标签自动添加了 CDN
服务器地址的前缀。
通常一些比较出名的开源框架都会将打包后的源码放到一些比较出名的、免费的 CDN
服务器上:
unpkg
、JSDelivr
、cdnjs
;CDN
是 bootcdn
;在项目中,我们如何去引入这些 CDN
呢?
lodash
或者 dayjs
这些库进行打包;html
模块中,我们需要自己加入对应的 CDN
服务器地址;public/index.html
模版,手动加上对应 CDN
服务器地址html<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.core.min.js"></script>
</head>
<body></body>
</html>
1.3.1
的基础上修改 webpack.config.js
配置,来排除一些库的打包并配置 html
模版:diffconst path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
mode: "development",
entry: {
index: "./src/index.js",
},
output: {
filename: "[name].bundle.js",
path: path.resolve(__dirname, "dist"),
chunkFilename: "chunk_[name].js",
},
plugins: [
new HtmlWebpackPlugin({
+ template: "./public/index.html",
}),
],
+ externals: {
+ lodash: "_",
+ },
};
以下补充了解即可(一些细节)
如果将 webpack.config.js
的 mode
改为 production
也就是生产环境时,经常会看到一写 .txt
后缀的注释文件
这是因为在 production
默认情况下,webpack
再进行分包时,有对包中的注释进行单独提取。
这个包提取是由另一个插件(TerserPlugin
后面会细说) 默认配置的原因,如果想去掉可以做以下配置:
optimization.chunkIds
配置用于告知 webpack
模块的 id
采用什么算法生成。
有三个比较常见的值:
natural
:按照数字的顺序使用 id
;named
:development下
的默认值,一个可读的(你能看的懂得)名称的 id
;deterministic
:确定性的,在不同的编译中不变的短数字 id
webpack4
中是没有这个值的;natural
,那么在一些编译发生变化时,就需要重新进行打包就会有问题;最佳实践:
named
;deterministic
;配置 runtime
相关的代码是否抽取到一个单独的 chunk
中:
runtime
相关的代码指的是在运行环境中,对模块进行解析、加载、模块信息相关的代码;index
中通过 import
函数相关的代码加载,就是通过 runtime
代码完成的;
抽离出来后,有利于浏览器缓存的策略:main
),那么 runtime
和 component
、bar
的 chunk
是不需要重新加载的;component
、bar
的代码,那么 main
中的代码是不需要重新加载的;
设置的值:true/multiple
:针对每个入口打包一个 runtime
文件;single
:打包一个 runtime
文件;name
属性决定 runtimeChunk
的名称;对于每个
runtime chunk
,导入的模块会被分别初始化,因此如果你在同一个页面中引用多个入口起点,请注意此行为。你或许应该将其设置为single
,或者使用其他只有一个runtime
实例的配置。
webpack v4.6.0+
增加了对预获取和预加载的支持。
在声明 import
时,使用下面这些内置指令,来告知浏览器:
prefetch
(预获取):将来某些导航下可能需要的资源preload
(预加载):当前导航下可能需要资源
与
prefetch
指令相比,preload
指令有许多不同之处:
preload chunk
会在父 chunk
加载时,以并行方式开始加载。prefetch chunk
会在父 chunk
加载结束后开始加载。preload chunk
具有中等优先级,并立即下载。prefetch chunk
在浏览器闲置时下载。preload chunk
会在父 chunk
中立即请求,用于当下时刻。prefetch chunk
会用于未来的某个时刻。推荐使用 prefetch
,因为它是在未来闲置的时候下载,有些东西是不需要立即下载的,这样做不会因为请求不重要的资源而占用网络带宽。
shimming
是一个概念,是某一类功能的统称:
lodash
,但是默认没有对 lodash
进行导入(认为全局存在 lodash
),那么我们就可以通过 ProvidePlugin
来实现 shimming
的效果;注意:
webpack
并不推荐随意的使用shimming
。Webpack
背后的整个理念是使前端开发更加模块化;也就是说,需要编写具有封闭性的、不存在隐含依赖(比如全局变量)的彼此隔离的模块;
假如一个文件中我们使用了 axios
,但是没有对它进行引入,那么下面的代码是会报错的;
jsaxios.get('XXXXX').then(res => {
console.log(res)
})
get('XXXXX').then(res => {
console.log(res)
})
我们可以通过使用 ProvidePlugin
来实现 shimming
的效果:
webpack.config.js
:jsnew ProvidePlugin({
axios: 'axios',
get: ['axios','get']
})
ProvidePlugin
能够帮助我们在每个模块中,通过一个变量来获取一个 package
;webpack
看到这个模块,它将在最终的 bundle
中引入这个模块;ProvidePlugin
是 webpack
默认的一个插件,所以不需要专门导入;这段代码的本质是告诉webpack: 如果你遇到了至少一处用到 axios
变量的模块实例,那请你将 axios package
引入进来,并将其提供给需要用到它的模块。
在了解 TerserPlugin
插件前,我们先来认识一下什么是 Terser
。
什么是 Terser
呢?
Terser
是一个 JavaScript
的解释(Parser
)、Mangler
(绞肉机)/ Compressor
(压缩机)的工具集;uglify-js
来压缩、丑化我们的 JavaScript
代码,但是目前已经不再维护,并且不支持 ES6+
的语法;Terser
是从 uglify-es fork
过来的,并且保留它原来的大部分 API
以及适配 uglify-es
和 uglify-js@3
等;也就是说,Terser
可以帮助我们压缩、丑化我们的代码,让我们的 bundle
变得更小。
我们现在就来用一下 Terser
,因为 Terser
是一个独立的工具,所以它可以单独安装:
# 全局安装 npm install terser -g # 局部安装 npm install terser -D
可以在命令行中使用 Terser:
terser [input files] [options] # 举例说明 terser js/file1.js -o foo.min.js -c -m
我们这里来讲解几个 Compress option
和 Mangle(乱砍) option
:
Compress option
:
Mangle option
:
真实开发中,我们不需要手动的通过 terser
来处理我们的代码,我们可以直接通过 webpack
来处理:
webpack
中有一个 minimizer
属性,在 production
模式下,默认就是使用TerserPlugin
来处理我们的代码的;TerserPlugin
的实例,并且覆盖相关的配置;修改 webpack.config.js
配置:
jsconst TerserPlugin = require("terser-webpack-plugin");
...
optimization: {
// 打开minimize,让其对我们的代码进行压缩(默认production模式下已经打
minimize: true,
minimizer: [
new TerserPlugin({
// extractComments:默认值为true,表示会将注释抽取到一个单独的文件中;
// 在开发中,我们不希望保留这个注释时,可以设置为false;
extractComments: false,
// parallel:使用多进程并发运行提高构建的速度,默认值是true
// 并发运行的默认数量: os.cpus().length - 1;
// 我们也可以设置自己的个数,但是使用默认值即可;
// parallel: true,
// terserOptions:设置我们的terser相关的配置
terserOptions: {
// 设置压缩相关的选项;
compress: {
unused: false,
},
// 设置丑化相关的选项,可以直接设置为true;
mangle: true,
// 顶层变量是否进行转换;
toplevel: true,
// 保留类的名称;
keep_classnames: true,
// 保留函数的名称;
keep_fnames: true,
},
}),
],
},
上面我们讲了 JS
的代码压缩,而在我们的前端项目中另一类占大头的代码就是 CSS
:
CSS
压缩通常是去除无用的空格等,因为很难去修改选择器、属性的名称、值等;CSS
的压缩我们可以使用另外一个插件:css-minimizer-webpack-plugin
;css-minimizer-webpack-plugin
是使用 cssnano
工具来优化、压缩 CSS
(也可以单独使用);css-minimizer-webpack-plugin
:shellnpm install css-minimizer-webpack-plugin -D
optimization.minimizer
中配置:什么是 Tree Shaking
?
Tree Shaking
是一个术语,在计算机中表示消除死代码(dead_code
);LISP
,用于消除未调用的代码(纯函数无副作用,可以放心的消除,这也是为什么要求我们在进行函数式编程时,尽量使用纯函数的原因之一);Tree Shaking
也被应用于其他的语言,比如 JavaScript
、Dart
;JavaScript
的 Tree Shaking
:
JavaScript
进行 Tree Shaking
是源自打包工具 rollup
;Tree Shaking
依赖于 ES Module
的静态语法分析(不执行任何的代码,可以明确知道模块的依赖关系);webpack2
正式内置支持了 ES2015
模块,和检测未使用模块的能力;webpack4
正式扩展了这个能力,并且通过 package.json
的 sideEffects
属性作为标记,告知 webpack
在编译时,哪里文件可以安全的删除掉;webpack5
中,也提供了对部分 CommonJS
的 tree shaking
的支持;
✓ https://github.com/webpack/changelog-v5#commonjs-tree-shakingwebpack
实现 Tree Shaking
采用了两种不同的方案:
usedExports
:通过标记某些函数是否被使用,之后通过 Terser
来进行优化的;sideEffects
:跳过整个模块/文件,直接查看该文件是否有副作用;usedExports
按 sideEffects
这两个东西的优化是不同的事情。
引用官方文档的话: The sideEffects and usedExports(more konwn as tree shaking)optimizations are two different things
下面我们分别来演示一下这两个属性的使用
webpack-demo
。shellmkdir webpack-demo cd webpack-demo npm init -y npm install webpack webpack-cli lodash --save-dev
src/math.js
文件:jsexport const add = (num1, num2) => num1 + num2;
export const sub = (num1, num2) => num1 - num2;
在这个问价中仅是导出了两个函数方法
src/index.js
文件:、jsimport { add, sub } from "./math";
console.log(add(1, 2));
在 index.js
中 导入了刚刚创建的两个函数,但是只使用了 add
webpack.config.js
:jsconst path = require("path");
module.exports = {
mode: "development",
devtool: false,
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "main.js",
},
optimization: {
usedExports: true,
},
};
为了可以看到 usedExports
带来的效果,我们需要设置为 development
模式。因为在 production
模式下,webpack
默认的一些优化会带来很大的影响。
usedExports
为 true
和 false
对比打包后的代码:仔细观察上面两张图可以发现当设置 usedExports: true
时,sub
函数没有导出了,另外会多出一段注释:unused harmony export mul
;这段注释的意义是会告知 Terser
在优化时,可以删除掉这段代码。
这个时候,我们将 minimize
设置 true
:
usedExports
设置为 false
时,sub
函数没有被移除掉;usedExports
设置为 true
时,sub
函数有被移除掉;所以,usedExports
实现 Tree Shaking
是结合 Terser
来完成的。
在一个纯粹的 ESM
模块世界中,很容易识别出哪些文件有副作用。然而,我们的项目无法达到这种纯度,所以,此时有必要提示 webpack compiler
哪些代码是“纯粹部分”。
通过 package.json
的 "sideEffects"
属性,来实现这种方式。
json{
"name": "your-project",
"sideEffects": false
}
如果所有代码都不包含副作用,我们就可以简单地将该属性标记为 false
,来告知 webpack
它可以安全地删除未用到的 export
。
"side effect(副作用)"
的定义是,在导入时会执行特殊行为的代码,而不是仅仅暴露一个export
或多个export
。举例说明,例如polyfill
,它影响全局作用域,并且通常不提供export
。
如果你的代码确实有一些副作用,可以改为提供一个数组:
json{
"name": "your-project",
"sideEffects": ["./src/some-side-effectful-file.js"]
}
注意,所有导入文件都会受到
tree shaking
的影响。这意味着,如果在项目中使用类似css-loader
并import
一个CSS
文件,则需要将其添加到side effect
列表中,以免在生产模式中无意中将它删除:
json{
"name": "your-project",
"sideEffects": ["./src/some-side-effectful-file.js", "*.css"]
}
上面将的都是关于 JavaScript
的 Tree Shaking
,对于 CSS
同样有对应的 Tree Shaking
操作。
在早期的时候,我们会使用 PurifyCss
插件来完成 CSS
的 tree shaking
,但是目前该库已经不再维护了(最新更新也是在 4
年前了);
目前我们可以使用另外一个库来完成 CSS
的 Tree Shaking
:PurgeCSS
,也是一个帮助我们删除未使用的 CSS
的工具;
PurgeCss
的 webpack
插件:shellnpm install purgecss-webpack-plugin -D
webpack.config.js
中配置 PurgeCss
new PurgeCSSPlugin({ paths: glob.sync(`${path.resolve(__dirname, '../src')}/**/*`, { nodir: true }), only: ['bundle', 'vendor'] })
paths
:表示要检测哪些目录下的内容需要被分析,这里我们可以使用 glob
;Purgecss
会将我们的 html
标签的样式移除掉,如果我们希望保留,可以添加一个 safelist
的属性;purgecss
也可以对 less
、sass
文件进行处理(它是对打包后的 css
进行 tree shaking
操作);
Scope Hoisting
是从 webpack3
开始增加的一个新功能,它的功能是对作用域进行提升,并且让 webpack
打包后的代码更小、运行更快;
默认情况下 webpack
打包会有很多的函数作用域,包括一些(比如最外层的)IIFE
:
Scope Hoisting
可以将函数合并到一个模块中来运行;(作用域提升,在主模块里直接运行它,而不是去加载一些单独的模块)使用 Scope Hoisting
非常的简单,webpack
已经内置了对应的模块:
production
模式下,默认这个模块就会启用;development
模式下,我们需要自己来打开该模块;jsnew webpack.optimize.ModuleConcatenationPlugin()
经过前几小节的代码压缩优化(Tree Shaking
的优化、Terser
的优化、CSS
压缩的优化),基本上已经没有什么可以通过删除一些代码再压缩文件的方法了(变量、空格、换行符、注释、没用的代码都已经处理了)
但是我们还有一种通过压缩算法从对文件压缩的方式来继续减小包的体积(就像在 winodows 将文件夹压缩成 zip
一样,只不过我们这里是对单个js文件进行压缩)
目前的压缩格式非常的多:
compress
– UNIX
的 “compress”
程序的方法(历史性原因,不推荐大多数应用使用,应该使用 gzip
或 deflate
);deflate
– 基于 deflate
算法(定义于RFC 1951)的压缩,使用 zlib
数据格式封装;gzip
– GNU zip
格式(定义于RFC 1952),是目前使用比较广泛的压缩算法;br
– 一种新的开源压缩算法,专为 HTTP
内容的编码而设计;在 webpack
中的配置:
CompressionPlugin
shellnpm install compression-webpack-plugin -D
webpack.config.js
:jsnew CompressionPlugin({
test: /].(css|js)$/, // 匹配哪些文件需要压缩
// threshold: 500, // 设置文件从多大开始压缩
minRatio: 0.7, // 至少的压缩比例
algorithm: "gzip, // 才用的压缩算法
// include
// exclude
})
我们之前使用了 HtmlWebpackPlugin
插件来生成 HTML
的模板,事实上它还有一些其他的配置:
本文作者:叶继伟
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!