Giter Site home page Giter Site logo

Plugin system about swc HOT 34 CLOSED

swc-project avatar swc-project commented on May 7, 2024
Plugin system

from swc.

Comments (34)

kdy1 avatar kdy1 commented on May 7, 2024 6

Javascript based plugin is almost done, and there's a basic example of using plugin.
See https://github.com/swc-project/node-swc/blob/d51369e43e590fa66ddc2db6ca39976cdd185ac9/__tests__/transform/plugin.js

cc @Michael-F-Bryan, @stefanpenner, @lifeart, @izelnakri, @hh9527

from swc.

hh9527 avatar hh9527 commented on May 7, 2024 5

@kdy1 , I do think the performance is most important, if we can not beat babel family in performance, very few people will use swc.

In the old days, plugin system is very important to babel, because ECMAScript was evolving very fast. people always need to use plugin-transform-xxx to use latest syntax. But these has been changed nowadays. In most cases, for a web/js developer, these are enough:

  • preset-env
  • preset-typescript
  • preset-react
  • css module (id/classname mapping)
  • a bundler

So, maybe it is not necessary to make a full dynamic plugin system to external developer. A crate based static plugin system is enough. That is why I prefer C. And if some user do have a requirement to make a customized extension, he can build his own customized swc by B (combine plugins and swc-core with his own plugin crate)

from swc.

stefanpenner avatar stefanpenner commented on May 7, 2024 4

Keep me posted!

But yes, absolutely down to author rust plugins. All we need is a good plugin API.
Especially if this allows concurrency provided by transform over transformSync.

from swc.

kdy1 avatar kdy1 commented on May 7, 2024 4

@stefanpenner #475 (comment)

[plugin]
  parse x 3,156 ops/sec ±0.43% (89 runs sampled)
  parse + print x 740 ops/sec ±0.35% (88 runs sampled)
  parse + transform x 734 ops/sec ±0.22% (88 runs sampled)
  plugin x 720 ops/sec ±0.32% (87 runs sampled)
[transform]
  swc (es3) x 761 ops/sec ±0.23% (89 runs sampled)
  swc (es2015) x 800 ops/sec ±1.02% (87 runs sampled)
  swc (es2016) x 2,123 ops/sec ±0.84% (88 runs sampled)
  swc (es2017) x 2,131 ops/sec ±1.13% (90 runs sampled)
  swc (es2018) x 2,981 ops/sec ±0.25% (90 runs sampled)
  swc-optimize (es3) x 712 ops/sec ±0.21% (86 runs sampled)
Browserslist: caniuse-lite is outdated. Please run next command `npm update caniuse-lite browserslist`
  babel (es5) x 41.75 ops/sec ±8.07% (56 runs sampled)
[typescript]
  swc (es3) x 646 ops/sec ±2.25% (87 runs sampled)
  swc (es5) x 703 ops/sec ±0.55% (89 runs sampled)
  swc (es2015) x 708 ops/sec ±0.26% (87 runs sampled)
  swc (es2016) x 1,656 ops/sec ±0.17% (90 runs sampled)
  swc (es2017) x 1,661 ops/sec ±0.33% (91 runs sampled)
  swc (es2018) x 2,135 ops/sec ±0.25% (88 runs sampled)
  swc-optimize (es3) x 631 ops/sec ±0.13% (88 runs sampled)
  babel (es5) x 41.89 ops/sec ±4.62% (54 runs sampled)

from swc.

kdy1 avatar kdy1 commented on May 7, 2024 3

Plugin system is almost ready.

TODOs

Sidenotes:

  • AST types are not compatible with babel's one.
    Even though, visitor based plugin will be easy to port for swc.

from swc.

kdy1 avatar kdy1 commented on May 7, 2024 2

@stefanpenner Oh.. I'm bit surprised by it. But either option do not affect performance gap caused by core transforms. I will do some investigation and add some benchmarks.

from swc.

Michael-F-Bryan avatar Michael-F-Bryan commented on May 7, 2024

I'd be keen to help out with this! We can probably reuse a lot of the logic from the Dynamic Loading and Plugins chapter from my FFI guide.

The main thing we'd need is a stable-ish interface for doing transformations (i.e. the Fold<T> trait) and then figure out a set of conventions for how users register their plugin(s).

from swc.

kdy1 avatar kdy1 commented on May 7, 2024

Note: All core transformations ported from babel and closure compiler will be statically compiled.

from swc.

kdy1 avatar kdy1 commented on May 7, 2024

@Michael-F-Bryan I'm sorry about my mistake.
I meant ecmascript module by 'Module'. Module loader meant bundler like browserify

I created another issue instead of modifying this issue as plugin system is required anyway.

from swc.

stefanpenner avatar stefanpenner commented on May 7, 2024

I have been doing some exploration re: work to get swc powering ember applications.
So far the performance seems really excellent, which motivates me to open discussion in-regards to the remaining non-bug blockers.

Currently, we rely heavily on babel plugins. Some of these plugins may make good core functionality, others maybe should remain as part of a plugin ecosystem.

The core babel plugins are:

My tracking issue: stefanpenner/broccoli-swc#10

from swc.

kdy1 avatar kdy1 commented on May 7, 2024

@stefanpenner I have some questions

  • babel-plugin-debug-macros

swc currently has inline_globals pass and simplifier pass which performs dead code elimination.

if (__DEBUG__) {
    console.log('Foo')
}

Isn't this enough?

(See https://github.com/swc-project/node-swc/blob/06845c25c64ccfc626cfdac53987f17b94ef95d8/__tests__/optimizer_test.js#L4-L22 for usage)

from swc.

stefanpenner avatar stefanpenner commented on May 7, 2024

@kdy1 it is very close, the exception is our API accomplishes this not via globals but rather via module imports.

so where you currently have __DEBUG__ global, we also have:

import { DEBUG } from '@ember/env-flags';

and

import { FEATURE_A, FEATURE_B } from '@ember/features';

Honestly, it seems like inline_globals having inline_modules as a sibling feature would be generic enough to accomplish this.

from swc.

kdy1 avatar kdy1 commented on May 7, 2024

Neon does not support invoking javascript function from worker thread. It seems like node's limitation as node requires all javascript code to run in event loop thread. So we don't have many option.

Options are

  • moving transformAsync to event loop thread
    This will reduce performance gap between swc and babel. Even though, it's also an option because swc is 16x - 20x faster than babel even with transfomSync, which works on event loop.

  • implementing plugin layer in javascript
    It can be done by

    • making transform* to return ast instead of stringified code (with hidden emit: 'ast' flag)
    • handling plugins from javascript
    • exporting parse / toCode method

I'll try second option.

@stefanpenner Okay, I got it and I'll implement it as a core module.

from swc.

stefanpenner avatar stefanpenner commented on May 7, 2024

@kdy1 honestly for us, we absolutely wouldn't mind authoring/re-implementing our plugins in rust. (In-fact this is what I assumed we would need to do).

The performance difference is something we wouldn't want to compromise on at all.

My expectation was that swc would provide a mechanism to providing plugins in rust, and we would author to that API.

from swc.

kdy1 avatar kdy1 commented on May 7, 2024

@stefanpenner javascript plugin cannot run in worker threads. It runs only on event loop thread. To make javascript code work concurrently, we should spawn child process. (Parcel do this).

from swc.

stefanpenner avatar stefanpenner commented on May 7, 2024

@kdy1 ya, that was my assumption.

from swc.

stefanpenner avatar stefanpenner commented on May 7, 2024

@kdy1 is there a way to load rust plugins? That way we get the best of both worlds.

from swc.

stefanpenner avatar stefanpenner commented on May 7, 2024

To make javascript code work concurrently, we should spawn child process.

Ya, we currently do this via node-workerpool for our babel builds.

from swc.

kdy1 avatar kdy1 commented on May 7, 2024

@kdy1 is there a way to load rust plugins? That way we get the best of both worlds.
@stefanpenner Yes, but I'm not sure about how rust plugins would be published and loaded

from swc.

stefanpenner avatar stefanpenner commented on May 7, 2024

Fair fair. I’ll do some inquiry this week myself :)

from swc.

stefanpenner avatar stefanpenner commented on May 7, 2024

@kdy1 I’m curious what issues the above #18 (comment) idea poses?

from swc.

kdy1 avatar kdy1 commented on May 7, 2024

@kdy1 I’m curious what issues the above #18 (comment) idea poses?

It was about plugin system based on dynamically loaded library (.dll on windows, .so on linux). I didn't merged it because such plugin system would make deploying plugin too hard.

from swc.

stefanpenner avatar stefanpenner commented on May 7, 2024

@kdy1 very cool. I'll give it a whirl once the the last step is out (even if its in PR form).

I'll be curious how performance characteristics are. I have some PTSD from another project which mixes js -> native -> js -> native -> js ;P But i'll keep an open mind

from swc.

lifeart avatar lifeart commented on May 7, 2024

Just in case - nginx has very fast subset of js

image

from swc.

izelnakri avatar izelnakri commented on May 7, 2024

transformAsync() JS plugin hook sounds very exciting, despite that being in JS, it would still be a very useful first step.

Later for rust plugins we can probably define the rust swc plugins in package.json and make @swc/cli swc compile command to read them and initiate several steps to create a new neon module with @swc/core + rust plugins in it compiled and exposed, it could also be a local npm linked module if needed. Probably hacky but shouldnt be impossible :)

just subscribed to this thread. @kdy1 please let us know when there is a PR.

from swc.

hh9527 avatar hh9527 commented on May 7, 2024

There will be many choices to make a plugin system.
A. dll/so based
B. crate based: swc as a dependency, leave the final combined binary to the other project
C. crate based: all plugins are a dependency crates, and build into one single binary (swc) together by feature gates
D. swc binary + ipc based plugin protocol
E. swc binary + js based plugin interface
F. swc as a wasm module (loaded by nodejs) + js based plugin interface

I prefer C (B is a pre step of C).
F is also interesting.

from swc.

kdy1 avatar kdy1 commented on May 7, 2024

@hh9527 I almost implemented E, but I think I should reimplement a javascript code generator in javascript because overhead of serialization / deserialization makes swc too slow.

from swc.

kdy1 avatar kdy1 commented on May 7, 2024

@hh9527

A: seems quite hard, Deployment process would be incredibly complex.
B: Has same issue as B. Deploying binary based stuff is too hard.
C: I also prefer C, but it requires user to write plugin in rust and would make .swcrc very complex.
D: Too hard, and serialization is too expensive.
E. swc binary + js based plugin interface
F: Serialization is too slow.

So I'm currently reimplementing code generator in javascript. (to implement E)

from swc.

kdy1 avatar kdy1 commented on May 7, 2024

There's a new issue for plugin system

Please see: #470 (comment)

from swc.

kdy1 avatar kdy1 commented on May 7, 2024

Closing in favor of #471.

from swc.

kdy1 avatar kdy1 commented on May 7, 2024

@hh9527 I'll go with js-based plugin and ipc-based plugin.

from swc.

stefanpenner avatar stefanpenner commented on May 7, 2024

@kdy1 very cool, any early benchmarks / perf intuitions?

from swc.

hh9527 avatar hh9527 commented on May 7, 2024

@hh9527 I'll go with js-based plugin and ipc-based plugin.

congratulations! thank you!

from swc.

swc-bot avatar swc-bot commented on May 7, 2024

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

from swc.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.