Skip to content

Commit cb744c2

Browse files
committed
Use babel for transpiling rather than closure compiler
We recently switch from using closure-compiler with `WHITESPACE_ONLY` to closure-compiler with `SIMPLE_OPTIMIZATIONS`. However this had the negative side effect that all input need to be free of closure compiler warnings, and this turned out not to be practical for all users. See #20810 for more on this When selecting a transpilation tool use I also evaluated `swx` (written in rust) and `esbuild` (written in go). `esbuild` was rejected because the simply don't support ES5 (evanw/esbuild#297). `swx` was rejected because it almost doubled the side of our `node_modules` directory by adding two 50mb binary files.
1 parent dabbde6 commit cb744c2

File tree

7 files changed

+6262
-2532
lines changed

7 files changed

+6262
-2532
lines changed

.flake8

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[flake8]
22
ignore = E111,E114,E501,E261,E266,E121,E402,E241,W504,E741,B011,B023,U101
33
exclude =
4+
./node_modules/, # third-party code
45
./third_party/, # third-party code
56
./tools/filelock.py, # third-party code
67
./tools/scons/, # third-party code

package-lock.json

Lines changed: 6213 additions & 2498 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
"ws": "^8.14.2"
1212
},
1313
"dependencies": {
14+
"@babel/cli": "^7.23.4",
15+
"@babel/core": "^7.23.5",
16+
"@babel/preset-env": "^7.23.5",
1417
"acorn": "^8.11.2",
1518
"google-closure-compiler": "20230802.0.0",
1619
"html-minifier-terser": "7.2.0"

src/settings_internal.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,10 +243,9 @@ var LINK_AS_CXX = false;
243243
// emitted in that case for closure compiler.
244244
var MAYBE_CLOSURE_COMPILER = false;
245245

246-
// Set when some minimum browser version triggers doesn't support the
247-
// minimum set of ES6 features. This triggers transpilation to ES5
248-
// using closure compiler.
249-
var TRANSPILE_TO_ES5 = false;
246+
// Set when some minimum browser version triggers doesn't support the minimum
247+
// set of JavaScript features. This triggers transpilation using babel.
248+
var TRANSPILE = false;
250249

251250
// A copy of the default the default INCOMING_MODULE_JS_API. (Soon to
252251
// include additional items).

test/test_other.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13130,7 +13130,6 @@ def check_for_es6(filename, expect):
1313013130
self.assertContained('foo(arg="hello")', js)
1313113131
self.assertContained(['() => 2', '()=>2'], js)
1313213132
self.assertContained('const ', js)
13133-
self.assertContained('let ', js)
1313413133
self.assertContained('?.[', js)
1313513134
self.assertContained('?.(', js)
1313613135
self.assertContained('??=', js)
@@ -13142,7 +13141,6 @@ def check_for_es6(filename, expect):
1314213141
self.assertNotContained('() => 2', js)
1314313142
self.assertNotContained('()=>2', js)
1314413143
self.assertNotContained('const ', js)
13145-
self.assertNotContained('let ', js)
1314613144
self.assertNotContained('??', js)
1314713145
self.assertNotContained('?.', js)
1314813146
self.assertNotContained('||=', js)

tools/building.py

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -509,14 +509,35 @@ def add_to_path(dirname):
509509
return closure_cmd, env
510510

511511

512+
def version_split(v):
513+
v = str(v)
514+
assert len(v) == 6
515+
rev = int(v[4:6])
516+
minor = int(v[2:4])
517+
major = int(v[0:2])
518+
return f'{major}.{minor}.{rev}'
519+
520+
512521
@ToolchainProfiler.profile()
513-
def closure_transpile(filename):
514-
user_args = []
515-
closure_cmd, env = get_closure_compiler_and_env(user_args)
516-
closure_cmd += ['--language_out', 'ES5']
517-
closure_cmd += ['--compilation_level', 'SIMPLE_OPTIMIZATIONS']
518-
closure_cmd += ['--formatting', 'PRETTY_PRINT']
519-
return run_closure_cmd(closure_cmd, filename, env)
522+
def transpile(filename):
523+
outfile = shared.get_temp_files().get('babel.js').name
524+
config_file = shared.get_temp_files().get('babel_config.json').name
525+
config = '{\n "targets": {'
526+
if settings.MIN_CHROME_VERSION:
527+
config += f'\n "chrome": "{settings.MIN_CHROME_VERSION}",'
528+
if settings.MIN_FIREFOX_VERSION:
529+
config += f'\n "firefox": "{settings.MIN_FIREFOX_VERSION}",'
530+
if settings.MIN_SAFARI_VERSION:
531+
min_safari_version = version_split(settings.MIN_SAFARI_VERSION)
532+
config += f'\n "safari": "{min_safari_version}",'
533+
if settings.MIN_NODE_VERSION:
534+
min_node_version = version_split(settings.MIN_NODE_VERSION)
535+
config += f'\n "node": "{min_node_version}",'
536+
config += '\n }\n}'
537+
utils.write_file(config_file, config)
538+
cmd = shared.get_npm_cmd('babel') + [filename, '-o', outfile, '--presets', '@babel/preset-env', '--config-file', config_file]
539+
check_call(cmd, cwd=path_from_root())
540+
return outfile
520541

521542

522543
@ToolchainProfiler.profile()
@@ -581,13 +602,8 @@ def closure_compiler(filename, advanced=True, extra_closure_args=None):
581602
args = ['--compilation_level', 'ADVANCED_OPTIMIZATIONS' if advanced else 'SIMPLE_OPTIMIZATIONS']
582603
# Keep in sync with ecmaVersion in tools/acorn-optimizer.mjs
583604
args += ['--language_in', 'ECMASCRIPT_2021']
584-
# Tell closure not to do any transpiling or inject any polyfills.
585-
# At some point we may want to look into using this as way to convert to ES5 but
586-
# babel is perhaps a better tool for that.
587-
if settings.TRANSPILE_TO_ES5:
588-
args += ['--language_out', 'ES5']
589-
else:
590-
args += ['--language_out', 'NO_TRANSPILE']
605+
# We do transpilation using babel
606+
args += ['--language_out', 'NO_TRANSPILE']
591607
# Tell closure never to inject the 'use strict' directive.
592608
args += ['--emit_use_strict=false']
593609

tools/link.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,15 +1138,12 @@ def phase_linker_setup(options, state, newargs):
11381138
# Taking the highest requirements gives is our minimum:
11391139
# Max Version: EDGE:85 FF:79 CHROME:85 SAFARI:14 NODE:16
11401140
# TODO: replace this with feature matrix in the future.
1141-
settings.TRANSPILE_TO_ES5 = (settings.MIN_EDGE_VERSION < 85 or
1142-
settings.MIN_FIREFOX_VERSION < 79 or
1143-
settings.MIN_CHROME_VERSION < 85 or
1144-
settings.MIN_SAFARI_VERSION < 140000 or
1145-
settings.MIN_NODE_VERSION < 160000 or
1146-
settings.MIN_IE_VERSION != 0x7FFFFFFF)
1147-
1148-
if options.use_closure_compiler is None and settings.TRANSPILE_TO_ES5:
1149-
diagnostics.warning('transpile', 'enabling transpilation via closure due to browser version settings. This warning can be suppressed by passing `--closure=1` or `--closure=0` to opt into this explicitly.')
1141+
settings.TRANSPILE = (settings.MIN_EDGE_VERSION < 85 or
1142+
settings.MIN_FIREFOX_VERSION < 79 or
1143+
settings.MIN_CHROME_VERSION < 85 or
1144+
settings.MIN_SAFARI_VERSION < 140000 or
1145+
settings.MIN_NODE_VERSION < 160000 or
1146+
settings.MIN_IE_VERSION != 0x7FFFFFFF)
11501147

11511148
# https://caniuse.com/class: EDGE:13 FF:45 CHROME:49 SAFARI:9
11521149
supports_es6_classes = (settings.MIN_EDGE_VERSION >= 13 and
@@ -2203,14 +2200,15 @@ def phase_binaryen(target, options, wasm_target, memfile):
22032200
with ToolchainProfiler.profile_block('asyncify_lazy_load_code'):
22042201
building.asyncify_lazy_load_code(wasm_target, debug=intermediate_debug_info)
22052202

2206-
if final_js and (options.use_closure_compiler or settings.TRANSPILE_TO_ES5):
2203+
if final_js:
22072204
if options.use_closure_compiler:
22082205
with ToolchainProfiler.profile_block('closure_compile'):
22092206
final_js = building.closure_compiler(final_js, extra_closure_args=options.closure_args)
2210-
else:
2211-
with ToolchainProfiler.profile_block('closure_transpile'):
2212-
final_js = building.closure_transpile(final_js)
2213-
save_intermediate_with_wasm('closure', wasm_target)
2207+
save_intermediate_with_wasm('closure', wasm_target)
2208+
if settings.TRANSPILE:
2209+
with ToolchainProfiler.profile_block('transpile'):
2210+
final_js = building.transpile(final_js)
2211+
save_intermediate_with_wasm('traspile', wasm_target)
22142212

22152213
symbols_file = None
22162214
if options.emit_symbol_map:

0 commit comments

Comments
 (0)