-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Finish the change import statement feature #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
029dd6f
chore: Init the plugin_optimize_package_import project
b03dc15
feat: Finished the change package import plugin
1d32d1e
chore: Update the cargo.lock file
c7e9f51
chore: Update the dependencies configs
3c251c7
refactor: Improve code's performance
a5ad414
refactor: Use macro function to simplify code
b1a9527
fix: Statements are not follow the original order
96228be
chore: Resolve conflict
bce6720
chore: add test case sample
ClarkXia a6ddd46
feat: Finished the all functions
a6d2aaf
refactor: Delete verbose code
1a1ce33
refactor: Rename directory and resolve issues
3b65160
chore: Resolve conflictions
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -196,4 +196,5 @@ $RECYCLE.BIN/ | |
*.node | ||
|
||
.rspack_crates/ | ||
node_modules/ | ||
node_modules/ | ||
.idea/ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/target | ||
^target/ | ||
target |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
[package] | ||
name = "swc_plugin_change_package_import" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[lib] | ||
crate-type = ["cdylib", "rlib"] | ||
|
||
[profile.release] | ||
lto = true | ||
|
||
[dependencies] | ||
serde = { workspace = true } | ||
swc_core = { workspace = true, features = [ | ||
"ecma_plugin_transform", | ||
"ecma_ast", | ||
"common", | ||
"ecma_utils", | ||
] } | ||
|
||
[dev-dependencies] | ||
testing = "0.35.11" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"name": "plugin_optimize_package_import", | ||
"version": "0.1.0", | ||
"description": "", | ||
"author": "", | ||
"license": "ISC", | ||
"keywords": ["swc-plugin"], | ||
"main": "target/wasm32-wasi/release/plugin_optimize_package_import.wasm", | ||
"scripts": { | ||
"prepublishOnly": "cargo build-wasi --release" | ||
}, | ||
"files": [], | ||
"preferUnplugged": true | ||
} |
207 changes: 207 additions & 0 deletions
207
crates/swc_plugin_change_package_import/src/change_package_import.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
use crate::config::{Config, ImportType}; | ||
use swc_core::{ | ||
common::{ | ||
DUMMY_SP, | ||
util::{ | ||
take::Take | ||
}, | ||
}, | ||
ecma::{ | ||
ast::*, | ||
atoms::{JsWord}, | ||
visit::{VisitMut, VisitMutWith}, | ||
utils::{quote_str, swc_ecma_ast::ImportSpecifier}, | ||
}, | ||
}; | ||
|
||
pub struct ModuleImportVisitor { | ||
// 用户配置 | ||
pub options: Vec<Config>, | ||
// 全新生成的导入声明 | ||
new_stmts: Vec<ModuleItem>, | ||
} | ||
|
||
impl ModuleImportVisitor { | ||
pub fn new(options: Vec<Config>) -> Self { | ||
Self { | ||
options, | ||
new_stmts: vec![], | ||
} | ||
} | ||
} | ||
|
||
impl VisitMut for ModuleImportVisitor { | ||
fn visit_mut_import_decl(&mut self, import_decl: &mut ImportDecl) { | ||
import_decl.visit_mut_children_with(self); | ||
|
||
for option in &self.options { | ||
match option { | ||
Config::LiteralConfig(src) => { | ||
if is_hit_rule(import_decl, option) { | ||
for specifier in &import_decl.specifiers { | ||
match specifier { | ||
ImportSpecifier::Named(named_import_spec) => { | ||
let mut import_new_src = src.clone(); | ||
import_new_src.push_str("/"); | ||
import_new_src.push_str(&get_import_module_name(named_import_spec)); | ||
|
||
self.new_stmts.push(create_default_import_decl(import_new_src, named_import_spec.local.clone())); | ||
} | ||
_ => () | ||
} | ||
} | ||
// 清空当前导入声明,否则会被作为有效的声明添加至 new_stmts 中 | ||
import_decl.take(); | ||
break; | ||
} | ||
} | ||
Config::SpecificConfig(config) => { | ||
if is_hit_rule(import_decl, option) { | ||
let target_fields: Vec<&String> = config.map.keys().clone().collect(); | ||
let mut named_import_spec_copy = import_decl.clone(); | ||
|
||
// 获取未命中规则的导入声明 | ||
named_import_spec_copy.specifiers = named_import_spec_copy.specifiers.into_iter().filter(|specifier| { | ||
match specifier { | ||
ImportSpecifier::Named(named_import_spec) => { | ||
let import_object_name = get_import_module_name(named_import_spec); | ||
!target_fields.contains(&&import_object_name) | ||
} | ||
_ => true | ||
} | ||
}).collect::<Vec<_>>(); | ||
|
||
if named_import_spec_copy.specifiers.len() != 0 { | ||
self.new_stmts.push(ModuleItem::ModuleDecl(ModuleDecl::Import(named_import_spec_copy))); | ||
} | ||
|
||
for (target, rules) in config.map.iter() { | ||
for specifier in &import_decl.specifiers { | ||
match specifier { | ||
ImportSpecifier::Named(named_import_spec) => { | ||
let import_object_name = get_import_module_name(named_import_spec); | ||
if target == &import_object_name { | ||
let new_import_decl: ModuleItem; | ||
if rules.import_type.is_none() || match rules.import_type.as_ref().unwrap() { | ||
ImportType::Default => true, | ||
_ => false | ||
} { | ||
// Default import mode | ||
new_import_decl = create_default_import_decl(rules.to.to_string(), named_import_spec.local.clone()); | ||
} else { | ||
// Named import mode | ||
let mut named_import_spec_copy = named_import_spec.clone(); | ||
|
||
if rules.name.is_some() { | ||
named_import_spec_copy.imported = Some(ModuleExportName::Str(Str { | ||
span: named_import_spec.span, | ||
value: rules.name.clone().unwrap().into(), | ||
raw: Some(rules.name.clone().unwrap().clone().into()), | ||
})) | ||
} | ||
|
||
new_import_decl = create_named_import_decl(rules.to.to_string(), vec![ImportSpecifier::Named(named_import_spec_copy)]); | ||
} | ||
|
||
self.new_stmts.push(new_import_decl); | ||
} | ||
} | ||
_ => () | ||
} | ||
} | ||
} | ||
import_decl.take(); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
if !is_empty_decl(import_decl) { | ||
self.new_stmts.push(wrap_with_moudle_item(import_decl.clone())); | ||
} | ||
} | ||
|
||
fn visit_mut_module_item(&mut self, n: &mut ModuleItem) { | ||
n.visit_mut_children_with(self); | ||
|
||
if !n.is_module_decl() { | ||
self.new_stmts.push(n.clone()); | ||
} | ||
} | ||
|
||
fn visit_mut_module_items(&mut self, stmts: &mut Vec<ModuleItem>) { | ||
stmts.visit_mut_children_with(self); | ||
|
||
*stmts = self.new_stmts.clone(); | ||
} | ||
} | ||
|
||
fn is_hit_rule(cur_import: &ImportDecl, rule: &Config) -> bool { | ||
match rule { | ||
Config::LiteralConfig(s) => { | ||
if cur_import.src.value == JsWord::from(s.clone()) { | ||
return true; | ||
} | ||
false | ||
} | ||
Config::SpecificConfig(s) => { | ||
if cur_import.src.value == JsWord::from(s.name.clone()) { | ||
return true; | ||
} | ||
false | ||
} | ||
} | ||
} | ||
|
||
fn is_empty_decl(decl: &ImportDecl) -> bool { | ||
decl.specifiers.len() == 0 && decl.src.value == JsWord::from("".to_string()) | ||
} | ||
|
||
fn get_import_module_name(named_import_spec: &ImportNamedSpecifier) -> String { | ||
if named_import_spec.imported.is_none() { | ||
(&named_import_spec.local.sym).to_string() | ||
} else { | ||
match &named_import_spec.imported.clone().unwrap() { | ||
ModuleExportName::Ident(ident) => { | ||
(&ident.sym).to_string() | ||
} | ||
ModuleExportName::Str(str) => { | ||
(&str.value).to_string() | ||
} | ||
} | ||
} | ||
} | ||
|
||
fn create_default_import_decl(src: String, local: Ident) -> ModuleItem { | ||
wrap_with_moudle_item( | ||
ImportDecl { | ||
src: Box::new(quote_str!(src)), | ||
specifiers: vec![ImportSpecifier::Default( | ||
ImportDefaultSpecifier { | ||
span: DUMMY_SP, | ||
local, | ||
} | ||
)], | ||
span: DUMMY_SP, | ||
type_only: false, | ||
with: None, | ||
} | ||
) | ||
} | ||
|
||
fn create_named_import_decl(src: String, specifiers: Vec<ImportSpecifier>) -> ModuleItem { | ||
wrap_with_moudle_item( | ||
ImportDecl { | ||
src: Box::new(quote_str!(src)), | ||
specifiers, | ||
span: DUMMY_SP, | ||
type_only: false, | ||
with: None, | ||
} | ||
) | ||
} | ||
|
||
fn wrap_with_moudle_item(import_decl: ImportDecl) -> ModuleItem { | ||
ModuleItem::ModuleDecl(ModuleDecl::Import(import_decl)) | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use std::collections::HashMap; | ||
|
||
#[derive(Debug)] | ||
pub enum Config { | ||
/// 配置: | ||
/// ```rs | ||
/// Config::LiteralConfig(String::from("antd")) | ||
/// ``` | ||
/// 效果: | ||
/// ```js | ||
/// import { Button } from "antd"; | ||
/// // ---> | ||
/// import Button from "antd/Button"; | ||
/// ``` | ||
LiteralConfig(String), | ||
/// 配置: | ||
/// ```rs | ||
/// Config::SpecificConfig( | ||
// SpecificConfigs { | ||
// name: String::from("ice"), | ||
// map: HashMap::from([ | ||
// ( | ||
// "a".to_string(), | ||
// MapProperty { | ||
// to: String::from("@ice/x/y"), | ||
// import_type: None, | ||
// name: None, | ||
// } | ||
// ), | ||
// ]), | ||
// } | ||
// ), | ||
/// ``` | ||
/// 效果: | ||
/// ```js | ||
/// import { a } from "ice"; | ||
/// // ---> | ||
/// import a from "@ice/x/y"; | ||
/// ``` | ||
/// | ||
/// 更多配置请参考[文档](https://alidocs.dingtalk.com/i/nodes/20eMKjyp810mMdK4Ho1LpqX7JxAZB1Gv?utm_scene=team_space) | ||
SpecificConfig(SpecificConfigs), | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct SpecificConfigs { | ||
pub name: String, | ||
pub map: HashMap<String, MapProperty>, | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct MapProperty { | ||
pub to: String, | ||
pub import_type: Option<ImportType>, | ||
pub name: Option<String>, | ||
} | ||
|
||
#[derive(Debug, PartialEq)] | ||
pub enum ImportType { | ||
Named, | ||
Default, | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
mod config; | ||
mod change_package_import; | ||
|
||
pub use config::*; | ||
pub use change_package_import::*; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.