浅谈JavaScript代码压缩
日期:2021-06-06 20:35:00
更新:2021-06-06 20:35:00
标签:前端, Javascript
分类:Javascript
前几天在写一个小工具的时候,需要用到代码压缩工具uglify-js,突然就在想:这种代码压缩工具是怎么样去实现的呢?于是去了解了一下它的原理~

前言
前几天在写一个小工具的时候,需要用到代码压缩工具uglify-js,突然就在想:这种代码压缩工具是怎么样去实现的呢?于是去了解了一下它的原理~
抽象语法树(AST)
要了解代码压缩原理,就必须要先了解 AST 树,它是进行 JS 代码压缩的基础。
抽象语法树概念
AST: Abstract Syntax Tree,译为抽象语法树,它的作用是将源码的语法结构变为抽象表示,并且以树的形式表示,树的每个节点对应源码中的语法[1]。它是这样实现的:将源代码以字符串的形式读取,按照编程语言的语法将其解析为语法树,比如有这样一句代码
var workTime = 996;
这里声明了一个变量workTime,并且给他赋值996。那么在 AST 抽象语法树中可以这样表示

上面图中将变量名,赋值运算符和值分成三部分表示,简单地表达了源码抽象成树来表达。我们继续在深入解析一下这个抽象树在 JS 中是如何描述的。
{
"type": "VariableDeclaration",
"declarations": [
{
"type": "VariableDeclarator",
"id": {
"type": "Identifier",
"name": "workTime"
},
"init": {
"type": "Literal",
"value": 996,
"raw": "996"
}
}
],
"kind": "var",
}
源码的语法就被表示成一个JSON对象,同理,按照一定规则也可以将语法树还原为源码。
AST 树的用处
那么,将源代码变为 AST 抽象语法树有什么用处呢?
它的用处首先就如我们的主题一样,它可以进行代码压缩,除此之外,它还可以用作编译器,程序分析等等。
代码压缩
压缩过程
上面我们已经把程序源码转换成 AST 树了,那为什么转换成 AST 树就可以进行代码压缩呢?引用一张 babel 的转化的流程图

图中可以看到代码压缩的步骤大概有三步:
- 将源代码转换为 AST
- 将 AST 通过
一定的规则进行优化,转换成更简洁的 AST
- 通过生成器将优化后的 AST 转换为代码
了解了压缩代码的基本原理后,接下来就用uglify-js尝试一下代码压缩
const uglify = require("uglify-js");
const sourceCode = `
function testFun() {
var a = 1;
var b = 2;
return a + b;
}
`;
const resultCode = uglify.minify(sourceCode);
console.log(resultCode.code);
可以看到,源代码中声明了两个变量并赋值,函数的作用是将这两个函数相加后返回。
而压缩后的代码,因为变量已经有了明确的值,直接将两个变量声明的代码去掉了,函数直接返回了两个明确的值相加的结果。
压缩规则
了解了代码压缩原理后,可以看到压缩过程的第二步:将AST通过一定的规则进行优化,转换成更简洁的AST。
代码压缩是通过 AST 树优化进行的,而 AST 优化是按一定规则,也就是说,压缩规则是一个影响压缩质量的主要因素。例如 uglify-js`的部分压缩选项如下,:
要了解更多压缩规则,请点击这里
小结
本文主要讲的是了 JavaScript 代码压缩是如何进行的
介绍了 AST 树的概念和它是如何抽象的
介绍了 JavaScript 代码压缩的原理和 UglifyJs 的压缩规则。
希望对大家有所帮助
参考
- Abstract syntax tree
- 手把手带你入门 AST 抽象语法树
- 抽象语法树在 JavaScript 中的应用