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

Turbopack: add support for an asset prefix (and basePath in Next.js) #6036

Merged
merged 4 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
33 changes: 32 additions & 1 deletion crates/turbopack-build/src/chunking_context.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use anyhow::{bail, Result};
use anyhow::{bail, Context, Result};
use indexmap::IndexSet;
use serde::{Deserialize, Serialize};
use turbo_tasks::{
Expand Down Expand Up @@ -51,6 +51,11 @@ pub struct BuildChunkingContextBuilder {
}

impl BuildChunkingContextBuilder {
pub fn asset_prefix(mut self, asset_prefix: Vc<Option<String>>) -> Self {
self.chunking_context.asset_prefix = asset_prefix;
self
}

pub fn minify_type(mut self, minify_type: MinifyType) -> Self {
self.chunking_context.minify_type = minify_type;
self
Expand Down Expand Up @@ -81,10 +86,14 @@ pub struct BuildChunkingContext {
context_path: Vc<FileSystemPath>,
/// This path is used to compute the url to request chunks or assets from
output_root: Vc<FileSystemPath>,
/// This path is used to compute the url to request chunks or assets from
client_root: Vc<FileSystemPath>,
/// Chunks are placed at this path
chunk_root_path: Vc<FileSystemPath>,
/// Static assets are placed at this path
asset_root_path: Vc<FileSystemPath>,
/// Static assets requested from this url base
asset_prefix: Vc<Option<String>>,
/// Layer name within this context
layer: Option<String>,
/// The environment chunks will be evaluated in.
Expand All @@ -100,6 +109,7 @@ impl BuildChunkingContext {
pub fn builder(
context_path: Vc<FileSystemPath>,
output_root: Vc<FileSystemPath>,
client_root: Vc<FileSystemPath>,
chunk_root_path: Vc<FileSystemPath>,
asset_root_path: Vc<FileSystemPath>,
environment: Vc<Environment>,
Expand All @@ -108,8 +118,10 @@ impl BuildChunkingContext {
chunking_context: BuildChunkingContext {
context_path,
output_root,
client_root,
chunk_root_path,
asset_root_path,
asset_prefix: Default::default(),
layer: None,
environment,
runtime_type: Default::default(),
Expand Down Expand Up @@ -243,6 +255,25 @@ impl ChunkingContext for BuildChunkingContext {
self.environment
}

#[turbo_tasks::function]
async fn asset_url(self: Vc<Self>, ident: Vc<AssetIdent>) -> Result<Vc<String>> {
let this = self.await?;
let asset_path = ident.path().await?.to_string();
let asset_path = asset_path
.strip_prefix(&format!("{}/", this.client_root.await?.path))
.context("expected client root to contain asset path")?;

Ok(Vc::cell(format!(
"{}{}",
this.asset_prefix
.await?
.as_ref()
.map(|s| s.to_owned())
.unwrap_or_else(|| "/".to_owned()),
asset_path
Comment on lines +271 to +272
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't need to become an owned value (and clones the string).

That should do it:

.as_ref()
..unwrap_or("/")

)))
}

#[turbo_tasks::function]
async fn chunk_path(
&self,
Expand Down
1 change: 1 addition & 0 deletions crates/turbopack-cli/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ async fn build_internal(
build_output_root,
build_output_root,
build_output_root,
build_output_root,
env,
)
.minify_type(minify_type)
Expand Down
5 changes: 5 additions & 0 deletions crates/turbopack-core/src/chunk/chunking_context.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use anyhow::Result;
use turbo_tasks::Vc;
use turbo_tasks_fs::FileSystemPath;

Expand Down Expand Up @@ -35,6 +36,10 @@ pub trait ChunkingContext {
asset_b: Vc<Box<dyn Module>>,
) -> Vc<bool>;

/// Returns a URL (relative or absolute, depending on the asset prefix) to
/// the static asset based on its `ident`.
fn asset_url(self: Vc<Self>, ident: Vc<AssetIdent>) -> Result<Vc<String>>;

fn asset_path(
self: Vc<Self>,
content_hash: String,
Expand Down
30 changes: 29 additions & 1 deletion crates/turbopack-dev/src/chunking_context.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use anyhow::{bail, Result};
use anyhow::{bail, Context, Result};
use indexmap::IndexSet;
use turbo_tasks::{
graph::{AdjacencyMap, GraphTraversal},
Expand Down Expand Up @@ -36,6 +36,11 @@ impl DevChunkingContextBuilder {
self
}

pub fn asset_base_path(mut self, asset_base_path: Vc<Option<String>>) -> Self {
self.chunking_context.asset_base_path = asset_base_path;
self
}

pub fn chunk_base_path(mut self, chunk_base_path: Vc<Option<String>>) -> Self {
self.chunking_context.chunk_base_path = chunk_base_path;
self
Expand Down Expand Up @@ -90,6 +95,9 @@ pub struct DevChunkingContext {
/// Base path that will be prepended to all chunk URLs when loading them.
/// This path will not appear in chunk paths or chunk data.
chunk_base_path: Vc<Option<String>>,
/// URL prefix that will be prepended to all static asset URLs when loading
/// them.
asset_base_path: Vc<Option<String>>,
/// Layer name within this context
layer: Option<String>,
/// Enable HMR for this chunking
Expand Down Expand Up @@ -117,6 +125,7 @@ impl DevChunkingContext {
reference_css_chunk_source_maps: true,
asset_root_path,
chunk_base_path: Default::default(),
asset_base_path: Default::default(),
layer: None,
enable_hot_module_replacement: false,
environment,
Expand Down Expand Up @@ -234,6 +243,25 @@ impl ChunkingContext for DevChunkingContext {
Ok(root_path.join(name.clone_value()))
}

#[turbo_tasks::function]
async fn asset_url(self: Vc<Self>, ident: Vc<AssetIdent>) -> Result<Vc<String>> {
let this = self.await?;
let asset_path = ident.path().await?.to_string();
let asset_path = asset_path
.strip_prefix(&format!("{}/", this.output_root.await?.path))
.context("expected output_root to contain asset path")?;

Ok(Vc::cell(format!(
"{}{}",
this.asset_base_path
.await?
.as_ref()
.map(|s| s.as_str())
.unwrap_or("/"),
asset_path
)))
}

#[turbo_tasks::function]
async fn reference_chunk_source_maps(
&self,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ function commonJsRequireContext(
}

function fetchWebAssembly(wasmChunkPath: ChunkPath) {
const chunkUrl = `/${getChunkRelativeUrl(wasmChunkPath)}`;

return fetch(chunkUrl);
return fetch(getChunkRelativeUrl(wasmChunkPath));
}

async function loadWebAssembly(
Expand Down Expand Up @@ -124,7 +122,7 @@ async function loadWebAssemblyModule(
.map((p) => encodeURIComponent(p))
.join("/");

const chunkUrl = `/${getChunkRelativeUrl(encodedChunkPath)}`;
const chunkUrl = getChunkRelativeUrl(encodedChunkPath);

const previousLinks = document.querySelectorAll(
`link[rel=stylesheet][href^="${chunkUrl}"]`
Expand Down Expand Up @@ -224,7 +222,7 @@ async function loadWebAssemblyModule(
return resolver.promise;
}

const chunkUrl = `/${getChunkRelativeUrl(chunkPath)}`;
const chunkUrl = getChunkRelativeUrl(chunkPath);

if (chunkPath.endsWith(".css")) {
const link = document.createElement("link");
Expand Down
10 changes: 6 additions & 4 deletions crates/turbopack-static/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,12 @@ impl EcmascriptChunkItem for ModuleChunkItem {
Ok(EcmascriptChunkItemContent {
inner_code: format!(
"__turbopack_export_value__({path});",
path = StringifyJs(&format_args!(
"/{}",
&*self.static_asset.ident().path().await?
))
path = StringifyJs(
&self
.chunking_context
.asset_url(self.static_asset.ident())
.await?
)
)
.into(),
..Default::default()
Expand Down
1 change: 1 addition & 0 deletions crates/turbopack-tests/tests/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ async fn run_test(resource: String) -> Result<Vc<FileSystemPath>> {
BuildChunkingContext::builder(
project_root,
path,
path,
chunk_root_path,
static_root_path,
env,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

Loading