[Meta] collecting feedback for new transform plugin interface #3540
Replies: 45 comments 109 replies
-
|
Beta Was this translation helpful? Give feedback.
-
Is it possible to get the name of the file being processed inside the plugin? |
Beta Was this translation helpful? Give feedback.
-
Created this plugin, repo has examples and tests too https://github.com/williamtetlow/swc-plugin-console-prefix Do you have an example |
Beta Was this translation helpful? Give feedback.
-
What do you think of saying to add wasm target when building instead of setting default in
I feel like the common dev flow is going to be more TDD based with users writing tests to assert the output when creating the Visitor and building wasm and running it with swc will be done less frequently. I think it will be common to add dev-dependencies that don't support wasm target. For example, I'm installing It's easier for me to run unit tests like |
Beta Was this translation helpful? Give feedback.
-
Is it possible to opt out of default compilation pipeline for plugins? Or maybe add a preprocess step. Use case is being able to perform JSX transforms on preserved AST without SWC compiling it to react JSX calls. |
Beta Was this translation helpful? Give feedback.
This comment has been hidden.
This comment has been hidden.
-
Is it possible to also pass comments to plugin? Use case would be replacing comments like react transform does. |
Beta Was this translation helpful? Give feedback.
This comment has been hidden.
This comment has been hidden.
-
I guess it's totally fine that SWC will introduce breaking changes at some time. What would be the best practice to specify in the package.json for which |
Beta Was this translation helpful? Give feedback.
This comment has been hidden.
This comment has been hidden.
-
Invalid package.json namethere are some rules for
What about converting the plugin name to kebab case automatically in the following example?
|
Beta Was this translation helpful? Give feedback.
-
My question kind of relates to 3 from the original post, but doesn't quite fit. When pointing directly to a WASM binary, is there any way to use a relative path? For example let's say at the top level my project is laid out like:
within
The configs use swc loader so somewhere in those files I have:
I'd like for that last bit to look something more like:
I can't figure out how to do that though. Is it possible? |
Beta Was this translation helpful? Give feedback.
-
Having a pretty great time with the plugin system so far, despite how early it is! I have what may be a dumb question though because I don't have any experience doing this kind of thing. Say I want to transform some string literals to identifiers and then add imports for them. Original: foo("bar"); Transformed: import { bar } from "baz";
foo(bar); I have seen this done in babel by
Is there a way to either
Edit: I'm aware I could probably do it from my "main function" ( |
Beta Was this translation helpful? Give feedback.
This comment has been hidden.
This comment has been hidden.
-
Anyone get a deno recipe goin? I found https://github.com/nestdotland/deno_swc, but think the bindings are out of date. Uncertain if there is another module people use. import { transform } from "https://x.nest.land/[email protected]/mod.ts";
const code = `import * as foo from "https://bar.org/baz";`;
const out = transform(code, {
filename: "input.js",
jsc: {
experimental: {
plugins: [
[
"./src/middlewares/emit/swc_plugin_deno_emit_server_rewrite_imports.wasm",
{},
],
],
},
},
});
console.log(out);
:) |
Beta Was this translation helpful? Give feedback.
-
How to call |
Beta Was this translation helpful? Give feedback.
This comment has been minimized.
This comment has been minimized.
This comment has been hidden.
This comment has been hidden.
-
What is the current status of the feature? as I see, plugins are still under experimental flag. I'm insterested is there are any specific plans or terms to mark it as stable and ready to use? |
Beta Was this translation helpful? Give feedback.
-
Hi there! I created a new plugin using Ended up getting this error:
Any ideas what's going on? |
Beta Was this translation helpful? Give feedback.
-
Is there any way to use builtin helpers like this in custom plugins?
I want to implement something similar to babel's imports tranform. |
Beta Was this translation helpful? Give feedback.
-
@kwonoj I want to transform import path in plugin like // before
import x from './foo'
// after
import x from './foo.cjs' Can I access Or there is any way to apply my plugin run after swc transform Thanks ~ |
Beta Was this translation helpful? Give feedback.
-
@kwonoj - I want to use babel-plugin-macro within my project (not a next.js project). Currently, when I use @swc/jest, it throws the error. MacroError: The macro you imported from "undefined" is being executed outside the context of compilation with babel-plugin-macros. This indicates that you don't have the babel plugin "babel-plugin-macros" configured correctly. I believe babel-plugin-macro either needs an equivalent rust plugin Any suggestion or are there any work arounds What I have tried - configured twin.macro and read.macro, but I beleive currently it support only text file reading, but failed in configurin them :( Let me know if any work around for using babel-plugin-macros |
Beta Was this translation helpful? Give feedback.
-
These codes will get an error "Caused by:
Here is my repository https://github.com/coder-xiaotian/swc-useclient. |
Beta Was this translation helpful? Give feedback.
-
The file system cache seems not working, I found that when WASM is compiled, it is saved into both memory cache called if let Some(fs_cache_store) = &self.fs_cache_store {
let hash = self.fs_cache_hash_store.get(key)?;
let store = new_store();
let module = unsafe { fs_cache_store.load(&store, *hash) };
if let Ok(module) = module {
return Some(Box::new(CompiledPluginModuleBytes::new(
...
)));
}
} Wonder if this is a bug, or I missed something here @kwonoj |
Beta Was this translation helpful? Give feedback.
-
we are using a swc plugin to automatically split i18n translations per chunk: https://github.com/jantimon/i18n-next-demo/blob/main/README.md and we are using a swc plugin for scoped css custom properties (aka css variables): after two years it would be interesting to know if this experiment will be stable in future |
Beta Was this translation helpful? Give feedback.
-
In the SWC Rust plugin, the fs API needs to be used. When the compilation target is wasm32-wasi, the fs API call does not take effect. |
Beta Was this translation helpful? Give feedback.
-
How can I use |
Beta Was this translation helpful? Give feedback.
-
Hey folks 👋 There was some recent movement in the linked rkyv issue related to the key question:
It seems like they are suggesting that we can create a stable interface contract by managing versioned types. I know that would be a complex thing to move to but is this something that solves our problem or do we need to clarify our need in the upstream issue? |
Beta Was this translation helpful? Give feedback.
-
New transform plugin is ready to try out 🎉
(Previous references: #2929)
What is this?
SWC currently has an interface to support plugins written in javascript for its transform (https://swc.rs/docs/usage/plugins). However, it was not strongly recommended due to several ergonomics, including performance bottleneck. Since then, SWC has tried to attempt to implement new plugin system does work on the host side (SWC's rust binary). #3167 was created to track initial effort for the experiments, and we think we have reached the state where people can try to write a plugin with new interfaces.
It is marked as
experimental
currently as we expect we'll have to iterate few changes or fixes we couldn't find while working on this feature. This discussion is to collect feedback, suggestions, or compile list of bugs to be fixed to stablize new plugin system.How to write a plugin
The new plugin system uses WebAssembly-based runtime. Currently, there is a rust-based package to support this (https://crates.io/crates/swc_plugin) which includes utilities to write plugins more easily. Package
swc_cli
includes small commandline utility to help creating a new project. First, if you haven't installswc_cli
package, install it via cargo. It'll allow to use commandline toolswc
. (note binary name isswc
, while package name isswc_cli
)Then you can create new plugin project.
swc plugin new ${plugin_name} --target-type=wasm32-wasi
One thing to note is you should specify
--target-type
betweenwasm32-wasi
orwasm32-unknown-unknown
. SWC's transform plugin should be either type of WebAssembly binary. Major difference between those 2 target iswasi
support. If you're not sure what to use, or you'd like to use macros likeprintln!()
, choose wasi.Once a project is created you can write actual transform visitor! It can be done by implementing proper
visit_mut_*
interfaces for your visitor. While there is no dedicated documentation yet, you can refer to some of core transform implementations as examples. Test cases like this or core's jest support can be a good reference to look into.To load plugins, you may use
swcrc
'sjsc.experimental
configs:Please give it a try, and share feedbacks! 🙏 We'd like to iterate as much before making this as stable release.
If you found bugs, or something is not working: Please create an issue at https://github.com/swc-project/swc/issues with reproducible repo
If you have opinions, suggestions: Feel free to use comment in here. Please use thread for each discussions as possible.
FAQ
1. Plugin binary is WebAssembly. Does that mean I can write a plugin using other than rust?
Technically, it is correct. As long as you can generate WebAssembly binary satisfies SWC's transform interface, it'll work. However, there are some tricky challenges to making it actually work, such as:
If anyone can attempt this and making it work it'd be great!
2. I'm using
wasm
version of SWC. How does plugin work?Currently, wasm version of SWC doesn't support any plugin including javascript one as well.
(Updated Mar / 9 / 2022) : Refer #3934.
3. What'll happen to javascript plugin support?
First, It won't be deprecated in a day or two. If you have existing javascript plugins for the SWC, it'll work.
However there are known blockers for the javascript based plugins - notably performance - which blocks us to improve it further. This is the main reason new plugin interface has been implemented. I'm planning to post separate RFC for the migration plan for this - at this moment, I expect eventually javascript plugin will be considered as
legacy
.Known issues / discussions.
1. How to deal with possible breaking changes in AST
This is by far the biggest blocker for the stabilization of plugin interface. SWC chooses to expose AST directly to the plugin. This enables a lot of good things, but also AST becomes a part of the plugin interface contract. If swc/core changes AST - adding, removing, modifying types of AST - it'll be major breaking changes require plugin to be updated to follow those.
One positive thing is inevitable breaking change (
removing
,modifying
AST) does not happen frequently. We expect to add some more types somewhat more frequently than those. There is upstream issue filed for supporting it (rkyv/rkyv#164) and if we have those upstream support, it'll be relatively easy to make AST as stable interface contract.2. Plugin transform interface
Currently, plugin's main transform interface is defined as
which passes AST and each plugin's config (not the whole swcrc!). It may sufficient or not and we'd like to hear for opinions.
3. Config interface
It is unclear whether the current swcrc config interface is good enough. In particular, current config is slightly polymorphic by using the first tuple value as either package name or absolute path which can be confusing.
#3247 also tracks resolving support.
4. Plugin scaffolding package.json support ✅
Filed - #3548
5. plugin config module resolving issue ✅
This is different to #3247 - make existing resolver works out of the box with wasm plugin when package.json sets proper main entrypoint. Currently swc trying to resolve its optionaldependencies.
6. Additional context for the plugin ✅
Now plugin's transform entrypoint fn accepts 3rd param
context: String
.This is a stringified JSON for
Record<string, unknown>
type can contain arbitrary informations.Others
Beta Was this translation helpful? Give feedback.
All reactions