一、AST (抽象语法树,Abstract Syntax Tree)
手把手带你走进Babel的编译世界 – 掘金 (juejin.cn)
1、概念
我们所写的代码转换为机器能识别的一种树形结构,本身是由一堆节点(Node)组成,每个节点都表示源代码中的一种结构。
2、节点类型
不同结构用类型(Type)来区分,常见的节点类型有Identifier(标识符),Expression(表达式),VariableDeclaration(变量定义),FunctionDeclaration(函数定义):
3、公共属性
4、查询AST工具
(1)AST explorer
(2)AST可视化
5、应用
- Babel 插件(ES6 转化 ES5)
- 构建时压缩代码
- css 预处理器编译
- webpack 插件
二、Babel
1、作用
(1)将es6转换成es5
利用插件babel-traverse,插件可以遍历 ast 节点并进行增删改操作,进而实现代码转换功能
(2)将jsx转换成js
2、工作流程
babel工作原理浅析 – 掘金 (juejin.cn)
Babel 的工作流程 – 掘金 (juejin.cn)
(1)parse解析:我的代码解析成AST。用到的babel包:@babel/parser
包含两步:
- 词法分析,也就是将原始代码拆分成一个个的 token(用于描述最小独立语法单元的对象)
- 语法分析,递归遍历 tokens 数组,构建 ast。自动分号插入,对于位置错误的tokens报告错误
- 语义分析,检查这个AST是否遵循ECMAScripts 所有静态的规则
(2)transform转换:AST转换成新的AST,算法是深度优先遍历。用到的babel包:@babel/traverse
(3)generate生成:遍历上一步的AST,生成目标代码。在必要的地方插入括号或缩进、注释等。用到的babel包:@babel/generator
图示过程:
3、babel核心包
@babel/cli:提供在命令行中调用 @babel/core 的能力
@babel/runtime & @babel/plugin-transform-runtime:包含各种帮助函数,是代码运行的时候需要用到的
安装:
npm i @babel/parser @babel/traverse @babel/types @babel/generator @babel/template -D
4、Babel 插件
(1)作用
插件相当于是指令,来告知 Babel 需要做什么事情。如果没有插件,Babel 将原封不动的输出代码。
(2)分类:语法插件和转换插件
- 语法插件作用于 @babel/parser,负责将代码解析为抽象语法树(AST)(官方的语法插件以 babel-plugin-syntax 开头)
- 转换插件作用于 @babel/core,负责转换 AST 的形态
5、Babel Types模块
(1)作用
用于 AST 节点的 Lodash 式工具库,它包含了构造、验证以及变换 AST 节点的方法
(2)节点类型判断
查询API:@babel/types · Babel 中文文档 (docschina.org)
import * as types from "@babel/types";
// 是否为标识符类型节点
if (types.isIdentifier(node)) {
// ...
}
// 是否为数字字面量节点
if (types.isNumberLiteral(node)) {
// ...
}
// 是否为表达式语句节点
if (types.isExpressionStatement(node)) {
// ...
}
(3)创建数据类型节点
Babel Types 生成的 AST 节点需使用@babel/generator
转换后得到相应代码
import * as types from "@babel/types";
import generator from "@babel/generator";
const log = (node: types.Node) => {
console.log(generator(node).code);
};
log(types.stringLiteral("Hello World")); // output: Hello World
(4)创建jsx ast节点
三、代码格式化
前端代码格式化与校验 – 掘金 (juejin.cn)
1、Eslint
(1)作用
JavaScript是一门动态的弱类型语言,缺少编译过程,有些本可以在编译过程中就发现的错误,只能等到运行时才发现。ESLint 相当于为语言增加了编译过程,在代码运行前进行静态分析,能够及时找到出错的地方
(2)运行原理
使用 espree 解析器将 JavaScript 代码解析成一个 AST(抽象语法树),然后通过深度遍历 AST 的所有节点,会触发监听了对应节点的自定义规则的回调函数
(3)配置
配置文件优先级
.eslintrc.js
.eslintrc.yaml
.eslintrc.yml
.eslintrc.json
.eslintrc
-
package.json
中的eslintConfig
字段
基本配置
// .eslintrc.js
module.exports = {
// 环境变量,指定脚本的运行环境
env: {},
// 全局变量,key-value形式,value为ritable表示允许重写变量,为readonly表示不允许重写变量
globals: {},
// 解析器,默认使用 Espree 作为其解析器,也可以用其他的
parser: 'espree',
// 解析器配置
parserOptions: {},
// 插件,ESLint 中的规则只会对 JS 进行校验,如果要对Vue、React等进行校验,需要用到相关插件
plugins: [],
// 可以使用 plugins 关键字来存放插件的列表,插件名称可以省略 eslint-plugin- 前缀
// 写成{
// plugins: ['vue'];
// }
// 扩展,继承预先定义好的校验规则,扩展名称可以省略 eslint-config- 前缀
extends: [],
// 规则,改变一个规则设置
rules: {},
// 覆盖,覆盖指定文件校验规则
overrides: {}
};
(4)项目整合
2、prettier
前端代码格式化与校验 – 掘金 (juejin.cn)
3、Stylelint
前端代码格式化与校验 – 掘金 (juejin.cn)
四、postcss
什么是 PostCSS?如何使用插件自动化 CSS 任务 – 掘金 (juejin.cn)
1、作用
一种 JavaScript 工具,可将你的 CSS 代码转换为抽象语法树 (AST),然后提供 API(应用程序编程接口)用于使用 JavaScript 插件对其进行分析和修改
2、本质
不是后处理器也不是预处理器,它只是一个将特殊的PostCSS插件语法转换为 Vanilla CSS 的转译器。你可以将其视为 CSS 的Babel工具
3、特点
完全可定制,只能使用应用程序所需的插件和功能
与其他预处理器相比,它还产生更快的构建时间
五、微前端
关于我理解的微前端 – 掘金 (juejin.cn)
1、是什么
概念来源于微服务,摒弃了大型单体应用的方式,将前端整体分解为小而简单的块儿,这些块儿可以独立的开发、独立测试、独立部署、同时仍然可以聚合为一个产品来使用
2、特点
- 与技术栈无关
- 独立开发部署
- 渐进式增量升级
3、使用场景
- 不同框架的功能进行合并
- 同个框架的子项目进行合并
4、解决方案
qiankun
: 可能是你见过最完善的微前端解决方案
MicroApp
: 一款轻量、高效、功能强大的微前端框架
六、打包工具vite
Vite 配置篇:日常开发掌握这些配置就够了! – 掘金 (juejin.cn)
七、模块化
前端模块化详解(完整版) – 掘金 (juejin.cn)
浅谈前端模块化 – 掘金 (juejin.cn)
1、是什么
- 将一个复杂的程序依据一定的规则(规范)封装成几个块(文件), 并进行组合在一起
- 块的内部数据与实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信
2、优点
- 避免命名冲突(减少命名空间污染)
- 更好的分离, 按需加载
- 更高复用性
- 高可维护性
3、模块化规范
(1)CommonJS
- 每个文件就是一个模块,有自己的作用域,代码运行时在模块作用域,不会污染全局作用域。
- 在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。
- 在服务器端,模块的加载是运行时同步加载的;在浏览器端,模块需要提前编译打包处理。
- 模块加载是按照代码书写顺序加载的
- 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
- 暴露模块:
module.exports = value
或exports.xxx = value
- 引入模块:
require(xxx)
,如果是第三方模块,xxx为模块名;如果是自定义模块,xxx为模块文件路径
(2)ES6Module
ES Modules 和 CommonJS的一些区别
- 使用语法层面,CommonJs是通过module.exports,exports导出,require导入;ESModule则是export导出,import导入
- CommonJs是运行时加载模块,ESModule是在静态编译期间就确定模块的依赖
- ESModule在编译期间会将所有import提升到顶部,CommonJs不会提升require
- CommonJs导出的是一个值拷贝,会对加载结果进行缓存,一旦内部再修改这个值,则不会同步到外部。ESModule是导出的一个引用,内部修改可以同步到外部
- CommonJs中顶层的this指向这个模块本身,而ESModule中顶层this指向undefined
- CommonJS加载的是整个模块,将所有的接口全部加载进来,ESModule可以单独加载其中的某个接口
- CommonJS无法再浏览器端使用,ESModule可以
- CommonJS无法并行加载多个模块,只能按顺序加载,ESModule可以并行加载多个模块
(3)amd
(4)cmd
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net