Skip to content

Commit

Permalink
feat: update
Browse files Browse the repository at this point in the history
  • Loading branch information
Allen Zhang (张涛) committed Oct 21, 2024
1 parent 077ad43 commit 48bb173
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 54 deletions.
1 change: 1 addition & 0 deletions plugins/swc-plugin-canyon/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/target
Cargo.lock
swc_plugin_canyon.wasm
5 changes: 4 additions & 1 deletion plugins/swc-plugin-canyon/package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
{
"name": "swc-plugin-canyon",
"version": "0.0.2-alpha.8",
"version": "0.0.2-alpha.9",
"description": "Canyon SWC plugin, for debugging",
"main": "swc_plugin_canyon.wasm",
"scripts": {
"prepack": "cargo build --release -p swc_plugin_canyon --target wasm32-wasi && cp ../../target/wasm32-wasi/release/swc_plugin_canyon.wasm . && ls && cat package.json"
},
"files": [
"swc_plugin_canyon.wasm"
],
"devDependencies": {
"@swc/cli": "0.4.1-nightly.20240914",
"@swc/core": "1.6.13",
Expand Down
114 changes: 61 additions & 53 deletions plugins/swc-plugin-canyon/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,67 +1,75 @@
#![allow(clippy::not_unsafe_ptr_arg_deref)]

use swc_common::{Spanned, SyntaxContext};
use swc_core::plugin::proxies::TransformPluginProgramMetadata;
use swc_ecma_ast::{Program, Script, Expr, ExprStmt, Stmt, Lit, Str, BinExpr, op, Ident};
use swc_ecma_visit::{as_folder, Fold, FoldWith, VisitMut, VisitMutWith};
use swc_plugin_macro::plugin_transform;
use swc_core::{
ecma::{
transforms::testing::test,
}
use swc_core::ecma::{
ast::{
Program, Module, Expr, Stmt, ModuleItem, Ident, Lit, KeyValueProp, Prop, PropName,
ObjectLit, ExprStmt, AssignExpr, AssignOp, MemberExpr, MemberProp,
},
transforms::testing::test_inline,
visit::{as_folder, FoldWith, VisitMut},
};
use swc_core::ecma::ast::{AssignTarget, IdentName};
use swc_core::ecma::visit::VisitMutWith;
use swc_core::plugin::{plugin_transform, proxies::TransformPluginProgramMetadata};

#[plugin_transform]
fn plugin(program: Program, metadata: TransformPluginProgramMetadata) -> Program {
// 确认插件被调用
println!("SWC 插件被调用");
pub struct TransformVisitor {
injected: bool, // 用于确保只注入一次
}

// 打印文件路径
if let Some(context) = metadata.get_context(&swc_core::plugin::metadata::TransformPluginMetadataContextKind::Filename) {
println!("当前文件的路径: {}", context);
} else {
println!("无法获取文件路径");
impl TransformVisitor {
pub fn new() -> Self {
Self { injected: false }
}

// 直接在每个文件末尾插入指定的代码
program.fold_with(&mut AddSimpleCode)
}

impl VisitMut for TransformVisitor {
fn visit_mut_module(&mut self, module: &mut Module) {
// 先调用父类的 visit_mut_module 方法
module.visit_mut_children_with(self);

// 在最后一行注入 window.canyon = {name: "zt"};
if !self.injected {
// 创建 window.canyon 的 MemberExpr
let window_canyon = Expr::Member(MemberExpr {
obj: Box::new(Expr::Ident(Ident::new("window".into(), Default::default(), Default::default()))),
prop: MemberProp::Ident(IdentName::from(Ident::new("__canyon__".into(), Default::default(), Default::default()))),
span: Default::default(),
});


struct AddSimpleCode;
// 默认为"",如果没有设置环境变量,则会报错
let dsn = std::env::var("dsn").unwrap_or_default();

impl Fold for AddSimpleCode {
fn fold_script(&mut self, mut script: Script) -> Script {
// 插入的代码是 console.log('hi');
let new_code = Expr::Call(swc_ecma_ast::CallExpr {
callee: swc_ecma_ast::Callee::Expr(Box::new(Expr::Member(swc_ecma_ast::MemberExpr {
obj: Box::new(Expr::Ident(Ident::new("console".into(), Default::default(), SyntaxContext::empty()))),
// prop: Box::new(Expr::Ident(Ident::new("log".into(), Default::default(), SyntaxContext::empty()))),
let object_lit = Expr::Object(ObjectLit {
props: vec![Prop::KeyValue(KeyValueProp {
key: PropName::Ident(IdentName::from(Ident::new("dsn".into(), Default::default(), Default::default()))),
value: Box::new(Expr::Lit(Lit::Str(dsn.into()))),
}).into()],
span: Default::default(),
prop: Default::default(),
}))),
args: vec![swc_ecma_ast::ExprOrSpread {
spread: None,
expr: Box::new(Expr::Lit(Lit::Str(Str {
value: "hi".into(),
span: Default::default(),
raw: None,
}))),
}],
span: Default::default(),
type_args: None,
ctxt: Default::default(),
});
});

// 构建表达式语句并插入
let new_item = Stmt::Expr(ExprStmt {
expr: Box::new(new_code),
span: Default::default(),
});
// 读取当前环境变量,把环境变量的dsn赋值给window.__canyon__.dsn
// 创建 window.canyon = {name: "zt"} 的赋值表达式
let assign_expr = AssignExpr {
left: AssignTarget::try_from(Box::new(window_canyon)).unwrap(), // 直接使用 Box<Expr>
op: AssignOp::Assign,
right: Box::new(object_lit),
span: Default::default(),
};

// 在脚本的末尾追加语句
script.body.push(new_item);
// 创建表达式语句
let assign_stmt = Stmt::Expr(ExprStmt {
expr: Box::new(Expr::Assign(assign_expr)),
span: Default::default(),
});

script
// 将新的语句添加到模块体中
module.body.push(ModuleItem::Stmt(assign_stmt));
self.injected = true; // 标记为已注入
}
}
}

/// SWC 插件的主函数
#[plugin_transform]
pub fn process_transform(program: Program, _metadata: TransformPluginProgramMetadata) -> Program {
program.fold_with(&mut as_folder(TransformVisitor::new()))
}

0 comments on commit 48bb173

Please sign in to comment.