-
Notifications
You must be signed in to change notification settings - Fork 27.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement
named_import_transform
(#54530)
This is the first step to enable the automatic "modularize imports" optimization for some libraries. It transforms named imports like `import { A, B, C as F } from 'foo'` to a special loader string: `import { A, B, C as F } from "barrel-optimize-loader?names=A,B,C!foo"`. In a follow-up PR we'll apply corresponding optimization with another SWC transformer.
- Loading branch information
Showing
13 changed files
with
165 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
83 changes: 83 additions & 0 deletions
83
packages/next-swc/crates/core/src/named_import_transform.rs
This file contains 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,83 @@ | ||
use serde::Deserialize; | ||
use turbopack_binding::swc::core::{ | ||
common::DUMMY_SP, | ||
ecma::{ast::*, visit::Fold}, | ||
}; | ||
|
||
#[derive(Clone, Debug, Deserialize)] | ||
pub struct Config { | ||
pub packages: Vec<String>, | ||
} | ||
|
||
pub fn named_import_transform(config: Config) -> impl Fold { | ||
NamedImportTransform { | ||
packages: config.packages, | ||
} | ||
} | ||
|
||
#[derive(Debug, Default)] | ||
struct NamedImportTransform { | ||
packages: Vec<String>, | ||
} | ||
|
||
impl Fold for NamedImportTransform { | ||
fn fold_import_decl(&mut self, decl: ImportDecl) -> ImportDecl { | ||
// Match named imports and check if it's included in the packages | ||
let src_value = decl.src.value.clone(); | ||
|
||
if self.packages.iter().any(|p| src_value == *p) { | ||
let mut specifier_names = vec![]; | ||
|
||
// Skip the transform if the default or namespace import is present | ||
let mut skip_transform = false; | ||
|
||
for specifier in &decl.specifiers { | ||
match specifier { | ||
ImportSpecifier::Named(specifier) => { | ||
// Push the import name as string to the vec | ||
if let Some(imported) = &specifier.imported { | ||
match imported { | ||
ModuleExportName::Ident(ident) => { | ||
specifier_names.push(ident.sym.to_string()); | ||
} | ||
ModuleExportName::Str(str_) => { | ||
specifier_names.push(str_.value.to_string()); | ||
} | ||
} | ||
} else { | ||
specifier_names.push(specifier.local.sym.to_string()); | ||
} | ||
} | ||
ImportSpecifier::Default(_) => { | ||
skip_transform = true; | ||
break; | ||
} | ||
ImportSpecifier::Namespace(_) => { | ||
skip_transform = true; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
if !skip_transform { | ||
let new_src = format!( | ||
"barrel-optimize-loader?names={}!{}", | ||
specifier_names.join(","), | ||
src_value | ||
); | ||
|
||
// Create a new import declaration, keep everything the same except the source | ||
let mut new_decl = decl.clone(); | ||
new_decl.src = Box::new(Str { | ||
span: DUMMY_SP, | ||
value: new_src.into(), | ||
raw: None, | ||
}); | ||
|
||
return new_decl; | ||
} | ||
} | ||
|
||
decl | ||
} | ||
} |
This file contains 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
3 changes: 3 additions & 0 deletions
3
packages/next-swc/crates/core/tests/fixture/named-import-transform/1/input.js
This file contains 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 @@ | ||
import { A, B, C as F } from 'foo' | ||
import D from 'bar' | ||
import E from 'baz' |
3 changes: 3 additions & 0 deletions
3
packages/next-swc/crates/core/tests/fixture/named-import-transform/1/output.js
This file contains 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 @@ | ||
import { A, B, C as F } from "barrel-optimize-loader?names=A,B,C!foo"; | ||
import D from 'bar'; | ||
import E from 'baz'; |
3 changes: 3 additions & 0 deletions
3
packages/next-swc/crates/core/tests/fixture/named-import-transform/2/input.js
This file contains 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 @@ | ||
import { A, B, C as F } from 'foo' | ||
import { D } from 'bar' | ||
import E from 'baz' |
3 changes: 3 additions & 0 deletions
3
packages/next-swc/crates/core/tests/fixture/named-import-transform/2/output.js
This file contains 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 @@ | ||
import { A, B, C as F } from "barrel-optimize-loader?names=A,B,C!foo"; | ||
import { D } from "barrel-optimize-loader?names=D!bar"; | ||
import E from 'baz'; |
This file contains 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 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 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
5 changes: 5 additions & 0 deletions
5
packages/next/src/build/webpack/loaders/barrel-optimize-loader.ts
This file contains 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 @@ | ||
export default function transformSource(this: any, source: string) { | ||
// const { names }: any = this.getOptions() | ||
// const { resourcePath } = this | ||
return source | ||
} |
12 changes: 12 additions & 0 deletions
12
test/development/basic/auto-modularize-imports/app/layout.js
This file contains 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,12 @@ | ||
export const metadata = { | ||
title: 'Next.js', | ||
description: 'Generated by Next.js', | ||
} | ||
|
||
export default function RootLayout({ children }) { | ||
return ( | ||
<html lang="en"> | ||
<body>{children}</body> | ||
</html> | ||
) | ||
} |
11 changes: 11 additions & 0 deletions
11
test/development/basic/auto-modularize-imports/app/page.js
This file contains 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,11 @@ | ||
'use client' | ||
|
||
import { IceCream } from 'lucide-react' | ||
|
||
export default function Page() { | ||
return ( | ||
<div> | ||
<IceCream /> | ||
</div> | ||
) | ||
} |