diff --git a/packages/next-swc/crates/next-api/src/project.rs b/packages/next-swc/crates/next-api/src/project.rs index b87f44b1ab905..0759224802159 100644 --- a/packages/next-swc/crates/next-api/src/project.rs +++ b/packages/next-swc/crates/next-api/src/project.rs @@ -292,8 +292,17 @@ impl Project { } #[turbo_tasks::function] - pub(super) fn client_relative_path(self: Vc) -> Vc { - self.client_root().join("_next".to_string()) + pub(super) async fn client_relative_path(self: Vc) -> Result> { + let next_config = self.next_config().await?; + Ok(self + .client_root() + .join( + next_config + .base_path + .clone() + .unwrap_or_else(|| "".to_string()), + ) + .join("_next".to_string())) } #[turbo_tasks::function] @@ -381,7 +390,8 @@ impl Project { let this = self.await?; Ok(get_client_chunking_context( self.project_path(), - self.client_root(), + self.client_relative_path(), + self.next_config().computed_asset_prefix(), self.client_compile_time_info().environment(), this.mode, )) @@ -392,7 +402,9 @@ impl Project { get_server_chunking_context( self.project_path(), self.node_root(), - self.client_root(), + // self.client_root(), + self.client_relative_path(), + self.next_config().computed_asset_prefix(), self.server_compile_time_info().environment(), ) } @@ -402,7 +414,7 @@ impl Project { get_edge_chunking_context( self.project_path(), self.node_root(), - self.client_root(), + self.client_relative_path(), self.edge_compile_time_info().environment(), ) } diff --git a/packages/next-swc/crates/next-build/src/next_build.rs b/packages/next-swc/crates/next-build/src/next_build.rs index 6c73fed464ee0..0a5f8327b1566 100644 --- a/packages/next-swc/crates/next-build/src/next_build.rs +++ b/packages/next-swc/crates/next-build/src/next_build.rs @@ -245,6 +245,7 @@ pub(crate) async fn next_build(options: TransientInstance) -> Resu let client_chunking_context = get_client_chunking_context( project_root, client_root, + next_config.computed_asset_prefix(), client_compile_time_info.environment(), mode, ); @@ -253,6 +254,10 @@ pub(crate) async fn next_build(options: TransientInstance) -> Resu project_root, node_root, client_root, + { + let asset_prefix = &*next_config.computed_asset_prefix().await?; + Vc::cell(Some(asset_prefix.to_string())) + }, server_compile_time_info.environment(), ); // TODO(alexkirsz) This should be the same chunking context. The layer should diff --git a/packages/next-swc/crates/next-core/src/next_client/context.rs b/packages/next-swc/crates/next-core/src/next_client/context.rs index a165be526cf0f..03c39193717d8 100644 --- a/packages/next-swc/crates/next-core/src/next_client/context.rs +++ b/packages/next-swc/crates/next-core/src/next_client/context.rs @@ -309,38 +309,40 @@ pub async fn get_client_module_options_context( } #[turbo_tasks::function] -pub fn get_client_chunking_context( +pub async fn get_client_chunking_context( project_path: Vc, client_root: Vc, + asset_prefix: Vc, environment: Vc, mode: NextMode, -) -> Vc> { - let output_root = match mode { - NextMode::DevServer => client_root, - NextMode::Development | NextMode::Build => client_root.join("_next".to_string()), - }; +) -> Result>> { let builder = DevChunkingContext::builder( project_path, - output_root, - client_root.join("_next/static/chunks".to_string()), + client_root, + client_root.join("static/chunks".to_string()), get_client_assets_path(client_root), environment, ); + let asset_prefix = &*asset_prefix.await?; + let asset_prefix: Vc> = Vc::cell(Some(asset_prefix.to_owned())); let builder = match mode { NextMode::DevServer => builder.hot_module_replacement(), NextMode::Development => builder .hot_module_replacement() - .chunk_base_path(Vc::cell(Some("_next/".to_string()))), - NextMode::Build => builder.chunk_base_path(Vc::cell(Some("_next/".to_string()))), + .chunk_base_path(asset_prefix) + .asset_prefix(asset_prefix), + NextMode::Build => builder + .chunk_base_path(asset_prefix) + .asset_prefix(asset_prefix), }; - Vc::upcast(builder.build()) + Ok(Vc::upcast(builder.build())) } #[turbo_tasks::function] pub fn get_client_assets_path(client_root: Vc) -> Vc { - client_root.join("_next/static/media".to_string()) + client_root.join("static/media".to_string()) } #[turbo_tasks::function] diff --git a/packages/next-swc/crates/next-core/src/next_config.rs b/packages/next-swc/crates/next-core/src/next_config.rs index f4c178b39bd52..f520b0ac15c7d 100644 --- a/packages/next-swc/crates/next-core/src/next_config.rs +++ b/packages/next-swc/crates/next-core/src/next_config.rs @@ -655,6 +655,23 @@ impl NextConfig { self.await?.skip_trailing_slash_redirect.unwrap_or(false), )) } + + /// Returns the final asset prefix. If an assetPrefix is set, it's used. + /// Otherwise, the basePath is used. + #[turbo_tasks::function] + pub async fn computed_asset_prefix(self: Vc) -> Result> { + let this = self.await?; + + Ok(Vc::cell( + if let Some(asset_prefix) = &this.asset_prefix { + asset_prefix.to_string() + } else if let Some(base_path) = &this.base_path { + base_path.to_string() + } else { + "".to_string() + } + "/_next/", + )) + } } fn next_configs() -> Vc> { diff --git a/packages/next-swc/crates/next-core/src/next_server/context.rs b/packages/next-swc/crates/next-core/src/next_server/context.rs index 913708f34082d..9b23fcfab1737 100644 --- a/packages/next-swc/crates/next-core/src/next_server/context.rs +++ b/packages/next-swc/crates/next-core/src/next_server/context.rs @@ -603,6 +603,7 @@ pub fn get_server_chunking_context( // TODO(alexkirsz) Is this even necessary? Are assets not always on the client chunking context // anyway? client_root: Vc, + asset_prefix: Vc>, environment: Vc, ) -> Vc { // TODO(alexkirsz) This should return a trait that can be implemented by the @@ -611,10 +612,12 @@ pub fn get_server_chunking_context( BuildChunkingContext::builder( project_path, node_root, + client_root, node_root.join("server/chunks".to_string()), - client_root.join("_next/static/media".to_string()), + client_root.join("static/media".to_string()), environment, ) + .asset_prefix(asset_prefix) .minify_type(MinifyType::NoMinify) .build() } diff --git a/packages/next-swc/crates/next-core/src/page_loader.rs b/packages/next-swc/crates/next-core/src/page_loader.rs index 9acb383bcd69b..06c21d4d2515c 100644 --- a/packages/next-swc/crates/next-core/src/page_loader.rs +++ b/packages/next-swc/crates/next-core/src/page_loader.rs @@ -182,8 +182,12 @@ fn page_loader_chunk_reference_description() -> Vc { impl OutputAsset for PageLoaderAsset { #[turbo_tasks::function] async fn ident(&self) -> Result> { - Ok(AssetIdent::from_path(self.server_root.join(format!( - "_next/static/chunks/pages{}", + let root = match *self.rebase_prefix_path.await? { + Some(prefix) => prefix, + None => self.server_root, + }; + Ok(AssetIdent::from_path(root.join(format!( + "static/chunks/pages{}", get_asset_path_from_pathname(&self.pathname.await?, ".js") )))) } diff --git a/packages/next/src/client/next-dev-turbopack.ts b/packages/next/src/client/next-dev-turbopack.ts index ba6a8f0bf4c9b..3381761de0b1b 100644 --- a/packages/next/src/client/next-dev-turbopack.ts +++ b/packages/next/src/client/next-dev-turbopack.ts @@ -29,26 +29,11 @@ initialize({ }) .then(({ assetPrefix }) => { // for the page loader - async function loadPageChunk(chunkData: any) { - if (typeof chunkData === 'string') { - const fullPath = assetPrefix + chunkData - - await __turbopack_load__(fullPath) - } else { - let fullChunkData = { - ...chunkData, - path: assetPrefix + chunkData.path, - } - - await __turbopack_load__(fullChunkData) - } - } - ;(self as any).__turbopack_load_page_chunks__ = ( page: string, chunksData: any ) => { - const chunkPromises = chunksData.map(loadPageChunk) + const chunkPromises = chunksData.map(__turbopack_load__) Promise.all(chunkPromises).catch((err) => console.error('failed to load chunks for page ' + page, err)