Skip to content

Commit 448aedf

Browse files
LingyuCoderkdy1
andauthored
feat(prefresh): Add @swc/plugin-prefresh (#326)
Add `@swc/plugin-prefresh`, which is the SWC implementation of the [prefresh babel plugin](https://github.com/preactjs/prefresh/tree/main/packages/babel). Prefresh babel plugin is a forked equivalent of the react-refresh babel plugin difference being that we need a way to memoize createContext between HMR. And SWC has built-in React Refresh transformation, therefore, this plugin only implements the `createContext` processing part and need to be used with `jsc.transform.react.refresh`. For example: ```json { "jsc": { "experimental": { "plugins": [ [ // enable prefresh specific transformation "@swc/plugin-prefresh", { // the customizable preact name, default is `["preact", "preact/compat", "react"]` "library": ["preact-like-framework"] } ] ] }, "parser": { "jsx": true }, "transform": { "react": { "development": true, "refresh": true, // enable react refresh transformation } } } } ``` --------- Co-authored-by: Donny/강동윤 <[email protected]>
1 parent 7830879 commit 448aedf

36 files changed

+650
-2
lines changed

Cargo.lock

+26
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ members = [
1313
"packages/swc-confidential",
1414
"packages/swc-magic",
1515
"packages/transform-imports",
16+
"packages/prefresh",
1617
]
1718

1819

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ Plugins for SWC, written in Rust
1616
- [`swc-confidential`](packages/swc-confidential) for hiding sensitive strings in your code.
1717
- [`swc-magic`](packages/swc-magic) for building high-performance frameworks.
1818
- [`transform-imports`](packages/transform-imports)
19+
- [`prefresh`](packages/prefresh) for preact refresh transformation.

cspell.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"lightningcss",
77
"quasis",
88
"rustc",
9-
"swcrc"
9+
"swcrc",
10+
"prefresh"
1011
]
11-
}
12+
}

packages/prefresh/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
Cargo.lock

packages/prefresh/.npmignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
transform/
2+
tests/

packages/prefresh/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# @swc/plugin-prefresh

packages/prefresh/Cargo.toml

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[package]
2+
3+
description = "SWC plugin for preact refresh."
4+
5+
6+
authors = { workspace = true }
7+
edition = { workspace = true }
8+
homepage = { workspace = true }
9+
license = { workspace = true }
10+
name = "swc_plugin_prefresh"
11+
publish = false
12+
repository = { workspace = true }
13+
rust-version = { workspace = true }
14+
version = "0.1.0"
15+
16+
17+
[lib]
18+
crate-type = ["cdylib", "rlib"]
19+
20+
[dependencies]
21+
serde_json = "1.0.117"
22+
swc_common = { version = "0.34.3" }
23+
swc_core = { version = "0.96.0", features = ["ecma_plugin_transform"] }
24+
25+
swc_prefresh = { path = "./transform" }

packages/prefresh/README.md

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# @swc/plugin-prefresh
2+
3+
The SWC implementation of the [prefresh babel plugin](https://github.com/preactjs/prefresh/tree/main/packages/babel).
4+
5+
## Usage
6+
7+
Prefresh babel plugin is a forked equivalent of the react-refresh babel plugin difference being that we need a way to memoize createContext between HMR.
8+
9+
And SWC has built-in React Refresh transformation, therefore, this plugin only implements the `createContext` processing part and need to be used with `jsc.transform.react.refresh`.
10+
11+
.swcrc:
12+
13+
```json
14+
{
15+
"jsc": {
16+
"experimental": {
17+
"plugins": [
18+
[
19+
// enable prefresh specific transformation
20+
"@swc/plugin-prefresh",
21+
{
22+
// the customizable preact name, default is `["preact", "preact/compat", "react"]`
23+
"library": ["preact-like-framework"]
24+
}
25+
]
26+
]
27+
},
28+
"parser": {
29+
"jsx": true
30+
},
31+
"transform": {
32+
"react": {
33+
"development": true,
34+
"refresh": true, // enable react refresh transformation
35+
}
36+
}
37+
}
38+
}
39+
```

packages/prefresh/README.tmpl.md

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# @swc/plugin-prefresh
2+
3+
The SWC implementation of the [prefresh babel plugin](https://github.com/preactjs/prefresh/tree/main/packages/babel).
4+
5+
## Usage
6+
7+
Prefresh babel plugin is a forked equivalent of the react-refresh babel plugin difference being that we need a way to memoize createContext between HMR.
8+
9+
And SWC has built-in React Refresh transformation, therefore, this plugin only implements the `createContext` processing part and need to be used with `jsc.transform.react.refresh`.
10+
11+
.swcrc:
12+
13+
```json
14+
{
15+
"jsc": {
16+
"experimental": {
17+
"plugins": [
18+
[
19+
// enable prefresh specific transformation
20+
"@swc/plugin-prefresh",
21+
{
22+
// the customizable preact name, default is `["preact", "preact/compat", "react"]`
23+
"library": ["preact-like-framework"]
24+
}
25+
]
26+
]
27+
},
28+
"parser": {
29+
"jsx": true
30+
},
31+
"transform": {
32+
"react": {
33+
"development": true,
34+
"refresh": true, // enable react refresh transformation
35+
}
36+
}
37+
}
38+
}
39+
```
40+
41+
${CHANGELOG}

packages/prefresh/package.json

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"name": "@swc/plugin-prefresh",
3+
"version": "2.0.7",
4+
"description": "SWC plugin for preact refresh",
5+
"main": "swc_plugin_prefresh.wasm",
6+
"scripts": {
7+
"prepack": "cargo build --release -p swc_plugin_prefresh --target wasm32-wasi && cp ../../target/wasm32-wasi/release/swc_plugin_prefresh.wasm ."
8+
},
9+
"homepage": "https://swc.rs",
10+
"repository": {
11+
"type": "git",
12+
"url": "+https://github.com/swc-project/plugins.git"
13+
},
14+
"bugs": {
15+
"url": "https://github.com/swc-project/plugins/issues"
16+
},
17+
"author": "강동윤 <[email protected]>",
18+
"keywords": [],
19+
"license": "Apache-2.0",
20+
"preferUnplugged": true,
21+
"dependencies": {
22+
"@swc/counter": "^0.1.3"
23+
}
24+
}

packages/prefresh/src/lib.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#![allow(clippy::not_unsafe_ptr_arg_deref)]
2+
3+
use swc_common::{SourceMapper, Spanned};
4+
use swc_core::{
5+
ecma::{ast::Program, visit::FoldWith},
6+
plugin::{plugin_transform, proxies::TransformPluginProgramMetadata},
7+
};
8+
#[plugin_transform]
9+
fn swc_plugin(program: Program, data: TransformPluginProgramMetadata) -> Program {
10+
let config = serde_json::from_str::<Option<swc_prefresh::PrefreshPluginConfig>>(
11+
&data
12+
.get_transform_plugin_config()
13+
.expect("failed to get plugin config for prefresh plugin"),
14+
)
15+
.expect("invalid packages")
16+
.unwrap_or_default();
17+
18+
let source_map = std::sync::Arc::new(data.source_map);
19+
let pos = source_map.lookup_char_pos(program.span().lo);
20+
let hash = format!("{:x}", pos.file.src_hash);
21+
22+
program.fold_with(&mut swc_prefresh::swc_prefresh(config, hash))
23+
}
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
[package]
2+
3+
description = "AST Transforms for prefresh plugin"
4+
5+
name = "swc_prefresh"
6+
7+
authors = { workspace = true }
8+
edition = { workspace = true }
9+
homepage = { workspace = true }
10+
license = { workspace = true }
11+
repository = { workspace = true }
12+
rust-version = { workspace = true }
13+
version = "0.1.0"
14+
15+
[dependencies]
16+
serde = { version = "1", features = ["derive"] }
17+
swc_atoms = "0.6.7"
18+
swc_common = "0.34.3"
19+
swc_core = { version = "0.96.0", features = ["ecma_quote"] }
20+
swc_ecma_ast = "0.115.1"
21+
swc_ecma_visit = "0.101.0"
22+
23+
[dev-dependencies]
24+
swc_ecma_parser = "0.146.7"
25+
swc_ecma_transforms_base = "0.140.1"
26+
swc_ecma_transforms_testing = "0.143.1"
27+
testing = "0.36.0"

0 commit comments

Comments
 (0)