上一章节主要介绍了webpack的进阶篇中的一些高阶功能的使用和配置,这些还能在代码中进行一些配置、构建。现在来主要介绍一些webpack4特性原理分析,可能会比较枯燥,但是很实用。
1.Tree Shaking的使用和与案例分析
QQ截图20200822173328.png
注:当mode设置production的时候TreeShaking是默认开启的
(1)什么是DCE
我们了解tree shaking的之前,就要先了解一个概念DCE。
QQ截图20200822175116.png
意思就是说没有用到的代码,就会被“杀死”;什么是DCE代码呢?如上图左边写的要求:
代码不被执行,不可到达:不会执行的代码,如if(false) {}这条if就回永远不被执行;
代码执行的结果不会被用到:这句话的含义是指定义了一个函数,并且return一个结果,但是在调用这个函数时,这个结果永远不会用到;
代码只会影响死变量(只写不读):这句话的含义是当我们定义了一个变量,并且给这个变量设置了数据,但是永远没有用到这个变量。
只要符合上述的三个要求,就是DCE代码,在构建的过程中就会把这些代码删除掉,不会打包到bundle中。
(2)tree shaking原理
QQ截图20200822193309.png
(3)tree shaking 实战演练
① 自定义一个js文件
QQ截图20200822202315.png
② 在js文件里应用a方法
QQ截图20200822202726.png
③ 配置webpack.prod.js
- 未开启tree shaking的情况
设置mode为none,因为tree shaking在mode为production的情况下是默认开启的,npm run build构建项目,情况如下
QQ截图20200822203558.png
可以看到我们只是在js文件中只引用了a方法,但是没有进行任何的调用,构建的时候把这两个方法都打包了进来,显然会增加项目的体积 - 开启tree shaking的情况
设置mode为production
QQ截图20200822204035.png
可以发现这两个方法都没有引用进来 -
使用a方法,并且开启tree shaking
QQ截图20200822204321.png
构建项目
QQ截图20200822204510.png
可见a方法是调用到了,再来搜索一下b方法
QQ截图20200822204629.png
b方法并没有加载进来,从而达到了tree shaking的目的。
-
其他
QQ截图20200822204911.png
上述情况,虽然引用了a方法,看看构建的时候是否将a方法引用了进来
QQ截图20200822205041.png
可以看到a方法并没有打包进来。
2.Scope Hoisting使用和原理分析
我们先来看下webpack在没有使用该特性的情况下,webpack构件时的包效果如下
QQ截图20200823152157.png
可以发下产生了很多的闭包函数,这样会产生什么样的后果呢?如下
QQ截图20200823152443.png
这就有个问题,为什么webpack打包会产生这么多的闭包呢?是因为模块转换
QQ截图20200823152709.png
QQ截图20200823152925.png
(1)scope hoisting原理
QQ截图20200823153629.png
(2)scope hoisting使用
QQ截图20200823153809.png
(3)实战演练
① 未开启scope hoisting的情况
QQ截图20200823155932.png
构建项目
QQ截图20200823160501.png
① 开启scope hoisting的情况
QQ截图20200823160907.png
构建项目
QQ截图20200823161202.png
3.代码分割和动态import
前面学过基础库分离,讲述过SplitChunksPlugin插件,将页面进行分离,但这只是基础分离,现在来看一下高阶的代码分割和动态import
QQ截图20200823205013.png
(1)js懒加载的方式
QQ截图20200823211434.png
有两种懒加载的方式,如上图所述
- CommonJS: require.ensure;
- 动态import(推荐);
目前动态import能够兼容好webpack。这节主要讲述import
(2)如何使用动态import
QQ截图20200823211843.png
分割后的效果如下
QQ截图20200823211957.png
(2)动态import实战演练
第一步安装babel插件
npm install @babel/plugin-syntax-dynamic-import --save-dev
第二步
配置.babelrc文件
QQ截图20200823212916.png
第三步创建一个text.js文件,如下
QQ截图20200823213034.png
第四步在index.js下做如下配置
QQ截图20200823213644.png
最后一步:npm run build
4.webpack中使用eslint
使用eslint能够规范代码,便于团队合作,能够避免一些不必要的错误。
QQ截图20200829173634.png
QQ截图20200829173841.png
QQ截图20200829174106.png
QQ截图20200829174158.png
QQ截图20200829174330.png
QQ截图20200829174420.png
5.webpack 打包库和组件
面试题
QQ截图20200829175513.png
压缩版:适用于开发阶段;
非压缩版:适用于发布上线;
QQ截图20200829185906.png
QQ截图20200829190010.png
除了上面的引用方式还支持
QQ截图20200829190130.png
QQ截图20200829190208.png
(1)实战演练
① 创建项目
mkdir large-number
cd large-number
npm init
② 搭建webpack环境
npm install webpack webpack-cli -D
③ 重构项目目录
360截图18720120496570.png
src/index.js代码如下
export default function add(a, b) {
let i = a.length - 1;
let j = b.length - 1;
let carry = 0;
let ret = '';
while(i >= 0 || j >= 0) {
let x = 0;
let y = 0;
let sum;
if(i >= 0) {
x = a[i] - '0'; // 转成数字
i--;
}
if(j >= 0) {
y = b[j] - '0'; // 转成数字
j--;
}
sum = x + y + carry;
if(sum >= 10) {
carry = 1;
sum -= 10;
} else {
carry = 0;
}
ret = sum + ret;
}
if(carry) {
ret = carry + ret;
}
return ret;
}
// add('999', '1');
④ 编写webpack配置文件
module.exports = {
entry: {
'large-number': './src/index.js',
'large-number.min': './src/index.js'
},
output: {
filename: '[name].js',
library: 'largeNumber',
libraryTarget: 'umd',
libraryExport: 'default'
}
}
// libraryExport:最好设置成default,不然引用的时候,就要在方法后面加上default,显得过于冗余
⑤ 配置package.json文件
360截图1872012274119115.png
⑥ 打包构建
npm run build
360截图17981130393752.png
然后打开项目目录中的dist文件夹
360截图181412139211391.png
我们打开这两个文件,发现都被压缩了,不符合我们的需求(开发版是非压缩版,非开发版是压缩版),那么怎么办呢?如下
360截图17610611143017.png
如上图,将mode设置成none,关闭默认压缩,然后添加一个optimization,将minimize设置成true,然后通过配置minimizer设置正则匹配,只对mini.js进行压缩即可。
注:我们使用了TerserPlugin这个压缩插件,他可以针对ES6的语法进行压缩,如果使用有些插件,就不会针对es6进行压缩,可能会报错,所以推荐使用TerserPlugin,因此我们要先安装一下这个插件
npm install terser-webpack-plugin -D
安装好之后,在webpack.config.js头部导入进来
360截图16700618425050.png
最后重新打包,发现只有mini.js文件进行了压缩
360截图17891230399281.png
总结
这借主要介绍了一写webpack的原理,下节是进阶的完结篇来源