-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
233 lines (199 loc) · 6.35 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
// https://juejin.im/post/5d7efbbb6fb9a06b2650c74a
// https://blog.hhking.cn/2019/04/02/babel-v7-update/
// https://github.com/sorrycc/blog/issues/80
/**
* 插件比预设先执行
* 插件执行顺序是插件数组从前向后执行
* 预设执行顺序是预设数组从后向前执行
*/
/**
* 需要指定执行环境 Browserslist, Browserslist 的配置有几种方式,并按下面的优先级使用:
* 1. @babel/preset-env 里的 targets
* 2. package.json 里的 browserslist 字段
* 3. .browserslistrc 配置文件
*
* browserslist 是用来给不同的前端工具(Autoprefixer, babel-preset-env)共享 target browsers 和 Node.js versions 配置的.
* 一般推荐将配置写在 package.json 里的 browserslist 字段。
*
* core-js 提供了两种补丁方式。
* 1. core-js/library,通过 helper 方法的方式提供
* 2. core-js/module,通过覆盖全局变量的方式提供
*/
/**
* @babel/runtime, @babel/plugin-transform-runtime 把 helpers 和 polyfill 功能拆分了。默认只提供 helpers。
* @babel/runtime里面是 helper 函数 (但是没有抽离公共 helper 函数,需要使用 @babel/plugin-transform-runtime 抽离)
*
* useBuiltIns: 'usage' -> (usage 会根据配置的浏览器兼容,以及你代码中用到的 API 来进行 polyfill,实现了按需添加)
* 在每个文件引入一次这个 api 需要的polyfill(多个文件之间的重复的polyfill需要其他插件抽离 -> 辅助函数是直接内嵌) -> (重复的被抽离出去了,通过require 引入)
* 需要 @babel/plugin-transform-runtime 解决
*
*
* useBuiltIns: false
* 此时不对 polyfill 做操作。如果引入 @babel/polyfill,则无视配置的浏览器兼容,引入所有的 polyfill。
*
*
* useBuiltIns: 'entry' (含义是找到入口文件里引入的 @babel/polyfill,并替换为 targets 浏览器/环境需要的补丁列表)
* 配置的浏览器兼容,引入浏览器不兼容的 polyfill。需要在入口文件手动添加 import '@babel/polyfill',会自动根据 browserslist 替换成浏览器不兼容的所有 polyfill。
*
* 需要指定 core-js 的版本, 如果 "corejs": 3, 则 import '@babel/polyfill' 需要改成
* import 'core-js/stable';
* import 'regenerator-runtime/runtime';
*/
const babel = require('@babel/core');
const code = `[1, 2, 3, 4, [5, 6, [7, 8]]].flat(Infinity);`;
// 只编译语法,不编译 api
// 注意 使用 和 不使用 @babel/plugin-transform-runtime 结果差异很大
// 使用 helpers 是通过 require 引入的,这样就不会存在代码重复的问题了。 (重复的被抽离出去了,通过require 引入)
{
const code = `() => {console.log('11')};class A{}`;
const ast1 = babel.transform(code, {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3
}
]
],
plugins: [
["@babel/plugin-transform-runtime"]
]
});
console.log(ast1.code)
// "use strict";
// (function () {
// console.log('11');
// });
}
{
const ast1 = babel.transform(code, {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 2
}
]
]
});
// 用core-js@2 来看看转码后的结果
console.log(ast1.code);
// "use strict";
// [1, 2, 3, 4, [5, 6, [7, 8]]].flat(Infinity);
}
/**
* 当使用 corejs 3 || 2 & useBuiltIns: 'usage' 再次引入 'require("@babel/polyfill");' 会 warn
*
* 当使用 corejs 3 & useBuiltIns: 'usage' 再次引入 "import 'core-js/stable';import 'regenerator-runtime/runtime';" 多引入 "require('core-js/stable');require('regenerator-runtime/runtime');"
* 当使用 corejs 2 & useBuiltIns: 'usage' 再次引入 "import 'core-js/stable';import 'regenerator-runtime/runtime';" 引入 "require('core-js/stable');require('regenerator-runtime/runtime');"
*/
{
const ast2 = babel.transform("import 'core-js/stable';import 'regenerator-runtime/runtime';" + code, {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: 3
}
]
]
});
// 用core-js@3 来看看转码后的结果
console.log(ast2.code);
// "use strict";
// require("core-js/modules/es.array.flat");
// require("core-js/modules/es.array.unscopables.flat");
// [1, 2, 3, 4, [5, 6, [7, 8]]].flat(Infinity);
}
{
const ast3 = babel.transform(code, {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'entry',
corejs: 2
}
]
]
});
console.log(ast3.code)
// "use strict";
// [1, 2, 3, 4, [5, 6, [7, 8]]].flat(Infinity);
}
/**
* 当使用 corejs 2 & useBuiltIns: 'entry' 再次引入 'require("@babel/polyfill");' 会 加载很多 polyfill
* 当使用 corejs 3 & useBuiltIns: 'entry' 再次引入 'require("@babel/polyfill");' 会 warn
*/
{
const ast3 = babel.transform('require("@babel/polyfill");' + code, {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'entry',
corejs: 2
}
]
]
});
console.log(ast3.code)
// "use strict";
// 加载很多 polyfill
// [1, 2, 3, 4, [5, 6, [7, 8]]].flat(Infinity);
}
{
const ast4 = babel.transform('require("@babel/polyfill");' + code, {
presets: [
[
'@babel/preset-env',
{
targets: {
ie: 9,
},
useBuiltIns: 'entry',
corejs: 2
}
]
]
});
console.log(ast4.code)
// "use strict";
// 加载很多 polyfill
// [1, 2, 3, 4, [5, 6, [7, 8]]].flat(Infinity);
}
{
const ast4 = babel.transform('import "core-js/stable";import "regenerator-runtime/runtime";' + code, {
presets: [
[
'@babel/preset-env',
{
targets: {
ie: 9,
},
useBuiltIns: 'entry',
corejs: 3
}
]
]
});
console.log(ast4.code)
// "use strict";
// 加载很多 polyfill
// [1, 2, 3, 4, [5, 6, [7, 8]]].flat(Infinity);
}
{
const arrays = [[10], 50, [100, [2000, 3000, [40000]]]];
function getList(list){
return list.reduce((result, item) => {
const i = Array.isArray(item) ? getList(item) : item
result = result.concat(i)
return result
}, [])
}
console.log(getList(arrays))
// [ 10, 50, 100, 2000, 3000, 40000 ]
}