swc icon indicating copy to clipboard operation
swc copied to clipboard

ESTree compatible AST

Open sosukesuzuki opened this issue 4 years ago • 24 comments

Describe the feature

Support ESTree compatible AST.

Some options:

  • SWC output ESTree compatible AST directly.
  • New tool like swc-to-estree

Babel plugin or link to the feature description

Nothing.

Additional context Add any other context about the problem here.

I'm a maintainer of Prettier Code Formatter and I'm developing to use SWC as a parser for Prettier (Disclaimer: It is a 100% personal activity and not affiliated with any organization.) Prettier already has a code base to handle ESTree compatible ASTs well. So, if SWC supports ESTree, it will be easier. Also, ESTree is the de facto standard for JavaScript ASTs, and by supporting it, many other tools may be able to use SWC.

related: https://github.com/swc-project/swc/issues/1392

sosukesuzuki avatar Aug 21 '21 04:08 sosukesuzuki

@kdy1 What do you think about this?

sosukesuzuki avatar Aug 23 '21 03:08 sosukesuzuki

@sosukesuzuki Just a heads up, the parse APIs are being deprecated. But I've asked if there'll be a way to support this scenario in the future as I've seen some perf improvements on my end (replacing acorn with swc+ little AST adapters).

jdalton avatar Aug 23 '21 03:08 jdalton

I made a mistake. parse will be preserved to help some tools like ast explorer.

kdy1 avatar Aug 23 '21 05:08 kdy1

Is it expected that third party libraries will only use the swc parser?

sosukesuzuki avatar Aug 23 '21 05:08 sosukesuzuki

No, but rust <-> js is very slow and it overwhelms time used for actual work.

kdy1 avatar Aug 23 '21 05:08 kdy1

I see. Out of curiosity, you are doing integration SWC and Next.js at vercel? At there, how to integrate Rust land and JS land?

sosukesuzuki avatar Aug 23 '21 05:08 sosukesuzuki

Yes. We are working on it. We are going to reimplement all transforms in rust, and call transform() from js.

kdy1 avatar Aug 23 '21 05:08 kdy1

I found https://github.com/vercel/next.js/tree/canary/packages/next/build/swc. It looks good, thanks

sosukesuzuki avatar Aug 23 '21 05:08 sosukesuzuki

@kdy1 (The main topic of this issue) What do you think about making swc's AST consistent with ESTree, which is the de facto standard?

sosukesuzuki avatar Aug 24 '21 02:08 sosukesuzuki

What's the advantage if I make it compatible with estree? Rust does not have GC, and estree-like ast will degrade performance.

kdy1 avatar Aug 24 '21 04:08 kdy1

I did not know about the performance drawbacks. The advantage is that it is much easier for existing tools such as ESLint and Prettier to use swc as a parser.

sosukesuzuki avatar Aug 24 '21 04:08 sosukesuzuki

I see. But actually, passing ast to javascript from rust is very slow. Parser itself is fast, but json serialization/deserialization is the problematic part, and I'm not sure about the way to make it fast. Maybe lazy accessors can be a solution, but I didn't try it.

kdy1 avatar Aug 24 '21 04:08 kdy1

If you provide the string the user can do things like fast-json. This allows for them to choose which serializer (JSON.parse or otherwise) to use.

jdalton avatar Aug 24 '21 04:08 jdalton

@jdalton If it's fast enough, I think we can support babel plugins. So I think it is worth benchmarking.

kdy1 avatar Aug 24 '21 05:08 kdy1

As a test of raw parse power I tried parsing babylon.max.js which s 10.6MB of JS. It takes acorn ~700ms and swc ~2 seconds, so I can see what you mean about the Rust->JS transition.

jdalton avatar Aug 24 '21 06:08 jdalton

Please see #2175 if you're interested. I've done some experiments into speeding up parse().

overlookmotel avatar Aug 29 '21 02:08 overlookmotel

@jdalton (replacing acorn with swc + little AST adapters)

Could you share this code?

vjpr avatar Sep 30 '21 15:09 vjpr

Why not just write a package to transform SWC's AST to ESTree's AST

const swcAst = parseSync(code);
const estreeAst = swc2estree(swcAst);

axetroy avatar Mar 07 '25 11:03 axetroy

Why not just write a package to transform SWC's AST to ESTree's AST

const swcAst = parseSync(code); const estreeAst = swc2estree(swcAst);

There's already have. https://github.com/swc-project/swc/blob/main/crates/swc_estree_compat/README.md

But it did not available on npm

axetroy avatar Mar 07 '25 11:03 axetroy

@kdy1 Just interesting, is swc_estree_compat ready to use?

alexander-akait avatar Mar 07 '25 12:03 alexander-akait

@alexander-akait Nearly, but it would be very slow at the moment because of JSON.parse of large AST is very slow

kdy1 avatar Mar 07 '25 12:03 kdy1

@kdy1 Any ideas how we can solve it?

alexander-akait avatar Mar 07 '25 12:03 alexander-akait

Yes, but need some triage because I need to port rkyv to typescript/javascript.

kdy1 avatar Mar 09 '25 04:03 kdy1

any update?

NaviTheCoderboi avatar Nov 21 '25 13:11 NaviTheCoderboi