Skip to content

Commit

Permalink
[chore] Use rspack
Browse files Browse the repository at this point in the history
  • Loading branch information
mantou132 committed Dec 14, 2024
1 parent d760e07 commit 105fddd
Show file tree
Hide file tree
Showing 25 changed files with 532 additions and 577 deletions.
2 changes: 1 addition & 1 deletion crates/swc-plugin-gem/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "swc-plugin-gem",
"version": "0.1.5",
"version": "0.1.6",
"description": "swc plugin for Gem",
"keywords": [
"swc-plugin",
Expand Down
74 changes: 48 additions & 26 deletions crates/swc-plugin-gem/src/visitors/hmr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ use swc_core::{
quote,
};
use swc_ecma_ast::{
BlockStmt, BlockStmtOrExpr, Callee, Class, ClassMember, ClassMethod, ClassProp, Expr,
ExprOrSpread, Function, Ident, IdentName, Lit, MemberExpr, MemberProp, ModuleItem, Param,
PropName, ThisExpr,
ArrowExpr, BlockStmt, BlockStmtOrExpr, Callee, Class, ClassMember, ClassMethod, ClassProp,
Expr, ExprOrSpread, Function, Ident, IdentName, Lit, MemberExpr, MemberProp, ModuleItem, Param,
Pat, PropName, RestPat, ThisExpr,
};

static DASH_REG: Lazy<Regex> = Lazy::new(|| Regex::new(r"-").unwrap());
Expand Down Expand Up @@ -98,6 +98,15 @@ fn gen_shadow_member(
})
}

fn gen_proxy_arg() -> Vec<Pat> {
vec![Pat::Rest(RestPat {
arg: Box::new(Pat::Ident("args".into())),
dot3_token: DUMMY_SP,
span: DUMMY_SP,
type_ann: None,
})]
}

fn gen_proxy_body(shadow_ident: &IdentName) -> BlockStmt {
let this_expr = Expr::Member(MemberExpr {
obj: Box::new(Expr::This(ThisExpr { span: DUMMY_SP })),
Expand All @@ -107,25 +116,50 @@ fn gen_proxy_body(shadow_ident: &IdentName) -> BlockStmt {
BlockStmt {
stmts: vec![quote!(
"
return $expr.bind(this)(...arguments);
return $expr.bind(this)(...args);
" as Stmt,
expr: Expr = this_expr
)],
..Default::default()
}
}

fn replace_to_proxy_function(
func: &mut Function,
shadow_ident: &IdentName,
) -> (Option<BlockStmt>, Vec<Param>) {
(
mem::replace(&mut func.body, gen_proxy_body(&shadow_ident).into()),
mem::replace(
&mut func.params,
gen_proxy_arg().drain(..).map(|x| x.into()).collect(),
),
)
}

fn replace_to_proxy_arrow(
func: &mut ArrowExpr,
shadow_ident: &IdentName,
) -> (Box<BlockStmtOrExpr>, Vec<Param>) {
(
mem::replace(
&mut func.body,
Box::new(BlockStmtOrExpr::BlockStmt(gen_proxy_body(&shadow_ident))),
),
mem::replace(&mut func.params, gen_proxy_arg())
.drain(..)
.map(|x| x.into())
.collect(),
)
}

fn transform_fn(node: ClassMember, key: &str) -> (ClassMember, Option<ClassMember>) {
// TODO: 支持计算属性名
match node {
ClassMember::Method(mut method) => {
if let Some(origin_ident) = method.key.as_ident() {
let shadow_ident = get_shadow_ident(origin_ident, key, false);
let body = mem::replace(
&mut method.function.body,
gen_proxy_body(&shadow_ident).into(),
);
let params = method.function.params.drain(..).collect();
let (body, params) = replace_to_proxy_function(&mut method.function, &shadow_ident);
let is_async = method.function.is_async;
(
ClassMember::Method(ClassMethod { ..method }),
Expand All @@ -145,11 +179,7 @@ fn transform_fn(node: ClassMember, key: &str) -> (ClassMember, Option<ClassMembe
let origin_ident = IdentName::new(method.key.name, DUMMY_SP);
let private_ident = PropName::Ident(get_private_ident(&origin_ident, key));
let shadow_ident = get_shadow_ident(&origin_ident, key, true);
let body = mem::replace(
&mut method.function.body,
gen_proxy_body(&shadow_ident).into(),
);
let params = method.function.params.drain(..).collect();
let (body, params) = replace_to_proxy_function(&mut method.function, &shadow_ident);
let is_async = method.function.is_async;
(
ClassMember::Method(ClassMethod {
Expand All @@ -174,14 +204,10 @@ fn transform_fn(node: ClassMember, key: &str) -> (ClassMember, Option<ClassMembe
}
ClassMember::ClassProp(mut prop) => {
if let Some(ref mut v) = prop.value {
if let Some(func) = v.as_mut_arrow() {
if let Some(mut func) = v.as_mut_arrow() {
let origin_ident = prop.key.as_ident().unwrap();
let shadow_ident = get_shadow_ident(origin_ident, key, false);
let body = mem::replace(
&mut func.body,
Box::new(BlockStmtOrExpr::BlockStmt(gen_proxy_body(&shadow_ident))),
);
let params = func.params.drain(..).map(|x| x.into()).collect();
let (body, params) = replace_to_proxy_arrow(&mut func, &shadow_ident);
let is_async = func.is_async;
if let BlockStmtOrExpr::BlockStmt(body) = *body {
return (
Expand All @@ -203,13 +229,9 @@ fn transform_fn(node: ClassMember, key: &str) -> (ClassMember, Option<ClassMembe
let origin_ident = IdentName::new(prop.key.name, DUMMY_SP);
let private_ident = PropName::Ident(get_private_ident(&origin_ident, key));
if let Some(ref mut v) = prop.value {
if let Some(func) = v.as_mut_arrow() {
if let Some(mut func) = v.as_mut_arrow() {
let shadow_ident = get_shadow_ident(&origin_ident, key, true);
let body = mem::replace(
&mut func.body,
Box::new(BlockStmtOrExpr::BlockStmt(gen_proxy_body(&shadow_ident))),
);
let params = func.params.drain(..).map(|x| x.into()).collect();
let (body, params) = replace_to_proxy_arrow(&mut func, &shadow_ident);
let is_async = func.is_async;
if let BlockStmtOrExpr::BlockStmt(body) = *body {
return (
Expand Down
9 changes: 5 additions & 4 deletions crates/swc-plugin-gem/tests/fixture/hmr/input.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
// @ts-nocheck
@customElement('my-element')
class MyElement extends GemElement {
@emitter change;
@effect([])
method(arg) {
console.log('method');
}
@effect([])
field = (arg) => {
console.log('field');
}
};
@effect([])
#method(arg) {
console.log('#method');
}
@effect([])
@effect((i) => [i.#field])
#field = (arg) => {
console.log('#field');
}
};
#content;
}
}
19 changes: 10 additions & 9 deletions crates/swc-plugin-gem/tests/fixture/hmr/output.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
// @ts-nocheck
@customElement('my-element')
class MyElement extends GemElement {
@emitter change;
_hmr_public_my_element_method(arg) {
console.log('method');
}
@effect([])
method() {
return this._hmr_public_my_element_method.bind(this)(...arguments);
method(...args) {
return this._hmr_public_my_element_method.bind(this)(...args);
}
_hmr_public_my_element_field(arg) {
console.log('field');
}
@effect([])
field = () => {
return this._hmr_public_my_element_field.bind(this)(...arguments);
field = (...args) => {
return this._hmr_public_my_element_field.bind(this)(...args);
};
_hmr_private_my_element_method(arg) {
console.log('#method');
}
@effect([])
_private_my_element_method() {
return this._hmr_private_my_element_method.bind(this)(...arguments);
_private_my_element_method(...args) {
return this._hmr_private_my_element_method.bind(this)(...args);
}
_hmr_private_my_element_field(arg) {
console.log('#field');
}
@effect([])
_private_my_element_field = () => {
return this._hmr_private_my_element_field.bind(this)(...arguments);
@effect((i) => [i._private_my_element_field])
_private_my_element_field = (...args) => {
return this._hmr_private_my_element_field.bind(this)(...args);
};
_private_my_element_content;
}
6 changes: 3 additions & 3 deletions packages/gem-devtools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"description": "Gem devtools",
"scripts": {
"update:version": "node ./scripts/update.js",
"serve": "vite",
"build": "vite build",
"serve": "rsbuild dev",
"build": "rsbuild build",
"watch": "pnpm build --watch",
"build:zip": "pnpm build && web-ext build",
"browser": "web-ext run --target=chromium --target=firefox-desktop",
Expand All @@ -18,8 +18,8 @@
},
"devDependencies": {
"@gemjs/config": "^2.1.0",
"@rsbuild/core": "^1.1.10",
"@types/webextension-polyfill": "^0.10.7",
"vite": "^5.2.10",
"web-ext": "^7.8.0"
},
"author": "mantou132",
Expand Down
43 changes: 43 additions & 0 deletions packages/gem-devtools/rsbuild.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// swc 还是谁有 bug,装饰器没有生效

import { defineConfig } from '@rsbuild/core';

export default defineConfig(({}) => ({
html: {
template: './src/template.html',
},
source: {
// 触发更新
preEntry: './src/manifest.json',
entry: {
test: './src/test.ts',
sidebarpanel: './src/sidebarpanel.ts',
devtools: './src/devtools.ts',
// not support module
content: {
import: './src/content.ts',
html: false,
},
},
},
output: {
copy: [{ from: './src/manifest.json' }],
distPath: {
root: 'extension',
js: '.',
},
filename: {
js: '[name].js',
},
dataUriLimit: 0,
sourceMap: true,
},
performance: {
chunkSplit: {},
},
resolve: {
alias: {
src: '',
},
},
}));
24 changes: 24 additions & 0 deletions packages/gem-devtools/src/chrome-polyfill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const getAny = () => {
// constructable
function anonymous() {
return getAny();
}
Object.defineProperties(anonymous, {
length: { writable: true },
name: { writable: true },
});
return new Proxy(anonymous, {
get(target, key) {
if (key === Symbol.toPrimitive) return () => '';
return target[key] || (target[key] = getAny());
},
});
};
globalThis.chrome = globalThis.browser = new Proxy(
{},
{
get() {
return getAny();
},
},
);
7 changes: 0 additions & 7 deletions packages/gem-devtools/src/content.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
// 作为静态资源输出
// eslint-disable-next-line import/no-duplicates
import './manifest.json?url';
// 实时更新
// eslint-disable-next-line import/no-duplicates
import './manifest.json';

type DevToolsHookStore = {
customElementMap: Map<string, CustomElementConstructor>;
currentElementsMap: Map<string, Element>;
Expand Down
1 change: 0 additions & 1 deletion packages/gem-devtools/src/devtools.html

This file was deleted.

1 change: 0 additions & 1 deletion packages/gem-devtools/src/sidebarpanel.html

This file was deleted.

4 changes: 4 additions & 0 deletions packages/gem-devtools/src/template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<!doctype html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no" />
</head>
30 changes: 0 additions & 30 deletions packages/gem-devtools/src/test.html

This file was deleted.

1 change: 1 addition & 0 deletions packages/gem-devtools/src/test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import './chrome-polyfill';
import { html, render } from '@mantou/gem';

import { panelStore, PanelStore } from './store';
Expand Down
Loading

0 comments on commit 105fddd

Please sign in to comment.