-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[babel 8] Move ESLint parsing to a Worker #13199
[babel 8] Move ESLint parsing to a Worker #13199
Conversation
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/46140/ |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 3febba7:
|
ad943ff
to
e76b293
Compare
I moved parsing from the worker to the main thread when using the default The negative performance impact of using a separate worker is gone: running I converted the files to The last commit isn't strictly required, but since this PR makes it easy to load the config asynchronously I removed the restriction that disallows |
|
||
if (process.env.BABEL_8_BREAKING) { | ||
return babel | ||
.loadPartialConfigAsync(parseOptions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we load partial config when options.requireConfigFile
is false?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to match the current behavior, and I think that when requireConfigFile: false
it still loads the config file if it's present, but it doesn't throw if it's not. To disable config file loading, you need to pass babelOptions: { configFile: false }
.
374d10e
to
45f120b
Compare
|
||
let send; | ||
|
||
exports.getVersion = sendCached("GET_VERSION"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we extract these action types to a constant that we reuse everywhere so we don't risk bugs due to typos?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved them to this file (rather than always using the string) so that we only have to care about those strings in the two "communication files" (worker client and server). Everywhere else we use getVersion()
etc.
Also, https://github.com/babel/babel/pull/13199/files#diff-62c6b0f19ec3e004fffbecf4acab02bc005e538ea3c08e9bd558def1f28634c7R32 throws so that we catch any invalid string early.
b597589
to
3febba7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
I'll try again moving to esm and let's see how far I can get this time 🤞 |
One of the main blockers for moving to ESM is that ESLint doesn't support asynchronous parsers yet (ref: eslint/eslint#14295).
This PR works around the problem by moving
@babel/core
usage inside@babel/eslint-parser
inside a service worker: by doing that it doesn't matter that loading@babel/core
is asynchronous, because we can always communicate with the worker synchronously. This can also be easily extended to allow users to usebabel.config.mjs
files with@babel/eslint-parser
(currently it throws an error).This PR touches all the files in
@babel/eslint-parser
, but the only new things aresrc/client.cjs
,src/worker/index.cjs
andsrc/worker/babel-core.cjs
. Everything else is just moved around.(EDIT: See #13199 (comment)) This PR causes (when
BABEL_8_BREAKING
istrue
) a performance drop of 10% when linting our repo witheslint-plugin-prettier
disabled (5% when it's enabled). For this reason, I'll follow up with a different approach: rather than passing the input source code to the worker and getting back the AST (which is big and expensive to clone across workers), I want to only give the worker the input filename and make it return the set of options that we need to give to@babel/parser
. By doing so, we can keep config/plugins resolution async while avoiding passing the big AST object around. However, this@babel/parser
to be CJS (and imo it would be acceptable, since it's also used as a standalone tool by other projects such as Prettier)tokTypes
identity, so it can only be done after fixing @babel/core^7.13.10 eslint error: Cannot read property 'value' of null when @babel/types are duplicated in node_modules #12985