前端工程化

一、打包资源处理

AST及其应用

源代码经过词法分析转化为Token流,维护一个Token的数组,可以利用Token流做一些代码检查、语法高亮、模版语法相关的操作,然后经过语法分析转化为有结构化ATS抽象语法树,方便操作。

参考一个最简编译器的实现

webpack的runtime做了什么事情?

  1. __webpack_modules__一个维护所有模块的数组,通过入口模块解析AST,根据AST深度优先搜索所有模块构建这个模块数组,每个模块通过一个函数 (module, module.exports, webpack_require) 进行包裹构成。

  2. __webpack_require__(moduleId)一个加载模块,通过模块id执行__webpack_modules__对应的模块包裹函数,之后会对已加载模块进行缓存。

  3. __webpack_require__(0)运行第一个模块,即运行入口模块。

当涉及到多个chunk的打包方式中,比如import、code spliting中,webpack会通过jsonp方式创建script标签动态加载模块

精简代码:

1
2
3
4
5
6
7
8
const __webpack_modules__ = [() => {}];
const __webpack_require__ = (id) => {
const module = { exports: {} };
const m = __webpack_modules__[id](module, __webpack_require__);
return module.exports;
};

__webpack_require__(0);

补充:rollup不存在modules模块数组,而是将所有模块铺平展开,如果两个模块变量重名冲突的话,会直接重新命名如:name->name$1

webpack/rollup如何加载style样式资源

在webpack中,需要借助loader将非JS资源转化为可识别为javascript的module。

处理css需要两个loader:css-loader、style-loader

  1. css-loader的原理就是postcss,借助postcss-value-parse解析css为ast,处理css中的url()和@import语法

  2. style-loader原理是使用dom api手动创建style标签,将css内容注入到style中

因为dom api加载css资源的性能原因,生产环境一般通过mini-css-extract-plugin将css单独抽离出来。

二、打包体积优化

如何提升webpack构建资源的速度?

  1. 更换AST转换工具SWC:webpack中耗时最久的就是负责AST转换的loader,javascript性能低下,可以将babel替换为由高性能语言rust编写的swc。

  2. 持久化缓存cache,webpack5内置了插件,通过cache字段开启.

  3. 开启多进程thread-loader,提升编译速度。

js代码压缩的原理是什么?

  1. 去除多余字符:空格,换行及注释,但是要注意多行代码压缩到一行时的行尾分号问题

  2. 压缩变量名:变量名、函数名、属性名

  3. 解析程序逻辑:合并声明、布尔值简化

  4. 编译预计算,编译期进行计算,减少运行时的计算量

Tree Shaking的原理是什么?

tree shaking基于ES Module进行静态分析,通过AST将用不到的函数进行移除,从而减少打包体积

core-js是做什么用的?

  core-js是关于ES标准的polyfill,其中实现了浏览器不支持的最新API,core-js已集成到了babel/swc之中,可以通过@babel/preset-env或者@babel/polyfill进行配置,通过配置,babel编译代码后将自动包含所需的polyfill。

评论