灵感来源于:Tree Shaking性能优化实践 原理我这边就不多做介绍了,主要看上面引用的文章,写这篇文章的主要目的是
为了方便我们这些小白想根据上面的文章实践一把,但是遇到种种的报错问题&&解决方案&&一些基础知识的查漏补缺。
-
rollup
打包命令-
rollup --input main.js --output bundle.js --format cjs 或者 rollup -i main.js -o bundle.js -f cjs
-
--input xxx.js 入口文件
-
--output bundle.js 出口文件
-
--format cjs 使用cjs方式进行打包
-
format的几种模式
-
amd:异步模块,用于 requireJs
-
cjs:commonjs,适用于 node 和 browserify/webpack
-
es:将软件包保存为 ES 模块文件
-
iife:一个自动执行的功能,适合作为 script 标签
-
umd:通用模块定义
-
-
-
-
-
不识别rollup命令
- 全局安装rollup: npm install rollup -g
-
webpack
打包命令 -
npx webpack ./code.js -o bunble1.js --mode development/production
-
--mode :development/production指定打包模式为开发或者生产,区别在于生产上打包体积会进行压缩
-
或者使用/node_modules/.bin/webpack ./code.js -o bunble1.js --mode development/production
-
使用node_modules下面的webpack命令进行操作,.bin目录下面是一些脚本命令
-
-
Q:为什么要使用npx webpack不直接使用webpack进行打包
- npx webpack在没有全局安装webpack的时候,可以执行当前项目内的 webpack 的打包命令。例如:npx webpack -v 就可以获取当前项目内的 webpack 版本,全局安装可直接使用 webpack。
-
Q:打包文件里面包含harmony import类似的代码是什么意思?
-
import 会被打包成 harmony import
-
export 会被打包成 harmony export
-
-
babel
-
Q:babel-loader是干什么用的?
- 用来处理 Js 文件的一个 loader
-
@babel/preset-env
-
用来做语法转换 es6->es5
-
webpack中如果使用polyfill,在webpack.config.js中没有指定corejs版本,打包时会提示找不到相应模块的问题
-
-
Q: babel-core是干啥用的?
- 调用babel-core中的API来进行直接转换
-
Q:babel/preset-env是干啥用的?
-
preset
根据当前配置的浏览器环境自动加载相应的polyfill,而不是全部进行加载,从而减少打包体积 -
"
useBuiltIns
":三个参数 usage, entry,false-
usage
:根据配置的浏览器兼容引入所有的polyfill
,根据配置的浏览器兼容性以及用到的API来按需添加。只需安装babel-polyfill
即可,打包时会自动引入代码中使用到的垫片模块 -
entry
:根据配置的浏览器兼容,引入浏览器不兼容的polyfill
。需要在入口文件手动添加import '@babel/polyfill'
,会自动根据browserslist
替换成浏览器不兼容的所有polyfill
。这里需要指定core-js
的版本, 如果"corejs": 3
, 则import '@babel/polyfill'
需要改成 -
false
:不对polyfill
做操作,如果引入@babel/polyfill
,则无视配置的浏览器兼容,引入所有的polyfill
-
-
-
代码演示:
let foo = () => {
let x = 1;
if (false) {
console.log("never reached");
}
let a = 3;
return a;
};
let baz = () => {
var x = 1;
console.log(x);
post();
function unused() {
return 5;
}
return x;
let c = x + 3;
return c;
};
baz();
const promise = [new Promise(() => {}), new Promise(() => {})];
promise.map((promise) => {
console.log(promise);
});
测试对比两个打包工具对Dead Code的打包结果
打包对比结果:中间是源代码,左边是rollup打包结果,右边是webpack打包结果对比。
image-20211222214353073.png结论:
-
rollup
打包的结果会把Dead Code
一些无用的代码以及一些不可达的代码清除掉 -
webpack
打包的结果这些代码依然存在,且可读性查,打包体积也大
测试 对比两个打包工具对引用无用function的打包结果
code.js中使用util.js中的post方法。
rollup没有做其他的配置,webpack配置usedExports:true
image-20211222221741407.png结论:
-
rollup
在没有引用uglify的情况下可以直接过滤没有引用到的代码 -
webpack
如图右侧所示,webpack会对没有应用到的export进行标记,打包结果出乎意料,和前面大佬讲的打包结果不相符,,看了很多的资料,我觉得这篇文章讲的是比较能够解决我的一部分疑惑的,传送门
usedExports:true:编译时分析出哪些export用到了,哪些没有用到,然后进行标记。
总结:出现上面结果的主要是因为所谓的副作用的影响。在es5->es6的过程中使用了babel,由于babel的编译,一些没有副作用的代码也会被标记成有副作用的。webpack没有完整的流程分析,不能更好的判断代码是否产生了副作用。
至此结束,后面还有一篇百度前端团队大佬们分享的另一篇文章写的是对组件库,CSS,提取公共代码等的优化,戳我
END结束语:相对于webpack
的打包,对比了一下rollup
之后,对其提不起什么兴趣了,给我的直观感受
-
打包后的文件可读性不够好
-
相关插件支持的webpack版本不够清晰。例如:我生生用uglify试了两天,才知道ugilfy是和webpack2.x版本配合使用的,webpack4之后使用了以下几个属性已经实现了这些插件的部分功能。
- image-20211223215450607.png
- 打包后的文件,虽然对其进行了标记,但是清除无用代码不够彻底,打包体积相当于只能在无副作用和压缩代码之间进行优化。额,咱就是说那些方法之类的不能被清除也就算了,就是注释和无用的变量以及console咱就不能清除吗? (PS:也可能是知识盲区,不知道。)
网友评论