Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
20 changes: 20 additions & 0 deletions turbopack/crates/turbopack-browser/src/chunking_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ impl BrowserChunkingContextBuilder {
self
}

pub fn chunk_loading_global(mut self, chunk_loading_global: RcStr) -> Self {
self.chunking_context.chunk_loading_global = Some(chunk_loading_global);
self
}

pub fn build(self) -> Vc<BrowserChunkingContext> {
BrowserChunkingContext::cell(self.chunking_context)
}
Expand Down Expand Up @@ -328,6 +333,9 @@ pub struct BrowserChunkingContext {
filename: Option<RcStr>,
/// Non evaluate chunk filename template
chunk_filename: Option<RcStr>,
/// The global variable name used for chunk loading.
/// Default: "TURBOPACK"
chunk_loading_global: Option<RcStr>,
}

impl BrowserChunkingContext {
Expand Down Expand Up @@ -377,6 +385,7 @@ impl BrowserChunkingContext {
should_use_absolute_url_references: false,
filename: Default::default(),
chunk_filename: Default::default(),
chunk_loading_global: Default::default(),
},
}
}
Expand Down Expand Up @@ -480,6 +489,17 @@ impl BrowserChunkingContext {
self.minify_type.cell()
}

/// Returns the chunk loading global variable name.
/// Defaults to "TURBOPACK" if not set.
#[turbo_tasks::function]
pub fn chunk_loading_global(&self) -> Vc<RcStr> {
Vc::cell(
self.chunk_loading_global
.clone()
.unwrap_or_else(|| rcstr!("TURBOPACK")),
)
}

/// Returns the chunk path information.
#[turbo_tasks::function]
fn chunk_path_info(&self) -> Vc<ChunkPathInfo> {
Expand Down
6 changes: 4 additions & 2 deletions turbopack/crates/turbopack-browser/src/ecmascript/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,18 @@ impl EcmascriptBrowserChunkContent {

// When a chunk is executed, it will either register itself with the current
// instance of the runtime, or it will push itself onto the list of pending
// chunks (`self.TURBOPACK`).
// chunks (using the configured chunk loading global variable).
//
// When the runtime executes (see the `evaluate` module), it will pick up and
// register all pending chunks, and replace the list of pending chunks
// with itself so later chunks can register directly with it.
let chunk_loading_global = this.chunking_context.chunk_loading_global().await?;
write!(
code,
// `||=` would be better but we need to be es2020 compatible
//`x || (x = default)` is better than `x = x || default` simply because we avoid _writing_ the property in the common case.
"(globalThis.TURBOPACK || (globalThis.TURBOPACK = [])).push([{script_or_path},"
"(globalThis[\"{chunk_loading_global}\"] || (globalThis[\"{chunk_loading_global}\"] = \
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r#

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done 了

[])).push([{script_or_path},"
)?;

let content = this.content.await?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,20 +171,21 @@ impl EcmascriptBrowserEvaluateChunk {
*this.chunking_context.debug_ids_enabled().await?,
);

// We still use the `TURBOPACK` global variable to store the chunk here,
// as there may be another runtime already loaded in the page.
// This is the case in integration tests.
// Use the configured chunk loading global variable to store the chunk here.
// This allows multiple runtimes to coexist on the same page when using different global
// names.
let chunk_loading_global = this.chunking_context.chunk_loading_global().await?;
writedoc!(
code,
// `||=` would be better but we need to be es2020 compatible
//`x || (x = default)` is better than `x = x || default` simply because we avoid _writing_ the property in the common case.
r#"
(globalThis.TURBOPACK || (globalThis.TURBOPACK = [])).push([
(globalThis["{chunk_loading_global}"] || (globalThis["{chunk_loading_global}"] = [])).push([
{script_or_path},
{}
{params}
]);
"#,
StringifyJs(&params),
params = StringifyJs(&params),
)?;

let runtime_type = *this.chunking_context.runtime_type().await?;
Expand All @@ -197,6 +198,7 @@ impl EcmascriptBrowserEvaluateChunk {
runtime_type,
output_root_to_root_path,
source_maps,
this.chunking_context.chunk_loading_global(),
);
code.push_code(&*runtime_code.await?);
}
Expand Down
15 changes: 12 additions & 3 deletions turbopack/crates/turbopack-browser/src/ecmascript/list/content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ pub(super) struct EcmascriptDevChunkListContent {
#[bincode(with = "turbo_bincode::indexmap")]
pub(super) chunks_contents: FxIndexMap<String, ResolvedVc<Box<dyn VersionedContent>>>,
source: EcmascriptDevChunkListSource,
/// The global variable name used for chunk loading (derived from chunkLoadingGlobal config).
chunk_loading_global: RcStr,
}

#[turbo_tasks::value_impl]
Expand All @@ -70,6 +72,11 @@ impl EcmascriptDevChunkListContent {
CurrentChunkMethodWithData::DocumentCurrentScript
}
};
let chunk_loading_global = (*chunk_list_ref
.chunking_context
.chunk_loading_global()
.await?)
.clone();
Ok(EcmascriptDevChunkListContent {
current_chunk_method,
chunks_contents: chunk_list_ref
Expand All @@ -90,6 +97,7 @@ impl EcmascriptDevChunkListContent {
.filter_map(|(path, content)| path.map(|path| (path, content)))
.collect(),
source: chunk_list_ref.source,
chunk_loading_global,
}
.cell())
}
Expand Down Expand Up @@ -153,15 +161,16 @@ impl EcmascriptDevChunkListContent {

let mut code = CodeBuilder::default();

// When loaded, JS chunks must register themselves with the `TURBOPACK` global
// When loaded, JS chunks must register themselves with the chunk loading global
// variable. Similarly, we register the chunk list with the
// `TURBOPACK_CHUNK_LISTS` global variable.
// `{chunk_loading_global}_CHUNK_LISTS` global variable.
let chunk_lists_global = format!("{}_CHUNK_LISTS", this.chunk_loading_global);
writedoc!(
code,
// `||=` would be better but we need to be es2020 compatible
//`x || (x = default)` is better than `x = x || default` simply because we avoid _writing_ the property in the common case.
r#"
(globalThis.TURBOPACK_CHUNK_LISTS || (globalThis.TURBOPACK_CHUNK_LISTS = [])).push({{
(globalThis["{chunk_lists_global}"] || (globalThis["{chunk_lists_global}"] = [])).push({{
script: {script_or_path},
chunks: {:#},
source: {:#}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub async fn get_browser_runtime_code(
runtime_type: RuntimeType,
output_root_to_root_path: RcStr,
generate_source_map: bool,
chunk_loading_global: Vc<RcStr>,
) -> Result<Vc<Code>> {
let asset_context = get_runtime_asset_context(*environment).resolve().await?;

Expand Down Expand Up @@ -83,12 +84,14 @@ pub async fn get_browser_runtime_code(
let chunk_base_path = chunk_base_path.await?;
let chunk_base_path = chunk_base_path.as_ref().map_or_else(|| "", |f| f.as_str());
let chunk_suffix = chunk_suffix.await?;
let chunk_loading_global = chunk_loading_global.await?;
let chunk_lists_global = format!("{}_CHUNK_LISTS", &*chunk_loading_global);

writedoc!(
code,
r#"
(() => {{
if (!Array.isArray(globalThis.TURBOPACK)) {{
if (!Array.isArray(globalThis["{chunk_loading_global}"])) {{
return;
}}

Expand Down Expand Up @@ -178,17 +181,17 @@ pub async fn get_browser_runtime_code(
writedoc!(
code,
r#"
const chunksToRegister = globalThis.TURBOPACK;
globalThis.TURBOPACK = {{ push: registerChunk }};
const chunksToRegister = globalThis["{chunk_loading_global}"];
globalThis["{chunk_loading_global}"] = {{ push: registerChunk }};
chunksToRegister.forEach(registerChunk);
"#
)?;
if matches!(runtime_type, RuntimeType::Development) {
writedoc!(
code,
r#"
const chunkListsToRegister = globalThis.TURBOPACK_CHUNK_LISTS || [];
globalThis.TURBOPACK_CHUNK_LISTS = {{ push: registerChunkList }};
const chunkListsToRegister = globalThis["{chunk_lists_global}"] || [];
globalThis["{chunk_lists_global}"] = {{ push: registerChunkList }};
chunkListsToRegister.forEach(registerChunkList);
"#
)?;
Expand Down
Loading