chst365's blog chst365's blog
首页
  • Git
  • 网络
  • 操作系统
  • 浏览器
  • webpack
  • JavaScript
  • TypeScript
  • 性能
  • 工程化
  • React
  • 编程题
  • React技术揭秘
  • 算法
  • Node
  • 编码解码
  • NodeJS系列
  • Linux系列
  • JavaScript系列
  • HTTP系列
  • GIT系列
  • ES6系列
  • 设计模式系列
  • CSS系列
  • 小程序系列
  • 数据结构与算法系列
  • React系列
  • Vue3系列
  • Vue系列
  • TypeScript系列
  • Webpack系列
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

chst365

DIV工程师
首页
  • Git
  • 网络
  • 操作系统
  • 浏览器
  • webpack
  • JavaScript
  • TypeScript
  • 性能
  • 工程化
  • React
  • 编程题
  • React技术揭秘
  • 算法
  • Node
  • 编码解码
  • NodeJS系列
  • Linux系列
  • JavaScript系列
  • HTTP系列
  • GIT系列
  • ES6系列
  • 设计模式系列
  • CSS系列
  • 小程序系列
  • 数据结构与算法系列
  • React系列
  • Vue3系列
  • Vue系列
  • TypeScript系列
  • Webpack系列
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 浏览器

  • webpack

  • TypeScript

  • 性能

  • 工程化

    • webpack-loader机制
    • webpack-插件机制
    • webpack工作流程
    • Babel原理
    • uglify-js代码是如何被压缩的
      • AST (抽象语法树)
      • 代码压缩原理
      • 代码压缩规则
    • Tree-Shaking性能优化
    • 前端模块化机制
    • 前端微服务
    • Vite为什么快?快在哪?
    • npm script了解多少?
  • React

  • JavaScript

  • 编程题

  • React技术揭秘

  • 算法

  • 前端
  • 工程化
chst365
2021-04-16
目录

uglify-js代码是如何被压缩的

# AST (抽象语法树)

抽象语法树:AST(Abstract Syntax Tree),是源代码的抽象语法结构的树状表现形式,这里特指编程语言的源代码。树上的每个节点都表示源代码中的一种结构。之所以说语法是「抽象」的,是因为这里的语法并不会表示出真实语法中出现的每个细节。

举个例子 可以看出 AST 是源代码根据其语法结构,省略一些细节,抽象成树形表达。 tips: 具体的 AST 树大家可以在 astexplorer (opens new window) 上在线获得

# 代码压缩原理

  • 将 code 转换成 AST
  • 将 AST 进行优化,生成一个更小的 AST
  • 将新生成的 AST 再转化成 code

babel,eslint,v8 的逻辑均与此类似,下图引用了 babel 的转化示意图

uglify 是怎么一步一步被压缩的?

// uglify-js的版本需要为2.x, 3.0之后uglifyjs不再暴露Compressor api
// 2.x的uglify不能自动解析es6,所以这里先切换成es5
// npm install uglify-js@2.x
var UglifyJS = require("uglify-js");
// 原始代码
var code = `var a;
var x = { b: 123 };
a = 123,
delete x`;
// 通过 UglifyJS 把代码解析为 AST
var ast = UglifyJS.parse(code);
ast.figure_out_scope();
// 转化为一颗更小的 AST 树
compressor = UglifyJS.Compressor();
ast = ast.transform(compressor);
// 再把 AST 转化为代码
code = ast.print_to_string();
// var a,x={b:123};a=123,delete x;
console.log("code", code);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

我们了解了 uglifyjs 的代码压缩原理,但是有个问题:为什么某些语句间的分号会被转换为逗号,某些不会转换? 这就涉及到 uglifyjs 的压缩规则

# 代码压缩规则

由于 uglify 的代码压缩规则很多,这里只分析与本文相关的部分 这其中需要注意的是只有“表达式语句”才能被合并,那么什么是表达式语句呢?

# 表达式 VS 语句 VS 表达式语句

// 表达式
    a; //返回a的值
b + 3; // 返回b+3的结果

// 语句
if(x > 0) {
...
}
for(var i = 0;i < arr.length; i ++) {
...
}
const a = 123;

// 表达式语句
A();
function() {}();
delete x.b;
b = b + 3;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

综上所述,因为 a = 123 和 delete x 都是表达式语句,所以分号被转换为逗号。而 var x = {b:123}则因为是声明语句,所以和 a=123 不会合并,分号不会被转换。但 var x = {b:123}和第一行 var a 又触发了另外一条规则,所以第一行和第二行会被合并为 var a,x={b:123}

#前端#工程化
上次更新: 2021/12/14, 23:27:23
Babel原理
Tree-Shaking性能优化

← Babel原理 Tree-Shaking性能优化→

最近更新
01
面试官
03-27
02
this&指针&作用域&闭包
03-27
03
前端
03-27
更多文章>
Theme by Vdoing | Copyright © 2019-2025 chst365 | 豫ICP备17031889号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式