Skip to content

Commit

Permalink
feat(transform-imports): Transform export * (#270)
Browse files Browse the repository at this point in the history
Closes #246
  • Loading branch information
kdy1 authored Feb 26, 2024
1 parent 0786ba7 commit 02f415f
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 143 deletions.
3 changes: 2 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/transform-imports/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @swc/plugin-transform-imports

## 1.5.119

### Patch Changes

- 1509e60: Support export all

## 1.5.118

### Patch Changes
Expand Down
6 changes: 6 additions & 0 deletions packages/transform-imports/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@

# @swc/plugin-transform-imports

## 1.5.119

### Patch Changes

- 1509e60: Support export all

## 1.5.118

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/transform-imports/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@swc/plugin-transform-imports",
"version": "1.5.118",
"version": "1.5.119",
"description": "SWC plugin for https://www.npmjs.com/package/babel-plugin-transform-imports",
"main": "swc_plugin_transform_imports.wasm",
"scripts": {
Expand Down
3 changes: 2 additions & 1 deletion packages/transform-imports/transform/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = "2021"
license = "Apache-2.0"
name = "modularize_imports"
repository = "https://github.com/swc-project/plugins.git"
version = "0.68.6"
version = "0.68.7"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand All @@ -15,6 +15,7 @@ handlebars = "4.2.1"
once_cell = "1.13.0"
regex = "1.5"
serde = "1"
swc_atoms = "0.6.5"
swc_cached = "0.3.19"
swc_common = "0.33.17"
swc_ecma_ast = "0.112.2"
Expand Down
242 changes: 102 additions & 140 deletions packages/transform-imports/transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use handlebars::{Context, Handlebars, Helper, HelperResult, Output, RenderContex
use once_cell::sync::Lazy;
use regex::{Captures, Regex};
use serde::{Deserialize, Serialize};
use swc_atoms::Atom;
use swc_cached::regex::CachedRegex;
use swc_common::DUMMY_SP;
use swc_ecma_ast::{ImportDecl, ImportSpecifier, ModuleExportName, *};
Expand Down Expand Up @@ -66,6 +67,84 @@ enum CtxData<'a> {
}

impl<'a> Rewriter<'a> {
fn new_path(&self, name_str: Option<&str>) -> Atom {
let mut ctx: HashMap<&str, CtxData> = HashMap::new();
ctx.insert("matches", CtxData::Array(&self.group[..]));
if let Some(name_str) = name_str {
ctx.insert("member", CtxData::Plain(name_str));
}

let new_path = match &self.config.transform {
Transform::String(s) => self.renderer.render_template(s, &ctx).unwrap_or_else(|e| {
panic!("error rendering template for '{}': {}", self.key, e);
}),
Transform::Vec(v) => {
let mut result: Option<String> = None;

// We iterate over the items to find the first match
v.iter().any(|(k, val)| {
let mut key = k.to_string();
if !key.starts_with('^') && !key.ends_with('$') {
key = format!("^{}$", key);
}

// Create a clone of the context, as we need to insert the
// `memberMatches` key for each key we try.
let mut ctx_with_member_matches: HashMap<&str, CtxData> = HashMap::new();
ctx_with_member_matches.insert("matches", CtxData::Array(&self.group[..]));

if let Some(name_str) = name_str {
ctx_with_member_matches.insert("member", CtxData::Plain(name_str));
}
let regex = CachedRegex::new(&key).expect("transform-imports: invalid regex");
if let Some(name_str) = name_str {
let group = regex.captures(name_str);

if let Some(group) = group {
let group = group
.iter()
.map(|x| x.map(|x| x.as_str()).unwrap_or_default())
.collect::<Vec<&str>>()
.clone();
ctx_with_member_matches
.insert("memberMatches", CtxData::Array(&group[..]));

result = Some(
self.renderer
.render_template(val, &ctx_with_member_matches)
.unwrap_or_else(|e| {
panic!(
"error rendering template for '{}': {}",
self.key, e
);
}),
);

true
} else {
false
}
} else {
false
}
});

if let Some(result) = result {
result
} else {
panic!(
"missing transform for import '{:?}' of package '{}'",
name_str, self.key
);
}
}
};

let new_path = DUP_SLASH_REGEX.replace_all(&new_path, |_: &Captures| "/");

new_path.into()
}

fn rewrite_export(&self, old_decl: &NamedExport) -> Vec<NamedExport> {
if old_decl.type_only || old_decl.with.is_some() {
return vec![old_decl.clone()];
Expand All @@ -82,76 +161,7 @@ impl<'a> Rewriter<'a> {
ModuleExportName::Str(x) => x.value.as_ref(),
};

let mut ctx: HashMap<&str, CtxData> = HashMap::new();
ctx.insert("matches", CtxData::Array(&self.group[..]));
ctx.insert("member", CtxData::Plain(name_str));

let new_path = match &self.config.transform {
Transform::String(s) => {
self.renderer.render_template(s, &ctx).unwrap_or_else(|e| {
panic!("error rendering template for '{}': {}", self.key, e);
})
}
Transform::Vec(v) => {
let mut result: Option<String> = None;

// We iterate over the items to find the first match
v.iter().any(|(k, val)| {
let mut key = k.to_string();
if !key.starts_with('^') && !key.ends_with('$') {
key = format!("^{}$", key);
}

// Create a clone of the context, as we need to insert the
// `memberMatches` key for each key we try.
let mut ctx_with_member_matches: HashMap<&str, CtxData> =
HashMap::new();
ctx_with_member_matches
.insert("matches", CtxData::Array(&self.group[..]));
ctx_with_member_matches.insert("member", CtxData::Plain(name_str));

let regex = CachedRegex::new(&key)
.expect("transform-imports: invalid regex");
let group = regex.captures(name_str);

if let Some(group) = group {
let group = group
.iter()
.map(|x| x.map(|x| x.as_str()).unwrap_or_default())
.collect::<Vec<&str>>()
.clone();
ctx_with_member_matches
.insert("memberMatches", CtxData::Array(&group[..]));

result = Some(
self.renderer
.render_template(val, &ctx_with_member_matches)
.unwrap_or_else(|e| {
panic!(
"error rendering template for '{}': {}",
self.key, e
);
}),
);

true
} else {
false
}
});

if let Some(result) = result {
result
} else {
panic!(
"missing transform for import '{:?}' of package '{}'",
named_spec.orig, self.key
);
}
}
};

let new_path = DUP_SLASH_REGEX.replace_all(&new_path, |_: &Captures| "/");
let new_path = self.new_path(Some(name_str));
let specifier = if self.config.skip_default_conversion {
ExportSpecifier::Named(named_spec.clone())
} else {
Expand Down Expand Up @@ -210,76 +220,7 @@ impl<'a> Rewriter<'a> {
})
.unwrap_or_else(|| named_spec.local.as_ref());

let mut ctx: HashMap<&str, CtxData> = HashMap::new();
ctx.insert("matches", CtxData::Array(&self.group[..]));
ctx.insert("member", CtxData::Plain(name_str));

let new_path = match &self.config.transform {
Transform::String(s) => {
self.renderer.render_template(s, &ctx).unwrap_or_else(|e| {
panic!("error rendering template for '{}': {}", self.key, e);
})
}
Transform::Vec(v) => {
let mut result: Option<String> = None;

// We iterate over the items to find the first match
v.iter().any(|(k, val)| {
let mut key = k.to_string();
if !key.starts_with('^') && !key.ends_with('$') {
key = format!("^{}$", key);
}

// Create a clone of the context, as we need to insert the
// `memberMatches` key for each key we try.
let mut ctx_with_member_matches: HashMap<&str, CtxData> =
HashMap::new();
ctx_with_member_matches
.insert("matches", CtxData::Array(&self.group[..]));
ctx_with_member_matches.insert("member", CtxData::Plain(name_str));

let regex = CachedRegex::new(&key)
.expect("transform-imports: invalid regex");
let group = regex.captures(name_str);

if let Some(group) = group {
let group = group
.iter()
.map(|x| x.map(|x| x.as_str()).unwrap_or_default())
.collect::<Vec<&str>>()
.clone();
ctx_with_member_matches
.insert("memberMatches", CtxData::Array(&group[..]));

result = Some(
self.renderer
.render_template(val, &ctx_with_member_matches)
.unwrap_or_else(|e| {
panic!(
"error rendering template for '{}': {}",
self.key, e
);
}),
);

true
} else {
false
}
});

if let Some(result) = result {
result
} else {
panic!(
"missing transform for import '{}' of package '{}'",
named_spec.local, self.key
);
}
}
};

let new_path = DUP_SLASH_REGEX.replace_all(&new_path, |_: &Captures| "/");
let new_path = self.new_path(Some(name_str));
let specifier = if self.config.skip_default_conversion {
ImportSpecifier::Named(named_spec.clone())
} else {
Expand Down Expand Up @@ -370,6 +311,27 @@ impl Fold for FoldImports {
}
None => new_items.push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(decl))),
},

ModuleItem::ModuleDecl(ModuleDecl::ExportAll(e @ ExportAll { .. })) => {
match self.should_rewrite(&e.src.value) {
Some(rewriter) => {
let rewritten = rewriter.new_path(None);
new_items.push(ModuleItem::ModuleDecl(ModuleDecl::ExportAll(
ExportAll {
src: Box::new(Str {
span: e.src.span,
value: rewritten,
raw: None,
}),
..e
},
)));
}
None => {
new_items.push(ModuleItem::ModuleDecl(ModuleDecl::ExportAll(e)));
}
}
}
_ => {
new_items.push(item);
}
Expand Down

0 comments on commit 02f415f

Please sign in to comment.