Skip to content

Commit e431f9e

Browse files
authored
Turbopack: migrate global module ids to single-graph (#73752)
1 parent bc3e597 commit e431f9e

File tree

24 files changed

+331
-383
lines changed

24 files changed

+331
-383
lines changed

Cargo.lock

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/next-api/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ turbo-rcstr = { workspace = true }
2828
turbo-tasks = { workspace = true }
2929
turbo-tasks-env = { workspace = true }
3030
turbo-tasks-fs = { workspace = true }
31+
turbo-tasks-hash = { workspace = true }
3132
turbo-tasks-memory = { workspace = true }
3233
turbopack = { workspace = true }
3334
turbopack-browser = { workspace = true }

crates/next-api/src/global_module_id_strategy.rs

Lines changed: 0 additions & 88 deletions
This file was deleted.

crates/next-api/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ mod dynamic_imports;
99
mod empty;
1010
pub mod entrypoints;
1111
mod font;
12-
pub mod global_module_id_strategy;
1312
mod instrumentation;
1413
mod loadable_manifest;
1514
mod middleware;

crates/next-api/src/pages.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ pub struct PagesProject {
8686
project: ResolvedVc<Project>,
8787
}
8888

89+
#[turbo_tasks::function]
90+
fn client_layer() -> Vc<RcStr> {
91+
Vc::cell("client".into())
92+
}
93+
8994
#[turbo_tasks::value_impl]
9095
impl PagesProject {
9196
#[turbo_tasks::function]
@@ -312,7 +317,7 @@ impl PagesProject {
312317
self.project().client_compile_time_info(),
313318
self.client_module_options_context(),
314319
self.client_resolve_options_context(),
315-
Vc::cell("client".into()),
320+
client_layer(),
316321
)
317322
}
318323

@@ -351,7 +356,7 @@ impl PagesProject {
351356
self.project().client_compile_time_info(),
352357
self.client_module_options_context(),
353358
self.client_resolve_options_context(),
354-
Vc::cell("client".into()),
359+
client_layer(),
355360
))
356361
}
357362

crates/next-api/src/project.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ use turbo_tasks::{
3434
use turbo_tasks_env::{EnvMap, ProcessEnv};
3535
use turbo_tasks_fs::{DiskFileSystem, FileSystem, FileSystemPath, VirtualFileSystem};
3636
use turbopack::{
37-
evaluate_context::node_build_environment, transition::TransitionOptions, ModuleAssetContext,
37+
evaluate_context::node_build_environment, global_module_ids::get_global_module_id_strategy,
38+
transition::TransitionOptions, ModuleAssetContext,
3839
};
3940
use turbopack_core::{
4041
changed::content_changed,
@@ -68,7 +69,6 @@ use crate::{
6869
build,
6970
empty::EmptyEndpoint,
7071
entrypoints::Entrypoints,
71-
global_module_id_strategy::GlobalModuleIdStrategyBuilder,
7272
instrumentation::InstrumentationEndpoint,
7373
middleware::MiddlewareEndpoint,
7474
pages::PagesProject,
@@ -1576,16 +1576,25 @@ impl Project {
15761576
/// Gets the module id strategy for the project.
15771577
#[turbo_tasks::function]
15781578
pub async fn module_id_strategy(self: Vc<Self>) -> Result<Vc<Box<dyn ModuleIdStrategy>>> {
1579-
let module_id_strategy = self.next_config().module_id_strategy_config();
1580-
match *module_id_strategy.await? {
1581-
Some(ModuleIdStrategyConfig::Named) => Ok(Vc::upcast(DevModuleIdStrategy::new())),
1582-
Some(ModuleIdStrategyConfig::Deterministic) => {
1583-
Ok(Vc::upcast(GlobalModuleIdStrategyBuilder::build(self)))
1579+
let module_id_strategy = if let Some(module_id_strategy) =
1580+
&*self.next_config().module_id_strategy_config().await?
1581+
{
1582+
*module_id_strategy
1583+
} else {
1584+
match *self.next_mode().await? {
1585+
NextMode::Development => ModuleIdStrategyConfig::Named,
1586+
NextMode::Build => ModuleIdStrategyConfig::Deterministic,
1587+
}
1588+
};
1589+
1590+
match module_id_strategy {
1591+
ModuleIdStrategyConfig::Named => Ok(Vc::upcast(DevModuleIdStrategy::new())),
1592+
ModuleIdStrategyConfig::Deterministic => {
1593+
let module_graphs = self.whole_app_module_graphs().await?;
1594+
Ok(Vc::upcast(get_global_module_id_strategy(
1595+
*module_graphs.full,
1596+
)))
15841597
}
1585-
None => match *self.next_mode().await? {
1586-
NextMode::Development => Ok(Vc::upcast(DevModuleIdStrategy::new())),
1587-
NextMode::Build => Ok(Vc::upcast(DevModuleIdStrategy::new())),
1588-
},
15891598
}
15901599
}
15911600
}

crates/next-core/src/next_config.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ pub enum LoaderItem {
567567
}
568568

569569
#[turbo_tasks::value(operation)]
570-
#[derive(Clone, Debug)]
570+
#[derive(Copy, Clone, Debug)]
571571
#[serde(rename_all = "camelCase")]
572572
pub enum ModuleIdStrategy {
573573
Named,
@@ -1483,11 +1483,11 @@ impl NextConfig {
14831483
.experimental
14841484
.turbo
14851485
.as_ref()
1486-
.and_then(|t| t.module_id_strategy.as_ref())
1486+
.and_then(|t| t.module_id_strategy)
14871487
else {
14881488
return Vc::cell(None);
14891489
};
1490-
Vc::cell(Some(module_id_strategy.clone()))
1490+
Vc::cell(Some(module_id_strategy))
14911491
}
14921492

14931493
#[turbo_tasks::function]

crates/next-core/src/next_server_component/server_component_module.rs

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use turbopack_core::{
99
asset::{Asset, AssetContent},
1010
chunk::{ChunkItem, ChunkItemExt, ChunkType, ChunkableModule, ChunkingContext},
1111
ident::AssetIdent,
12-
module::{Module, Modules},
12+
module::Module,
1313
module_graph::ModuleGraph,
1414
reference::ModuleReferences,
1515
};
@@ -18,17 +18,11 @@ use turbopack_ecmascript::{
1818
EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable,
1919
EcmascriptChunkType, EcmascriptExports,
2020
},
21-
references::{
22-
esm::{EsmExport, EsmExports},
23-
external_module::IncludeIdentModule,
24-
},
21+
references::esm::{EsmExport, EsmExports},
2522
utils::StringifyJs,
2623
};
2724

2825
use super::server_component_reference::NextServerComponentModuleReference;
29-
use crate::next_app::app_client_references_chunks::{
30-
client_modules_modifier, ssr_modules_modifier,
31-
};
3226

3327
#[turbo_tasks::function]
3428
fn modifier() -> Vc<RcStr> {
@@ -68,22 +62,6 @@ impl Module for NextServerComponentModule {
6862
.await?,
6963
)]))
7064
}
71-
72-
#[turbo_tasks::function]
73-
async fn additional_layers_modules(self: Vc<Self>) -> Result<Vc<Modules>> {
74-
let base_ident = self.ident();
75-
let ssr_entry_module = ResolvedVc::upcast(
76-
IncludeIdentModule::new(base_ident.with_modifier(ssr_modules_modifier()))
77-
.to_resolved()
78-
.await?,
79-
);
80-
let client_entry_module = ResolvedVc::upcast(
81-
IncludeIdentModule::new(base_ident.with_modifier(client_modules_modifier()))
82-
.to_resolved()
83-
.await?,
84-
);
85-
Ok(Vc::cell(vec![ssr_entry_module, client_entry_module]))
86-
}
8765
}
8866

8967
#[turbo_tasks::value_impl]

test/production/pages-dir/production/test/index.test.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -580,16 +580,19 @@ describe('Production Usage', () => {
580580

581581
const resources: Set<string> = new Set()
582582

583-
const manifestKey = Object.keys(reactLoadableManifest).find((item) => {
584-
return item
585-
.replace(/\\/g, '/')
586-
.endsWith(
587-
process.env.TURBOPACK
588-
? 'components/dynamic-css/with-css.js [client] (ecmascript, next/dynamic entry)'
589-
: 'dynamic/css.js -> ../../components/dynamic-css/with-css'
590-
)
591-
})
592-
expect(manifestKey).toBeString()
583+
let manifestKey: string
584+
if (process.env.TURBOPACK) {
585+
// the key is an arbitrary and changing number for Turbopack prod, but each page has its own manifest
586+
expect(Object.keys(reactLoadableManifest).length).toBe(1)
587+
manifestKey = Object.keys(reactLoadableManifest)[0]
588+
expect(manifestKey).toBeString()
589+
} else {
590+
manifestKey = Object.keys(reactLoadableManifest).find((item) =>
591+
item
592+
.replace(/\\/g, '/')
593+
.endsWith('dynamic/css.js -> ../../components/dynamic-css/with-css')
594+
)
595+
}
593596

594597
// test dynamic chunk
595598
reactLoadableManifest[manifestKey].files.forEach((f) => {

turbopack/crates/turbopack-core/src/chunk/module_id_strategies.rs

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
use anyhow::Result;
2-
use turbo_rcstr::RcStr;
3-
use turbo_tasks::{FxIndexMap, ResolvedVc, ValueToString, Vc};
1+
use anyhow::{bail, Result};
2+
use rustc_hash::FxHashMap;
3+
use turbo_tasks::{ResolvedVc, ValueToString, Vc};
44
use turbo_tasks_hash::hash_xxh3_hash64;
55

66
use super::ModuleId;
7-
use crate::ident::AssetIdent;
7+
use crate::{
8+
ident::AssetIdent,
9+
issue::{module::ModuleIssue, IssueExt, StyledString},
10+
};
811

912
#[turbo_tasks::value_trait]
1013
pub trait ModuleIdStrategy {
@@ -32,25 +35,43 @@ impl ModuleIdStrategy for DevModuleIdStrategy {
3235
}
3336
}
3437

35-
#[turbo_tasks::value]
38+
#[turbo_tasks::value(shared)]
3639
pub struct GlobalModuleIdStrategy {
37-
module_id_map: FxIndexMap<RcStr, ModuleId>,
38-
}
39-
40-
impl GlobalModuleIdStrategy {
41-
pub async fn new(module_id_map: FxIndexMap<RcStr, ModuleId>) -> Result<Vc<Self>> {
42-
Ok(GlobalModuleIdStrategy { module_id_map }.cell())
43-
}
40+
pub module_id_map: FxHashMap<ResolvedVc<AssetIdent>, u64>,
4441
}
4542

4643
#[turbo_tasks::value_impl]
4744
impl ModuleIdStrategy for GlobalModuleIdStrategy {
4845
#[turbo_tasks::function]
49-
async fn get_module_id(&self, ident: Vc<AssetIdent>) -> Result<Vc<ModuleId>> {
50-
let ident_string = ident.to_string().await?.clone_value();
51-
if let Some(module_id) = self.module_id_map.get(&ident_string) {
52-
return Ok(module_id.clone().cell());
46+
async fn get_module_id(&self, ident: ResolvedVc<AssetIdent>) -> Result<Vc<ModuleId>> {
47+
if let Some(module_id) = self.module_id_map.get(&ident) {
48+
const JS_MAX_SAFE_INTEGER: u64 = (1u64 << 53) - 1;
49+
if *module_id > JS_MAX_SAFE_INTEGER {
50+
bail!("Numeric module id is too large: {}", module_id);
51+
}
52+
return Ok(ModuleId::Number(*module_id).cell());
5353
}
54+
55+
let ident_string = ident.to_string().await?;
56+
if !ident_string.ends_with("[app-client] (ecmascript, next/dynamic entry)") {
57+
// TODO: This shouldn't happen, but is a temporary workaround to ignore next/dynamic
58+
// imports of a server component from another server component.
59+
60+
ModuleIssue {
61+
ident,
62+
title: StyledString::Text(
63+
format!("ModuleId not found for ident: {:?}", ident_string).into(),
64+
)
65+
.resolved_cell(),
66+
description: StyledString::Text(
67+
format!("ModuleId not found for ident: {:?}", ident_string).into(),
68+
)
69+
.resolved_cell(),
70+
}
71+
.resolved_cell()
72+
.emit();
73+
}
74+
5475
Ok(ModuleId::String(
5576
hash_xxh3_hash64(ident.to_string().await?)
5677
.to_string()

0 commit comments

Comments
 (0)