swc
swc copied to clipboard
Possible to use swc with / for eslint?
eslint
is a big part of our largest project's build times and it's currently configured to use babel-parser.
To get rid of babel entirely it'd be nice to be able to get eslint to use swc somehow: https://eslint.org/docs/user-guide/configuring#specifying-parser
On an unrelated note, with swc 1.0.21 the project finally builds and seems to mostly work (I haven't looked to closely yet). Thank you for your hard work and the quick responses to bug reports, it's much appreciated!
It's blocked by #230 (because we can't emit esprima-compatible ast)
Would be pretty nice if the parser could be turned into a standalone project you can use in other rust projects 👀
@ForsakenHarmony Parser is uploaded on crates.io, and it can be built with stable rust.
I just tried but it seems eslint is expecting something a little bit different than the format returned by
exports.parse = function(str, opts) {
return {
ast: require('@swc/core').parseSync(str.toString(), {})
};
};
EDIT2: this is what eslint expects: https://eslint.org/docs/developer-guide/working-with-custom-parsers
To test with eslint, just create a swcparser.js
file at the root of your project,
then put this into your project's .eslintrc
:
{"parser": "./swcparser.js"}
Then to debug,
DEBUG=eslint:* eslint somefile.js
Using @swc/core 1.1.6 and eslint 6.7.2:
echo "var a = 1;" | eslint --stdin
eslint:linter Parsing error: AST is missing the tokens array.
eslint:linter Error: AST is missing the tokens array.
as expected, since the tokens array is indeed not where it is supposed to be.
@kdy1 I'm a bit confused about the status of this, hope you can clarify. (As you might be guessing I'm also super excited about swc use with eslint because of speed).
A comment above (https://github.com/swc-project/swc/issues/246#issuecomment-465403756) is mentioning this having been blocked by #230. That issue is closed and merged. Considering the comment above "AST is missing the tokens array." I'm guessing there is more missing?
It still requires lots of work
If I got it right #230 would allow to have the needed AST format as an output.
as https://github.com/swc-project/swc/pull/274 is merged, does this mean this issue is unblocked? What would be the needed next steps?
In case it is not unblocked, would something like https://github.com/babel/babel-eslint/tree/master/lib/babylon-to-espree be an intermediate solution? Adapting it to work with the output from swc? Or is there some issue with the format that would make that solution used by babel impossible with swc?
It's possible, but I'm not sure if it worths
Can you elaborate more?
Do you mean that with #274 it is now natively possible to use swc as a eslint (espree) parser? And if not, what is missing to be done?
or do you mean that converting the format in js as it is done with babel is "possible, but not worth it"? Would that be too much work for a possibly small speed improvement?
In general I think this is a topic of interest to speed up eslint end if the remaining work to be done is clear maybe easier to get it contributed.
Do you mean that with #274 it is now natively possible to use swc as a eslint (espree) parser? And if not, what is missing to be done?
No, because eslint does not use babel ast. It can be used if something like https://github.com/babel/babel-eslint/tree/master/lib/babylon-to-espree is used.
swc-to-espree is not done.
or do you mean that converting the format in js as it is done with babel is "possible, but not worth it"? Would that be too much work for a possibly small speed improvement?
Is eslint slow because of the parser? I know parsing in javsacript is very slow, but optimizations have only meaning if it was the bottleneck.
Note: It can be a huge difference if eslint custom parser api supports asynchronous parser. If it's the case, performance will be improved a lot even if the bottleneck wasn't the parser.
I started a discussion on eslint about asynchronous parser api. https://github.com/eslint/eslint/discussions/14733
It takes over 90 seconds to lint our project on my Mac. Here's a screenshot of a CPU profile (Top-down view) - hope it helps.

FYI The missing 20% is GC.
It may worth then, but I expect conversion of swc ast -> babel ast -> espree ast to be slow. Need some profiling I guess.
Is there some insight on this? Is there a working solution that could make ESLint work with SWC yet?
@extroonie swc has code to produce ESTree AST/ acorn AST, but it's not exposed to js world currently. It will be nice if you can patch it to expose it.
@kdy1 sorry but I don't quite get that. What do you mean by patching it? Could you walk me through it please?
@extroonie I mean adding a method that is callable from js world, like https://github.com/swc-project/swc/blob/a4e93eb2dff0614e7a39c4301c84654412cf68dc/crates/node/src/transform.rs#L140-L157
@kdy1 thanks. Just want to double-check, the problem I'm having with ESLint and SWC is that some of the code with decorators and other ECMAScript proposals are throwing parser errors with ESLint. Now, I'm not sure whether SWC or ESLint has to deal with it.
You need to patch both
@extroonie swc has code to produce ESTree AST/ acorn AST, but it's not exposed to js world currently. It will be nice if you can patch it to expose it.
@kdy1 I'd love to give it a shot!
Which methods of swc_estree_compat
would you expose for that?
@manuschillerdev There's babelify()
In my case, I have just deleted the attribute "parser": "@babel/eslint-parser"
in the .eslintrc
config fie.
Then I set up the following config in vscode.
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[javascriptreact]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
}
It works well for me.
How are things going?