Skip to content
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

feat: Enable tree shaking in next.js #8523

Merged
merged 154 commits into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
154 commits
Select commit Hold shift + click to select a range
c3d89be
WIP: Print input
kdy1 Jun 18, 2024
6b75f6c
Add a test
kdy1 Jun 18, 2024
0ec839e
Print the split result
kdy1 Jun 18, 2024
330d378
Remove useless unit test
kdy1 Jun 18, 2024
bd250f5
top_level_vars
kdy1 Jun 18, 2024
4e06e0a
dump module on failure
kdy1 Jun 18, 2024
5e2f16b
export *
kdy1 Jun 18, 2024
e53f2e4
fixup
kdy1 Jun 18, 2024
f325ac9
Add a test
kdy1 Jun 19, 2024
906ee3c
Update test refs
kdy1 Jun 19, 2024
6f33da3
cleanup
kdy1 Jun 19, 2024
7261365
required_vars
kdy1 Jun 19, 2024
06b85a0
Remove wrong optimization
kdy1 Jun 19, 2024
52de4ad
Update test refs
kdy1 Jun 19, 2024
da310e2
TODO
kdy1 Jun 19, 2024
cc62fd2
Add a tedst
kdy1 Jun 19, 2024
3d8a85a
Update test refs
kdy1 Jun 19, 2024
1f825a3
Use real input for testing
kdy1 Jun 19, 2024
45fb46b
Make more access not eventual
kdy1 Jun 19, 2024
b7129b4
Update test refs
kdy1 Jun 19, 2024
fddbdd7
Add a test
kdy1 Jun 19, 2024
8ca5842
fixup
kdy1 Jun 19, 2024
bd34642
Make class decl not hoisted
kdy1 Jun 19, 2024
b81c365
Update test refs
kdy1 Jun 20, 2024
24021a2
strong dep for side-effect node
kdy1 Jun 20, 2024
a1a0be0
Update test refs
kdy1 Jun 20, 2024
2152040
export default fn
kdy1 Jun 20, 2024
5d7c6a6
Remove self-read
kdy1 Jun 20, 2024
69b9e48
fixup
kdy1 Jun 20, 2024
0003aab
side_effecrts: false
kdy1 Jun 20, 2024
5f7934c
Respect declarator from eventual accesses
kdy1 Jun 20, 2024
0684d55
Update test refs
kdy1 Jun 20, 2024
eefff9b
Use strong depx
kdy1 Jun 20, 2024
a289eeb
Update test refs
kdy1 Jun 20, 2024
addfba6
State.declarator
kdy1 Jun 20, 2024
7582630
fixup
kdy1 Jun 20, 2024
ab5fe30
Handle dependencies of cycles corectly
kdy1 Jun 20, 2024
d3aeda4
Use eprintln
kdy1 Jun 21, 2024
d6233cb
Add a test
kdy1 Jun 21, 2024
0935a24
Update tests refs
kdy1 Jun 21, 2024
b952425
Remove debugging code
kdy1 Jun 21, 2024
46ebf77
Add a test
kdy1 Jun 21, 2024
3543eb8
Revert "Remove debugging code"
kdy1 Jun 21, 2024
0e60e4b
Update test refs
kdy1 Jun 21, 2024
23cf8ce
Add a test
kdy1 Jun 21, 2024
1285386
Test
kdy1 Jun 21, 2024
51a6257
fixup
kdy1 Jun 21, 2024
d4b6f88
Update test refs
kdy1 Jun 21, 2024
a34d00b
Rename
kdy1 Jun 24, 2024
a16cbe1
should_skip_tree_shaking
kdy1 Jun 24, 2024
e4dc02e
lint
kdy1 Jun 24, 2024
2bb2f3a
fix
kdy1 Jun 24, 2024
980ad96
Skip @swc/helpers
kdy1 Jun 24, 2024
88c014d
skip
kdy1 Jun 24, 2024
94d2faf
disable some
kdy1 Jun 24, 2024
8d64722
Add a unit test
kdy1 Jun 24, 2024
95a0ba1
tiny
kdy1 Jun 24, 2024
5350d53
Improve analyzer
kdy1 Jun 24, 2024
6f26124
Update test refs
kdy1 Jun 24, 2024
761b864
Revert "Improve analyzer"
kdy1 Jun 24, 2024
da29cc8
Update test refs
kdy1 Jun 24, 2024
3a0eb8a
Remove logging
kdy1 Jun 24, 2024
74023fe
Enable logging
kdy1 Jun 24, 2024
61c19b1
\n
kdy1 Jun 24, 2024
b9b0237
skip
kdy1 Jun 24, 2024
63e0379
skip
kdy1 Jun 24, 2024
6efaae3
Remove logging
kdy1 Jun 24, 2024
3c31731
lint
kdy1 Jun 24, 2024
ecebb61
Add a unit test
kdy1 Jun 24, 2024
53d998a
Revert "Remove logging"
kdy1 Jun 24, 2024
f41e9af
`let`
kdy1 Jun 24, 2024
d849c85
`should_skip_tree_shaking`
kdy1 Jun 24, 2024
316966f
Server actions
kdy1 Jun 24, 2024
1b1f69d
Revert "Revert "Remove logging""
kdy1 Jun 24, 2024
dcd2685
Revert "Revert "Revert "Remove logging"""
kdy1 Jun 24, 2024
7a2bdd8
lint
kdy1 Jun 24, 2024
f039d5d
Suport EcmascriptModulePartAsset
kdy1 Jun 24, 2024
1cb5b16
Remove logging
kdy1 Jun 24, 2024
ed3b903
Revert "Remove logging"
kdy1 Jun 24, 2024
8f52523
Cleanup cjs
kdy1 Jul 1, 2024
6216989
Remove logging
kdy1 Jul 1, 2024
6ea2aaa
lint
kdy1 Jul 1, 2024
3b84d3a
Enable `let`
kdy1 Jul 1, 2024
404f564
Enable more
kdy1 Jul 1, 2024
257dae1
Revert "Remove logging"
kdy1 Jul 1, 2024
d446368
Deduplicate export *
kdy1 Jul 1, 2024
fb98710
Revert "Revert "Remove logging""
kdy1 Jul 1, 2024
628f89b
Revert "Remove logging"
kdy1 Jul 1, 2024
bf28c67
Add tests
kdy1 Jul 1, 2024
8450311
Shorthand is read-write
kdy1 Jul 1, 2024
03f6ae9
Add a test
kdy1 Jul 2, 2024
ed59314
Tests
kdy1 Jul 2, 2024
714ac4d
Enable for more files
kdy1 Jul 2, 2024
403fb62
Update test refs
kdy1 Jul 2, 2024
b205432
next.js
kdy1 Jul 2, 2024
ce91849
Remove logging
kdy1 Jul 2, 2024
03c0441
Revert "Remove logging"
kdy1 Jul 2, 2024
58ebb33
Disable tree shaking for `nanoid`
kdy1 Jul 2, 2024
d83cd69
`is_next_js_special_export`
kdy1 Jul 2, 2024
945cea5
Skip special reexports that are recognized by next.js
kdy1 Jul 2, 2024
a2a1c13
middleware
kdy1 Jul 2, 2024
d44aee4
Remove logging
kdy1 Jul 2, 2024
a0bb4bc
Add logging
kdy1 Jul 2, 2024
9b70518
Add a test
kdy1 Jul 2, 2024
f6dd028
Add a test
kdy1 Jul 2, 2024
8333edd
Remove a test
kdy1 Jul 2, 2024
63d18e8
Update test refs
kdy1 Jul 2, 2024
767f2d6
Ignore `@opentelemetry/core`
kdy1 Jul 2, 2024
687be7a
Remove logging
kdy1 Jul 2, 2024
bc78084
Revert "Remove logging"
kdy1 Jul 2, 2024
2c6b241
`star_reexports`
kdy1 Jul 3, 2024
155eaf9
Remove logging
kdy1 Jul 3, 2024
dc98dec
Enable all
kdy1 Jul 3, 2024
9427590
Fix `star_reexports` for 1-module result
kdy1 Jul 3, 2024
08ed0a0
Add logging
kdy1 Jul 3, 2024
d60319c
Fix `star_reexports`
kdy1 Jul 3, 2024
ac5d195
Remove logging
kdy1 Jul 3, 2024
1c52b32
Ignore `middleware`
kdy1 Jul 3, 2024
9fe3420
Add logging
kdy1 Jul 3, 2024
4e3e39d
ImportedSymbol::Exports
kdy1 Jul 3, 2024
2f01cef
Remove logging
kdy1 Jul 3, 2024
c241205
Update test refs
kdy1 Jul 4, 2024
a53b34f
gitattributes
kdy1 Jul 11, 2024
b23c654
Update crates/turbopack-ecmascript/src/tree_shake/cjs_finder.rs
kdy1 Jul 11, 2024
4578bf8
Update crates/turbopack-ecmascript/src/tree_shake/mod.rs
kdy1 Jul 11, 2024
195ba1e
Update crates/turbopack-ecmascript/src/tree_shake/mod.rs
kdy1 Jul 11, 2024
79724cf
Update crates/turbopack-ecmascript/src/tree_shake/mod.rs
kdy1 Jul 11, 2024
7f106d0
Update crates/turbopack-ecmascript/src/tree_shake/mod.rs
kdy1 Jul 11, 2024
0dee3b5
Rename
kdy1 Jul 11, 2024
98d7c0a
TODO
kdy1 Jul 11, 2024
6ef9c9a
Update crates/turbopack-ecmascript/src/tree_shake/graph.rs
kdy1 Jul 11, 2024
ff34349
`special_exports`
kdy1 Jul 11, 2024
3d7a277
Eanble optimization again
kdy1 Jul 11, 2024
d3af661
Remove `@swc/helpers` opt & lint
kdy1 Jul 11, 2024
3c8ff30
Update test refs
kdy1 Jul 11, 2024
8ba15f2
Remove `ImportSymbol::Namespace`
kdy1 Jul 11, 2024
b23bc1f
Remove skip_namespace
kdy1 Jul 11, 2024
9437099
Revert "Remove logging"
kdy1 Jul 12, 2024
82c7616
Fix export
kdy1 Jul 12, 2024
b13fa9d
Remove logging
kdy1 Jul 12, 2024
9f3ec22
Update test refs
kdy1 Jul 15, 2024
b4ef2a1
Update test refs
kdy1 Jul 15, 2024
d9bd9f3
clippy
kdy1 Jul 15, 2024
05a6d73
review
kdy1 Jul 15, 2024
0f8f6ec
review: We don't need special_exports
kdy1 Jul 15, 2024
5e716d6
Doc
kdy1 Jul 15, 2024
2dbd0fb
review
kdy1 Jul 15, 2024
f47478a
review
kdy1 Jul 15, 2024
fed946a
review
kdy1 Jul 15, 2024
94bf8c1
fix
kdy1 Jul 15, 2024
5ea0f62
pub
kdy1 Jul 15, 2024
f642983
lint
kdy1 Jul 15, 2024
c09d8c0
lint
kdy1 Jul 15, 2024
2d203aa
loader_as_resolve_origin
kdy1 Jul 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.config/ast-grep/rule-tests/__snapshots__/** linguist-generated=true
crates/turbo-tasks-macros-tests/tests/**/*.stderr linguist-generated=true
crates/turbopack-ecmascript/tests/tree-shaker/analyzer/**/output.md linguist-generated=true
crates/turbopack-tests/tests/snapshot/**/output/** linguist-generated=true
crates/turborepo-lockfiles/fixtures/*.lock text eol=lf
2 changes: 1 addition & 1 deletion crates/turbopack-ecmascript/benches/analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub fn benchmark(c: &mut Criterion) {
program.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, false));

let eval_context =
EvalContext::new(&program, unresolved_mark, top_level_mark, false, None);
EvalContext::new(&program, unresolved_mark, top_level_mark, None);
let var_graph = create_graph(&program, &eval_context);

let input = BenchInput {
Expand Down
3 changes: 1 addition & 2 deletions crates/turbopack-ecmascript/src/analyzer/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,13 +270,12 @@ impl EvalContext {
module: &Program,
unresolved_mark: Mark,
top_level_mark: Mark,
skip_namespace: bool,
source: Option<Vc<Box<dyn Source>>>,
) -> Self {
Self {
unresolved_mark,
top_level_mark,
imports: ImportMap::analyze(module, skip_namespace, source),
imports: ImportMap::analyze(module, source),
}
}

Expand Down
20 changes: 4 additions & 16 deletions crates/turbopack-ecmascript/src/analyzer/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,6 @@ pub(crate) struct ImportMap {
pub(crate) enum ImportedSymbol {
ModuleEvaluation,
Symbol(JsWord),
/// User requested the whole module
Namespace,
Exports,
Part(u32),
}
Expand Down Expand Up @@ -202,16 +200,11 @@ impl ImportMap {
}

/// Analyze ES import
pub(super) fn analyze(
m: &Program,
skip_namespace: bool,
source: Option<Vc<Box<dyn Source>>>,
) -> Self {
pub(super) fn analyze(m: &Program, source: Option<Vc<Box<dyn Source>>>) -> Self {
let mut data = ImportMap::default();

m.visit_with(&mut Analyzer {
data: &mut data,
skip_namespace,
source,
});

Expand All @@ -221,7 +214,6 @@ impl ImportMap {

struct Analyzer<'a> {
data: &'a mut ImportMap,
skip_namespace: bool,
source: Option<Vc<Box<dyn Source>>>,
}

Expand All @@ -233,10 +225,6 @@ impl<'a> Analyzer<'a> {
imported_symbol: ImportedSymbol,
annotations: ImportAnnotations,
) -> Option<usize> {
if self.skip_namespace && matches!(imported_symbol, ImportedSymbol::Namespace) {
return None;
}

let issue_source = self
.source
.map(|s| IssueSource::from_swc_offsets(s, span.lo.to_usize(), span.hi.to_usize()));
Expand Down Expand Up @@ -339,7 +327,7 @@ impl Visit for Analyzer<'_> {
let i = self.ensure_reference(
export.span,
export.src.value.clone(),
symbol.unwrap_or(ImportedSymbol::Namespace),
kdy1 marked this conversation as resolved.
Show resolved Hide resolved
symbol.unwrap_or(ImportedSymbol::Exports),
annotations,
);
if let Some(i) = i {
Expand Down Expand Up @@ -455,7 +443,7 @@ fn get_import_symbol_from_import(specifier: &ImportSpecifier) -> ImportedSymbol
_ => local.sym.clone(),
}),
ImportSpecifier::Default(..) => ImportedSymbol::Symbol(js_word!("default")),
ImportSpecifier::Namespace(..) => ImportedSymbol::Namespace,
ImportSpecifier::Namespace(..) => ImportedSymbol::Exports,
}
}

Expand All @@ -465,6 +453,6 @@ fn get_import_symbol_from_export(specifier: &ExportSpecifier) -> ImportedSymbol
ImportedSymbol::Symbol(orig_name(orig))
}
ExportSpecifier::Default(..) => ImportedSymbol::Symbol(js_word!("default")),
ExportSpecifier::Namespace(..) => ImportedSymbol::Namespace,
ExportSpecifier::Namespace(..) => ImportedSymbol::Exports,
}
}
3 changes: 1 addition & 2 deletions crates/turbopack-ecmascript/src/analyzer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3588,8 +3588,7 @@ mod tests {
let top_level_mark = Mark::new();
m.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, false));

let eval_context =
EvalContext::new(&m, unresolved_mark, top_level_mark, false, None);
let eval_context = EvalContext::new(&m, unresolved_mark, top_level_mark, None);

let mut var_graph = create_graph(&m, &eval_context);

Expand Down
8 changes: 8 additions & 0 deletions crates/turbopack-ecmascript/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ pub enum TreeShakingMode {
ReexportsOnly,
}

#[turbo_tasks::value(transparent)]
pub struct OptionTreeShaking(pub Option<TreeShakingMode>);

#[turbo_tasks::value(shared, serialization = "auto_for_input")]
#[derive(PartialOrd, Ord, Hash, Debug, Default, Copy, Clone)]
pub struct EcmascriptOptions {
Expand All @@ -139,6 +142,11 @@ pub struct EcmascriptOptions {
/// If false, they will reference the whole directory. If true, they won't
/// reference anything and lead to an runtime error instead.
pub ignore_dynamic_requests: bool,

/// The list of export names that should make tree shaking bail off. This is
/// required because tree shaking can split imports like `export const
/// runtime = 'edge'` as a separate module.
pub special_exports: Vc<Vec<RcStr>>,
kdy1 marked this conversation as resolved.
Show resolved Hide resolved
}

#[turbo_tasks::value(serialization = "auto_for_input")]
Expand Down
1 change: 0 additions & 1 deletion crates/turbopack-ecmascript/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,6 @@ async fn parse_content(
&parsed_program,
unresolved_mark,
top_level_mark,
false,
Some(source),
);

Expand Down
3 changes: 3 additions & 0 deletions crates/turbopack-ecmascript/src/references/esm/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ pub struct EsmAssetReference {
pub issue_source: Option<Vc<IssueSource>>,
pub export_name: Option<Vc<ModulePart>>,
pub import_externals: bool,
pub special_exports: Vc<Vec<RcStr>>,
}

/// A list of [EsmAssetReference]s
Expand All @@ -121,6 +122,7 @@ impl EsmAssetReference {
issue_source: Option<Vc<IssueSource>>,
annotations: Value<ImportAnnotations>,
export_name: Option<Vc<ModulePart>>,
special_exports: Vc<Vec<RcStr>>,
import_externals: bool,
) -> Vc<Self> {
Self::cell(EsmAssetReference {
Expand All @@ -130,6 +132,7 @@ impl EsmAssetReference {
annotations: annotations.into_value(),
export_name,
import_externals,
special_exports,
})
}

Expand Down
9 changes: 6 additions & 3 deletions crates/turbopack-ecmascript/src/references/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ struct AnalysisState<'a> {
// the object allocation.
first_import_meta: bool,
tree_shaking_mode: Option<TreeShakingMode>,
special_exports: Vc<Vec<RcStr>>,
import_externals: bool,
ignore_dynamic_requests: bool,
}
Expand Down Expand Up @@ -412,6 +413,7 @@ pub(crate) async fn analyse_ecmascript_module_internal(
let options = raw_module.options;
let compile_time_info = raw_module.compile_time_info;
let options = options.await?;
let special_exports = options.special_exports;
let import_externals = options.import_externals;

let origin = Vc::upcast::<Box<dyn ResolveOrigin>>(module);
Expand All @@ -428,7 +430,7 @@ pub(crate) async fn analyse_ecmascript_module_internal(

let parsed = if let Some(part) = part {
let parsed = parse(source, ty, transforms);
let split_data = split(source.ident(), source, parsed);
let split_data = split(source.ident(), source, parsed, special_exports);
part_of_module(split_data, part)
} else {
parse(source, ty, transforms)
Expand Down Expand Up @@ -576,7 +578,6 @@ pub(crate) async fn analyse_ecmascript_module_internal(
ImportedSymbol::Symbol(name) => Some(ModulePart::export((&**name).into())),
ImportedSymbol::Part(part_id) => Some(ModulePart::internal(*part_id)),
ImportedSymbol::Exports => Some(ModulePart::exports()),
ImportedSymbol::Namespace => None,
},
Some(TreeShakingMode::ReexportsOnly) => match &r.imported_symbol {
ImportedSymbol::ModuleEvaluation => {
Expand All @@ -586,10 +587,10 @@ pub(crate) async fn analyse_ecmascript_module_internal(
ImportedSymbol::Symbol(name) => Some(ModulePart::export((&**name).into())),
ImportedSymbol::Part(part_id) => Some(ModulePart::internal(*part_id)),
ImportedSymbol::Exports => None,
ImportedSymbol::Namespace => None,
},
None => None,
},
special_exports,
import_externals,
);

Expand Down Expand Up @@ -814,6 +815,7 @@ pub(crate) async fn analyse_ecmascript_module_internal(
first_import_meta: true,
tree_shaking_mode: options.tree_shaking_mode,
import_externals: options.import_externals,
special_exports: options.special_exports,
ignore_dynamic_requests: options.ignore_dynamic_requests,
};

Expand Down Expand Up @@ -1972,6 +1974,7 @@ async fn handle_free_var_reference(
.map(|export| ModulePart::export(export.clone())),
None => None,
},
state.special_exports,
state.import_externals,
)
.resolve()
Expand Down
2 changes: 1 addition & 1 deletion crates/turbopack-ecmascript/src/tree_shake/asset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::{
/// This type is used for an advanced tree shkaing.
#[turbo_tasks::value]
pub struct EcmascriptModulePartAsset {
pub(crate) full_module: Vc<EcmascriptModuleAsset>,
pub full_module: Vc<EcmascriptModuleAsset>,
pub(crate) part: Vc<ModulePart>,
pub(crate) import_externals: bool,
}
Expand Down
11 changes: 0 additions & 11 deletions crates/turbopack-ecmascript/src/tree_shake/cjs_finder.rs

This file was deleted.

Loading
Loading