Skip to content

Commit 6ef7bbb

Browse files
committed
Only insert CJS globals if undeclared
1 parent 1f929b6 commit 6ef7bbb

File tree

6 files changed

+102
-32
lines changed

6 files changed

+102
-32
lines changed

turbopack/crates/turbopack-ecmascript/src/chunk/item.rs

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ use turbopack_core::{
1313
};
1414

1515
use crate::{
16-
references::async_module::{AsyncModuleOptions, OptionAsyncModuleOptions},
16+
references::{
17+
async_module::{AsyncModuleOptions, OptionAsyncModuleOptions},
18+
DeclaredCjsGlobals,
19+
},
1720
utils::FormatIter,
1821
EcmascriptModuleContent, EcmascriptOptions,
1922
};
@@ -35,6 +38,7 @@ impl EcmascriptChunkItemContent {
3538
chunking_context: Vc<Box<dyn ChunkingContext>>,
3639
options: Vc<EcmascriptOptions>,
3740
async_module_options: Vc<OptionAsyncModuleOptions>,
41+
declared_cjs_globals: Vc<DeclaredCjsGlobals>,
3842
) -> Result<Vc<Self>> {
3943
let refresh = options.await?.refresh;
4044
let externals = *chunking_context
@@ -44,6 +48,7 @@ impl EcmascriptChunkItemContent {
4448

4549
let content = content.await?;
4650
let async_module = async_module_options.await?.clone_value();
51+
let declared_cjs_globals = declared_cjs_globals.await?;
4752

4853
Ok(EcmascriptChunkItemContent {
4954
inner_code: content.inner_code.clone(),
@@ -54,7 +59,11 @@ impl EcmascriptChunkItemContent {
5459
refresh,
5560
externals,
5661
async_module,
57-
stub_require: true,
62+
require: if declared_cjs_globals.require {
63+
EcmascriptChunkItemRequireType::None
64+
} else {
65+
EcmascriptChunkItemRequireType::Stub
66+
},
5867
..Default::default()
5968
}
6069
} else {
@@ -65,10 +74,12 @@ impl EcmascriptChunkItemContent {
6574
EcmascriptChunkItemOptions {
6675
refresh,
6776
externals,
68-
// These things are not available in ESM
77+
require: EcmascriptChunkItemRequireType::Real,
78+
// These are not available in ESM
6979
module: true,
7080
exports: true,
7181
this: true,
82+
dirname: true,
7283
..Default::default()
7384
}
7485
},
@@ -96,8 +107,6 @@ impl EcmascriptChunkItemContent {
96107
"R: __turbopack_resolve_module_id_path__",
97108
"b: __turbopack_worker_blob_url__",
98109
"g: global",
99-
// HACK
100-
"__dirname",
101110
];
102111
if this.options.async_module.is_some() {
103112
args.push("a: __turbopack_async_module__");
@@ -109,21 +118,26 @@ impl EcmascriptChunkItemContent {
109118
if this.options.refresh {
110119
args.push("k: __turbopack_refresh__");
111120
}
121+
if this.options.dirname {
122+
args.push("__dirname");
123+
}
112124
if this.options.module || this.options.refresh {
113125
args.push("m: module");
114126
}
115127
if this.options.exports {
116128
args.push("e: exports");
117129
}
118-
if this.options.stub_require {
119-
args.push("z: require");
120-
} else {
121-
args.push("t: require");
130+
match this.options.require {
131+
EcmascriptChunkItemRequireType::Real => args.push("t: require"),
132+
EcmascriptChunkItemRequireType::Stub => args.push("z: require"),
133+
EcmascriptChunkItemRequireType::None => {}
122134
}
135+
123136
if this.options.wasm {
124137
args.push("w: __turbopack_wasm__");
125138
args.push("u: __turbopack_wasm_module__");
126139
}
140+
127141
let mut code = CodeBuilder::default();
128142
let args = FormatIter(|| args.iter().copied().intersperse(", "));
129143
if this.options.this {
@@ -159,6 +173,17 @@ impl EcmascriptChunkItemContent {
159173
}
160174
}
161175

176+
#[derive(PartialEq, Eq, Default, Debug, Clone, Serialize, Deserialize, TraceRawVcs)]
177+
pub enum EcmascriptChunkItemRequireType {
178+
/// No require at all
179+
#[default]
180+
None,
181+
/// A throwing stub (for ESM)
182+
Stub,
183+
/// The real require
184+
Real,
185+
}
186+
162187
#[derive(PartialEq, Eq, Default, Debug, Clone, Serialize, Deserialize, TraceRawVcs)]
163188
pub struct EcmascriptChunkItemOptions {
164189
/// Whether this chunk item should be in "use strict" mode.
@@ -172,15 +197,19 @@ pub struct EcmascriptChunkItemOptions {
172197
/// Whether this chunk item's module factory should include an `exports`
173198
/// argument.
174199
pub exports: bool,
175-
/// Whether this chunk item's module factory should include an argument for the real `require`,
176-
/// or just a throwing stub (for ESM)
177-
pub stub_require: bool,
200+
/// Whether this chunk item's module factory should include an `__dirname`
201+
/// argument.
202+
pub dirname: bool,
203+
/// What `require` argument this chunk item's module factory should include
204+
/// an argument for the real `require`.
205+
pub require: EcmascriptChunkItemRequireType,
178206
/// Whether this chunk item's module factory should include a
179207
/// `__turbopack_external_require__` argument.
180208
pub externals: bool,
181209
/// Whether this chunk item's module is async (either has a top level await
182210
/// or is importing async modules).
183211
pub async_module: Option<AsyncModuleOptions>,
212+
/// Whether this chunk item accesses the module-global `this` object.
184213
pub this: bool,
185214
/// Whether this chunk item's module factory should include
186215
/// `__turbopack_wasm__` to load WebAssembly.

turbopack/crates/turbopack-ecmascript/src/lib.rs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ use swc_core::{
5252
visit::{VisitMutWith, VisitMutWithAstPath},
5353
},
5454
};
55+
use tracing::Instrument;
5556
pub use transform::{
5657
CustomTransformer, EcmascriptInputTransform, EcmascriptInputTransforms, OptionTransformPlugin,
5758
TransformContext, TransformPlugin, UnsupportedServerActionIssue,
@@ -685,27 +686,32 @@ impl EcmascriptChunkItem for ModuleChunkItem {
685686
async_module_info: Option<Vc<AsyncModuleInfo>>,
686687
) -> Result<Vc<EcmascriptChunkItemContent>> {
687688
let this = self.await?;
688-
let _span = tracing::info_span!(
689+
async {
690+
let async_module_options = this
691+
.module
692+
.get_async_module()
693+
.module_options(async_module_info);
694+
695+
// TODO check if we need to pass async_module_info at all
696+
let content = this
697+
.module
698+
.module_content(this.chunking_context, async_module_info);
699+
700+
let declared_cjs_globals = this.module.analyze().await?.declared_cjs_globals;
701+
702+
Ok(EcmascriptChunkItemContent::new(
703+
content,
704+
this.chunking_context,
705+
this.module.options(),
706+
async_module_options,
707+
declared_cjs_globals,
708+
))
709+
}
710+
.instrument(tracing::info_span!(
689711
"code generation",
690712
module = self.asset_ident().to_string().await?.to_string()
691-
)
692-
.entered();
693-
let async_module_options = this
694-
.module
695-
.get_async_module()
696-
.module_options(async_module_info);
697-
698-
// TODO check if we need to pass async_module_info at all
699-
let content = this
700-
.module
701-
.module_content(this.chunking_context, async_module_info);
702-
703-
Ok(EcmascriptChunkItemContent::new(
704-
content,
705-
this.chunking_context,
706-
this.module.options(),
707-
async_module_options,
708713
))
714+
.await
709715
}
710716
}
711717

turbopack/crates/turbopack-ecmascript/src/references/external_module.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::{fmt::Display, io::Write};
22

33
use anyhow::Result;
44
use serde::{Deserialize, Serialize};
5-
use turbo_tasks::{trace::TraceRawVcs, RcStr, TaskInput, Vc};
5+
use turbo_tasks::{trace::TraceRawVcs, RcStr, TaskInput, ValueDefault, Vc};
66
use turbo_tasks_fs::{glob::Glob, rope::RopeBuilder, FileContent, FileSystem, VirtualFileSystem};
77
use turbopack_core::{
88
asset::{Asset, AssetContent},
@@ -12,6 +12,7 @@ use turbopack_core::{
1212
reference::ModuleReferences,
1313
};
1414

15+
use super::DeclaredCjsGlobals;
1516
use crate::{
1617
chunk::{
1718
EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable,
@@ -241,6 +242,7 @@ impl EcmascriptChunkItem for CachedExternalModuleChunkItem {
241242
self.chunking_context,
242243
EcmascriptOptions::default().cell(),
243244
async_module_options,
245+
DeclaredCjsGlobals::value_default(),
244246
))
245247
}
246248
}

turbopack/crates/turbopack-ecmascript/src/references/mod.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ use swc_core::{
5151
},
5252
};
5353
use tracing::Instrument;
54-
use turbo_tasks::{RcStr, TryJoinIterExt, Upcast, Value, ValueToString, Vc};
54+
use turbo_tasks::{RcStr, TryJoinIterExt, Upcast, Value, ValueDefault, ValueToString, Vc};
5555
use turbo_tasks_fs::FileSystemPath;
5656
use turbopack_core::{
5757
compile_time_info::{
@@ -143,6 +143,22 @@ use crate::{
143143
TreeShakingMode,
144144
};
145145

146+
#[turbo_tasks::value(shared)]
147+
#[derive(Clone, Debug, Default)]
148+
pub struct DeclaredCjsGlobals {
149+
pub dirname: bool,
150+
pub filename: bool,
151+
pub require: bool,
152+
}
153+
154+
#[turbo_tasks::value_impl]
155+
impl ValueDefault for DeclaredCjsGlobals {
156+
#[turbo_tasks::function]
157+
fn value_default() -> Vc<Self> {
158+
Self::default().cell()
159+
}
160+
}
161+
146162
#[turbo_tasks::value(shared)]
147163
#[derive(Clone)]
148164
pub struct AnalyzeEcmascriptModuleResult {
@@ -153,6 +169,7 @@ pub struct AnalyzeEcmascriptModuleResult {
153169
pub code_generation: Vc<CodeGenerateables>,
154170
pub exports: Vc<EcmascriptExports>,
155171
pub async_module: Vc<OptionAsyncModule>,
172+
pub declared_cjs_globals: Vc<DeclaredCjsGlobals>,
156173
/// `true` when the analysis was successful.
157174
pub successful: bool,
158175
pub source_map: Vc<OptionSourceMap>,
@@ -168,6 +185,7 @@ pub struct AnalyzeEcmascriptModuleResultBuilder {
168185
code_gens: Vec<CodeGen>,
169186
exports: EcmascriptExports,
170187
async_module: Vc<OptionAsyncModule>,
188+
declared_cjs_globals: DeclaredCjsGlobals,
171189
successful: bool,
172190
source_map: Option<Vc<OptionSourceMap>>,
173191
bindings: Vec<EsmBinding>,
@@ -183,6 +201,7 @@ impl AnalyzeEcmascriptModuleResultBuilder {
183201
code_gens: Vec::new(),
184202
exports: EcmascriptExports::None,
185203
async_module: Vc::cell(None),
204+
declared_cjs_globals: Default::default(),
186205
successful: false,
187206
source_map: None,
188207
bindings: Vec::new(),
@@ -263,6 +282,11 @@ impl AnalyzeEcmascriptModuleResultBuilder {
263282
self.exports = exports;
264283
}
265284

285+
/// Sets the analysis result CJS globals.
286+
pub fn set_declared_cjs_globals(&mut self, globals: DeclaredCjsGlobals) {
287+
self.declared_cjs_globals = globals;
288+
}
289+
266290
/// Sets the analysis result ES export.
267291
pub fn set_async_module(&mut self, async_module: Vc<AsyncModule>) {
268292
self.async_module = Vc::cell(Some(async_module));
@@ -336,6 +360,7 @@ impl AnalyzeEcmascriptModuleResultBuilder {
336360
code_generation: Vc::cell(self.code_gens),
337361
exports: self.exports.into(),
338362
async_module: self.async_module,
363+
declared_cjs_globals: self.declared_cjs_globals.into(),
339364
successful: self.successful,
340365
source_map,
341366
},
@@ -627,6 +652,12 @@ pub(crate) async fn analyse_ecmascript_module_internal(
627652
let mut var_graph =
628653
set_handler_and_globals(&handler, globals, || create_graph(program, eval_context));
629654

655+
analysis.set_declared_cjs_globals(DeclaredCjsGlobals {
656+
dirname: var_graph.values.keys().any(|(k, _)| k == "__dirname"),
657+
filename: var_graph.values.keys().any(|(k, _)| k == "__filename"),
658+
require: var_graph.values.keys().any(|(k, _)| k == "require"),
659+
});
660+
630661
let mut evaluation_references = Vec::new();
631662

632663
for (i, r) in eval_context.imports.references().enumerate() {

turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/locals/chunk_item.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ impl EcmascriptChunkItem for EcmascriptModuleLocalsChunkItem {
6666
self.chunking_context,
6767
original_module.await?.options,
6868
async_module_options,
69+
analyze_result.declared_cjs_globals,
6970
))
7071
}
7172

turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ impl EcmascriptChunkItem for EcmascriptModulePartChunkItem {
6464
this.chunking_context,
6565
module.full_module.await?.options,
6666
async_module_options,
67+
analyze.declared_cjs_globals,
6768
))
6869
}
6970

0 commit comments

Comments
 (0)