Skip to content

[Meta] Plugin system for 2.0 #2635

@kdy1

Description

@kdy1

I will modify this as required.

Javascript plugins

If it's possible to make it fast, I'll support js plugins, too.

Rust-based plugins

Tasks

Task: Proxy swc_common (#2646)

  • swc_common: Create a trait for thread-local APIs. (cargo feature plugin-base)
  • swc_common: Implement the trait. (cargo feature plugin-rt)
  • swc_common: Replace APIs in plugin mode. (cargo feature plugin-mode)
  • Pass the trait to plugins and use it to replace swc_common APIs.

Task: rplugin: System to pass AST directly (#2671)

This is important for performance.

Task: Share more input, like SourceMap or SourceFile.

Task: Actaully use rplugin.

Task: Improve plugin runner

Task: Add plugin feature to swc

Task: Expose node apis

Design

I experimented lots of ways for plugin system, and decided to go with abi_stable. But there's a problem.

Problem: Identical API

I want to provide identical API as core transforms. And it requires sharing data stored in thread-local variables.

Triage: Dynamic library

I initially thought I need to make swc_common a dynamic library so plugins can invoke it. But dynamic linking does not fit for swc plugins. As swc_common depends on std, the version of rustc should be all same among plugins, and chaning version of rustc becomes a huge breaking change. I don't want to break all plugins by upgrading rustc. So wee need another way than a dynamic library.


I posted some questions on the rust community while trying this option, in case you are curious about what I tried.

I also experimented with extern "C". See https://github.com/kdy1/rust-dylib-test

Solution: Pass function to plugin with stable abi

Instead of making swc_common dynamic library, we can pass a big trait that contains functions related to thread-local variables in swc_common.

The plugin runner will pass this trait while invoking plugins. abi_stable can be used to do this.

For plugins, operations of swc_common will be replaced by the trait. In other words, functions in swc_common will work by calling a method in the passed trait object.


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions