diff --git a/crates/node-file-trace/src/nft_json.rs b/crates/node-file-trace/src/nft_json.rs index 38d88d0d2132f..c79650189a9a2 100644 --- a/crates/node-file-trace/src/nft_json.rs +++ b/crates/node-file-trace/src/nft_json.rs @@ -4,6 +4,7 @@ use turbo_tasks_fs::{File, FileSystem}; use turbopack_core::{ asset::{Asset, AssetContentVc, AssetVc}, ident::AssetIdentVc, + output::{OutputAsset, OutputAssetVc}, reference::all_assets, }; @@ -20,6 +21,9 @@ impl NftJsonAssetVc { } } +#[turbo_tasks::value_impl] +impl OutputAsset for NftJsonAsset {} + #[turbo_tasks::value_impl] impl Asset for NftJsonAsset { #[turbo_tasks::function] diff --git a/crates/turbopack-build/src/chunking_context.rs b/crates/turbopack-build/src/chunking_context.rs index ebd5611427dee..090d07e1b9635 100644 --- a/crates/turbopack-build/src/chunking_context.rs +++ b/crates/turbopack-build/src/chunking_context.rs @@ -7,13 +7,14 @@ use turbo_tasks::{ }; use turbo_tasks_fs::FileSystemPathVc; use turbopack_core::{ - asset::{Asset, AssetVc, AssetsVc}, + asset::{Asset, AssetVc}, chunk::{ Chunk, ChunkVc, ChunkableModule, ChunkingContext, ChunkingContextVc, ChunksVc, EvaluatableAssetsVc, }, environment::EnvironmentVc, ident::AssetIdentVc, + output::{OutputAssetVc, OutputAssetsVc}, }; use turbopack_css::chunk::CssChunkVc; use turbopack_ecmascript::chunk::{ @@ -119,7 +120,7 @@ impl BuildChunkingContextVc { path: FileSystemPathVc, module: EcmascriptChunkPlaceableVc, evaluatable_assets: EvaluatableAssetsVc, - ) -> Result { + ) -> Result { let entry_chunk = module.as_root_chunk(self_vc.into()); let other_chunks = self_vc @@ -129,7 +130,7 @@ impl BuildChunkingContextVc { let asset = EcmascriptBuildNodeEntryChunkVc::new( path, self_vc, - AssetsVc::cell(other_chunks), + OutputAssetsVc::cell(other_chunks), evaluatable_assets, module, ) @@ -139,12 +140,14 @@ impl BuildChunkingContextVc { } #[turbo_tasks::function] - async fn generate_chunk(self, chunk: ChunkVc) -> Result { + async fn generate_chunk(self, chunk: ChunkVc) -> Result { Ok( if let Some(ecmascript_chunk) = EcmascriptChunkVc::resolve_from(chunk).await? { EcmascriptBuildNodeChunkVc::new(self, ecmascript_chunk).into() + } else if let Some(output_asset) = OutputAssetVc::resolve_from(chunk).await? { + output_asset } else { - chunk.into() + bail!("Unable to generate output asset for chunk"); }, ) } @@ -155,7 +158,7 @@ impl BuildChunkingContextVc { self, entry_chunk: ChunkVc, evaluatable_assets: EvaluatableAssetsVc, - ) -> Result> { + ) -> Result> { let evaluatable_assets_ref = evaluatable_assets.await?; let mut chunks: IndexSet<_> = evaluatable_assets_ref @@ -270,18 +273,18 @@ impl ChunkingContext for BuildChunkingContext { async fn chunk_group( self_vc: BuildChunkingContextVc, entry_chunk: ChunkVc, - ) -> Result { + ) -> Result { let parallel_chunks = get_parallel_chunks([entry_chunk]).await?; let optimized_chunks = get_optimized_chunks(parallel_chunks).await?; - let assets: Vec = optimized_chunks + let assets: Vec = optimized_chunks .await? .iter() .map(|chunk| self_vc.generate_chunk(*chunk)) .collect(); - Ok(AssetsVc::cell(assets)) + Ok(OutputAssetsVc::cell(assets)) } #[turbo_tasks::function] @@ -289,7 +292,7 @@ impl ChunkingContext for BuildChunkingContext { _self_vc: BuildChunkingContextVc, _entry_chunk: ChunkVc, _evaluatable_assets: EvaluatableAssetsVc, - ) -> Result { + ) -> Result { // TODO(alexkirsz) This method should be part of a separate trait that is // only implemented for client/edge runtimes. bail!("the build chunking context does not support evaluated chunk groups") diff --git a/crates/turbopack-build/src/ecmascript/node/chunk.rs b/crates/turbopack-build/src/ecmascript/node/chunk.rs index e677cdb465e48..b65e3795b36ec 100644 --- a/crates/turbopack-build/src/ecmascript/node/chunk.rs +++ b/crates/turbopack-build/src/ecmascript/node/chunk.rs @@ -6,6 +6,7 @@ use turbopack_core::{ chunk::ChunkingContext, ident::AssetIdentVc, introspect::{Introspectable, IntrospectableChildrenVc, IntrospectableVc}, + output::{OutputAsset, OutputAssetVc}, reference::AssetReferencesVc, source_map::{ GenerateSourceMap, GenerateSourceMapVc, OptionSourceMapVc, SourceMapAssetReferenceVc, @@ -62,6 +63,9 @@ impl EcmascriptBuildNodeChunkVc { } } +#[turbo_tasks::value_impl] +impl OutputAsset for EcmascriptBuildNodeChunk {} + #[turbo_tasks::value_impl] impl Asset for EcmascriptBuildNodeChunk { #[turbo_tasks::function] diff --git a/crates/turbopack-build/src/ecmascript/node/entry/chunk.rs b/crates/turbopack-build/src/ecmascript/node/entry/chunk.rs index 2b573d8a18c14..e24c6e4f304d9 100644 --- a/crates/turbopack-build/src/ecmascript/node/entry/chunk.rs +++ b/crates/turbopack-build/src/ecmascript/node/entry/chunk.rs @@ -5,10 +5,11 @@ use indoc::writedoc; use turbo_tasks::{primitives::StringVc, ValueToString, ValueToStringVc}; use turbo_tasks_fs::{File, FileSystemPathVc}; use turbopack_core::{ - asset::{Asset, AssetContentVc, AssetVc, AssetsVc}, + asset::{Asset, AssetContentVc, AssetVc}, chunk::{ChunkingContext, EvaluatableAssetsVc}, code_builder::{CodeBuilder, CodeVc}, ident::AssetIdentVc, + output::{OutputAsset, OutputAssetVc, OutputAssetsVc}, reference::{AssetReferencesVc, SingleAssetReferenceVc}, source_map::{ GenerateSourceMap, GenerateSourceMapVc, OptionSourceMapVc, SourceMapAssetReferenceVc, @@ -28,7 +29,7 @@ use crate::BuildChunkingContextVc; pub(crate) struct EcmascriptBuildNodeEntryChunk { path: FileSystemPathVc, chunking_context: BuildChunkingContextVc, - other_chunks: AssetsVc, + other_chunks: OutputAssetsVc, evaluatable_assets: EvaluatableAssetsVc, exported_module: EcmascriptChunkPlaceableVc, } @@ -40,7 +41,7 @@ impl EcmascriptBuildNodeEntryChunkVc { pub fn new( path: FileSystemPathVc, chunking_context: BuildChunkingContextVc, - other_chunks: AssetsVc, + other_chunks: OutputAssetsVc, evaluatable_assets: EvaluatableAssetsVc, exported_module: EcmascriptChunkPlaceableVc, ) -> Self { @@ -181,6 +182,9 @@ fn chunk_reference_description() -> StringVc { StringVc::cell("chunk".to_string()) } +#[turbo_tasks::value_impl] +impl OutputAsset for EcmascriptBuildNodeEntryChunk {} + #[turbo_tasks::value_impl] impl Asset for EcmascriptBuildNodeEntryChunk { #[turbo_tasks::function] @@ -202,9 +206,10 @@ impl Asset for EcmascriptBuildNodeEntryChunk { } let other_chunks = this.other_chunks.await?; - for other_chunk in &*other_chunks { + for &other_chunk in &*other_chunks { references.push( - SingleAssetReferenceVc::new(*other_chunk, chunk_reference_description()).into(), + SingleAssetReferenceVc::new(other_chunk.into(), chunk_reference_description()) + .into(), ); } diff --git a/crates/turbopack-build/src/ecmascript/node/entry/runtime.rs b/crates/turbopack-build/src/ecmascript/node/entry/runtime.rs index ed016523961f4..01b3896e039b6 100644 --- a/crates/turbopack-build/src/ecmascript/node/entry/runtime.rs +++ b/crates/turbopack-build/src/ecmascript/node/entry/runtime.rs @@ -9,6 +9,7 @@ use turbopack_core::{ chunk::ChunkingContext, code_builder::{CodeBuilder, CodeVc}, ident::AssetIdentVc, + output::{OutputAsset, OutputAssetVc}, reference::{AssetReference, AssetReferenceVc, AssetReferencesVc}, resolve::{ResolveResult, ResolveResultVc}, source_map::{ @@ -88,6 +89,9 @@ impl ValueToString for EcmascriptBuildNodeRuntimeChunk { } } +#[turbo_tasks::value_impl] +impl OutputAsset for EcmascriptBuildNodeRuntimeChunk {} + #[turbo_tasks::value_impl] impl Asset for EcmascriptBuildNodeRuntimeChunk { #[turbo_tasks::function] diff --git a/crates/turbopack-core/src/chunk/chunking_context.rs b/crates/turbopack-core/src/chunk/chunking_context.rs index 4eb5de3bca457..633e98779b263 100644 --- a/crates/turbopack-core/src/chunk/chunking_context.rs +++ b/crates/turbopack-core/src/chunk/chunking_context.rs @@ -6,9 +6,7 @@ use turbo_tasks_fs::FileSystemPathVc; use super::{ChunkVc, EvaluatableAssetsVc}; use crate::{ - asset::{AssetVc, AssetsVc}, - environment::EnvironmentVc, - ident::AssetIdentVc, + asset::AssetVc, environment::EnvironmentVc, ident::AssetIdentVc, output::OutputAssetsVc, }; /// A context for the chunking that influences the way chunks are created @@ -49,11 +47,11 @@ pub trait ChunkingContext { fn with_layer(&self, layer: &str) -> ChunkingContextVc; - fn chunk_group(&self, entry: ChunkVc) -> AssetsVc; + fn chunk_group(&self, entry: ChunkVc) -> OutputAssetsVc; fn evaluated_chunk_group( &self, entry: ChunkVc, evaluatable_assets: EvaluatableAssetsVc, - ) -> AssetsVc; + ) -> OutputAssetsVc; } diff --git a/crates/turbopack-core/src/chunk/data.rs b/crates/turbopack-core/src/chunk/data.rs index 61b5b27a1bac3..9a3279d333842 100644 --- a/crates/turbopack-core/src/chunk/data.rs +++ b/crates/turbopack-core/src/chunk/data.rs @@ -3,8 +3,9 @@ use turbo_tasks::{primitives::StringVc, TryJoinIterExt}; use turbo_tasks_fs::FileSystemPathVc; use crate::{ - asset::{Asset, AssetVc, AssetsVc}, + asset::Asset, chunk::{ModuleIdReadRef, OutputChunk, OutputChunkRuntimeInfo, OutputChunkVc}, + output::{OutputAssetVc, OutputAssetsVc}, reference::{AssetReferencesVc, SingleAssetReferenceVc}, }; @@ -37,7 +38,7 @@ impl ChunkDataVc { #[turbo_tasks::function] pub async fn from_asset( output_root: FileSystemPathVc, - chunk: AssetVc, + chunk: OutputAssetVc, ) -> Result { let output_root = output_root.await?; let path = chunk.ident().path().await?; @@ -127,7 +128,7 @@ impl ChunkDataVc { #[turbo_tasks::function] pub async fn from_assets( output_root: FileSystemPathVc, - chunks: AssetsVc, + chunks: OutputAssetsVc, ) -> Result { Ok(ChunksDataVc::cell( chunks diff --git a/crates/turbopack-core/src/chunk/mod.rs b/crates/turbopack-core/src/chunk/mod.rs index d06b361791add..7ecc0db372bc9 100644 --- a/crates/turbopack-core/src/chunk/mod.rs +++ b/crates/turbopack-core/src/chunk/mod.rs @@ -39,6 +39,7 @@ use crate::{ asset::{Asset, AssetVc, AssetsVc}, ident::AssetIdentVc, module::{Module, ModuleVc}, + output::OutputAssetsVc, reference::{AssetReference, AssetReferenceVc, AssetReferencesVc}, resolve::{PrimaryResolveResult, ResolveResult, ResolveResultVc}, }; @@ -208,7 +209,7 @@ impl ChunkGroupReferenceVc { } #[turbo_tasks::function] - async fn chunks(self) -> Result { + async fn chunks(self) -> Result { let this = self.await?; Ok(this.chunking_context.chunk_group(this.entry)) } @@ -218,7 +219,7 @@ impl ChunkGroupReferenceVc { impl AssetReference for ChunkGroupReference { #[turbo_tasks::function] async fn resolve_reference(self_vc: ChunkGroupReferenceVc) -> Result { - let set = self_vc.chunks().await?.clone_value(); + let set = self_vc.chunks().await?.iter().map(|&c| c.into()).collect(); Ok(ResolveResult::assets(set).into()) } } diff --git a/crates/turbopack-core/src/lib.rs b/crates/turbopack-core/src/lib.rs index 3c27f998859b8..51c09f80feaa8 100644 --- a/crates/turbopack-core/src/lib.rs +++ b/crates/turbopack-core/src/lib.rs @@ -18,9 +18,11 @@ pub mod ident; pub mod introspect; pub mod issue; pub mod module; +pub mod output; pub mod package_json; pub mod proxied_asset; pub mod raw_module; +pub mod raw_output; pub mod reference; pub mod reference_type; pub mod resolve; diff --git a/crates/turbopack-core/src/output.rs b/crates/turbopack-core/src/output.rs new file mode 100644 index 0000000000000..8e8114070d442 --- /dev/null +++ b/crates/turbopack-core/src/output.rs @@ -0,0 +1,29 @@ +use anyhow::{Context, Result}; + +use crate::asset::{Asset, AssetVc}; + +/// An asset that should be outputted, e. g. written to disk or served from a +/// server. +#[turbo_tasks::value_trait] +pub trait OutputAsset: Asset {} + +#[turbo_tasks::value(transparent)] +pub struct OutputAssets(Vec); + +#[turbo_tasks::value_impl] +impl OutputAssetsVc { + #[turbo_tasks::function] + pub fn empty() -> Self { + Self::cell(Vec::new()) + } +} + +/// This is a temporary function that should be removed once the [OutputAsset] +/// trait completely replaces the [Asset] trait. +/// TODO make this function unnecessary +#[turbo_tasks::function] +pub async fn asset_to_output_asset(asset: AssetVc) -> Result { + OutputAssetVc::resolve_from(asset) + .await? + .context("Asset must be a OutputAsset") +} diff --git a/crates/turbopack-core/src/proxied_asset.rs b/crates/turbopack-core/src/proxied_asset.rs index 7d7455e6fcba7..12ce08f845c58 100644 --- a/crates/turbopack-core/src/proxied_asset.rs +++ b/crates/turbopack-core/src/proxied_asset.rs @@ -4,6 +4,7 @@ use turbo_tasks_fs::FileSystemPathVc; use crate::{ asset::{Asset, AssetContentVc, AssetVc}, ident::AssetIdentVc, + output::{OutputAsset, OutputAssetVc}, reference::AssetReferencesVc, version::VersionedContentVc, }; @@ -27,6 +28,9 @@ impl ProxiedAssetVc { } } +#[turbo_tasks::value_impl] +impl OutputAsset for ProxiedAsset {} + #[turbo_tasks::value_impl] impl Asset for ProxiedAsset { #[turbo_tasks::function] diff --git a/crates/turbopack-core/src/raw_output.rs b/crates/turbopack-core/src/raw_output.rs new file mode 100644 index 0000000000000..7eecf17146fd1 --- /dev/null +++ b/crates/turbopack-core/src/raw_output.rs @@ -0,0 +1,37 @@ +use crate::{ + asset::{Asset, AssetContentVc, AssetVc}, + ident::AssetIdentVc, + output::{OutputAsset, OutputAssetVc}, + source::SourceVc, +}; + +/// A module where source code doesn't need to be parsed but can be used as is. +/// This module has no references to other modules. +#[turbo_tasks::value] +pub struct RawOutput { + source: SourceVc, +} + +#[turbo_tasks::value_impl] +impl OutputAsset for RawOutput {} + +#[turbo_tasks::value_impl] +impl Asset for RawOutput { + #[turbo_tasks::function] + fn ident(&self) -> AssetIdentVc { + self.source.ident() + } + + #[turbo_tasks::function] + fn content(&self) -> AssetContentVc { + self.source.content() + } +} + +#[turbo_tasks::value_impl] +impl RawOutputVc { + #[turbo_tasks::function] + pub fn new(source: SourceVc) -> RawOutputVc { + RawOutput { source }.cell() + } +} diff --git a/crates/turbopack-core/src/source_map/source_map_asset.rs b/crates/turbopack-core/src/source_map/source_map_asset.rs index a8a1381f8b892..b6e76fc6180a0 100644 --- a/crates/turbopack-core/src/source_map/source_map_asset.rs +++ b/crates/turbopack-core/src/source_map/source_map_asset.rs @@ -7,6 +7,7 @@ use crate::{ asset::{Asset, AssetContentVc, AssetVc}, ident::AssetIdentVc, introspect::{Introspectable, IntrospectableChildrenVc, IntrospectableVc}, + output::{OutputAsset, OutputAssetVc}, reference::{AssetReference, AssetReferenceVc}, resolve::{ResolveResult, ResolveResultVc}, source_map::{GenerateSourceMap, GenerateSourceMapVc, SourceMapVc}, @@ -26,6 +27,9 @@ impl SourceMapAssetVc { } } +#[turbo_tasks::value_impl] +impl OutputAsset for SourceMapAsset {} + #[turbo_tasks::value_impl] impl Asset for SourceMapAsset { #[turbo_tasks::function] diff --git a/crates/turbopack-css/src/chunk/mod.rs b/crates/turbopack-css/src/chunk/mod.rs index 3caa7d8e82ecd..6f8729c9e92cc 100644 --- a/crates/turbopack-css/src/chunk/mod.rs +++ b/crates/turbopack-css/src/chunk/mod.rs @@ -23,6 +23,7 @@ use turbopack_core::{ Introspectable, IntrospectableChildrenVc, IntrospectableVc, }, module::{Module, ModuleVc}, + output::{OutputAsset, OutputAssetVc}, reference::{AssetReference, AssetReferenceVc, AssetReferencesVc}, resolve::PrimaryResolveResult, source_map::{GenerateSourceMap, GenerateSourceMapVc, OptionSourceMapVc}, @@ -354,6 +355,9 @@ impl OutputChunk for CssChunk { } } +#[turbo_tasks::value_impl] +impl OutputAsset for CssChunk {} + #[turbo_tasks::value_impl] impl Asset for CssChunk { #[turbo_tasks::function] diff --git a/crates/turbopack-css/src/chunk/single_item_chunk/chunk.rs b/crates/turbopack-css/src/chunk/single_item_chunk/chunk.rs index 34138feb842e9..e8a36086da5e3 100644 --- a/crates/turbopack-css/src/chunk/single_item_chunk/chunk.rs +++ b/crates/turbopack-css/src/chunk/single_item_chunk/chunk.rs @@ -9,6 +9,7 @@ use turbopack_core::{ code_builder::{CodeBuilder, CodeVc}, ident::AssetIdentVc, introspect::{Introspectable, IntrospectableVc}, + output::{OutputAsset, OutputAssetVc}, reference::AssetReferencesVc, source_map::{GenerateSourceMap, GenerateSourceMapVc, OptionSourceMapVc}, }; @@ -84,6 +85,9 @@ fn single_item_modifier() -> StringVc { StringVc::cell("single item css chunk".to_string()) } +#[turbo_tasks::value_impl] +impl OutputAsset for SingleItemCssChunk {} + #[turbo_tasks::value_impl] impl Asset for SingleItemCssChunk { #[turbo_tasks::function] diff --git a/crates/turbopack-css/src/chunk/single_item_chunk/source_map.rs b/crates/turbopack-css/src/chunk/single_item_chunk/source_map.rs index ad2a6949b7ddc..1890fb210eb63 100644 --- a/crates/turbopack-css/src/chunk/single_item_chunk/source_map.rs +++ b/crates/turbopack-css/src/chunk/single_item_chunk/source_map.rs @@ -5,6 +5,7 @@ use turbopack_core::{ asset::{Asset, AssetContentVc, AssetVc}, chunk::Chunk, ident::AssetIdentVc, + output::{OutputAsset, OutputAssetVc}, reference::{AssetReference, AssetReferenceVc}, resolve::{ResolveResult, ResolveResultVc}, source_map::{GenerateSourceMap, SourceMapVc}, @@ -26,6 +27,9 @@ impl SingleItemCssChunkSourceMapAssetVc { } } +#[turbo_tasks::value_impl] +impl OutputAsset for SingleItemCssChunkSourceMapAsset {} + #[turbo_tasks::value_impl] impl Asset for SingleItemCssChunkSourceMapAsset { #[turbo_tasks::function] diff --git a/crates/turbopack-css/src/chunk/source_map.rs b/crates/turbopack-css/src/chunk/source_map.rs index 12b8d7e2aed94..3a4dc11b1d1c7 100644 --- a/crates/turbopack-css/src/chunk/source_map.rs +++ b/crates/turbopack-css/src/chunk/source_map.rs @@ -5,6 +5,7 @@ use turbopack_core::{ asset::{Asset, AssetContentVc, AssetVc}, chunk::Chunk, ident::AssetIdentVc, + output::{OutputAsset, OutputAssetVc}, reference::{AssetReference, AssetReferenceVc}, resolve::{ResolveResult, ResolveResultVc}, source_map::{GenerateSourceMap, SourceMapVc}, @@ -26,6 +27,9 @@ impl CssChunkSourceMapAssetVc { } } +#[turbo_tasks::value_impl] +impl OutputAsset for CssChunkSourceMapAsset {} + #[turbo_tasks::value_impl] impl Asset for CssChunkSourceMapAsset { #[turbo_tasks::function] diff --git a/crates/turbopack-dev-server/src/html.rs b/crates/turbopack-dev-server/src/html.rs index 3f10271e73db4..19fee36d39b8a 100644 --- a/crates/turbopack-dev-server/src/html.rs +++ b/crates/turbopack-dev-server/src/html.rs @@ -4,11 +4,12 @@ use turbo_tasks::{primitives::StringVc, TryJoinIterExt}; use turbo_tasks_fs::{File, FileSystemPathVc}; use turbo_tasks_hash::{encode_hex, Xxh3Hash64Hasher}; use turbopack_core::{ - asset::{Asset, AssetContentVc, AssetVc, AssetsVc}, + asset::{Asset, AssetContentVc, AssetVc}, chunk::{ ChunkableModule, ChunkableModuleVc, ChunkingContext, ChunkingContextVc, EvaluatableAssetsVc, }, ident::AssetIdentVc, + output::{OutputAsset, OutputAssetVc, OutputAssetsVc}, reference::{AssetReferencesVc, SingleAssetReferenceVc}, version::{Version, VersionVc, VersionedContent, VersionedContentVc}, }; @@ -35,6 +36,9 @@ fn dev_html_chunk_reference_description() -> StringVc { StringVc::cell("dev html chunk".to_string()) } +#[turbo_tasks::value_impl] +impl OutputAsset for DevHtmlAsset {} + #[turbo_tasks::value_impl] impl Asset for DevHtmlAsset { #[turbo_tasks::function] @@ -50,9 +54,10 @@ impl Asset for DevHtmlAsset { #[turbo_tasks::function] async fn references(self_vc: DevHtmlAssetVc) -> Result { let mut references = Vec::new(); - for chunk in &*self_vc.chunks().await? { + for &chunk in &*self_vc.chunks().await? { references.push( - SingleAssetReferenceVc::new(*chunk, dev_html_chunk_reference_description()).into(), + SingleAssetReferenceVc::new(chunk.into(), dev_html_chunk_reference_description()) + .into(), ); } Ok(AssetReferencesVc::cell(references)) @@ -136,7 +141,7 @@ impl DevHtmlAssetVc { } #[turbo_tasks::function] - async fn chunks(self) -> Result { + async fn chunks(self) -> Result { let this = self.await?; let all_assets = this @@ -161,7 +166,7 @@ impl DevHtmlAssetVc { .copied() .collect(); - Ok(AssetsVc::cell(all_assets)) + Ok(OutputAssetsVc::cell(all_assets)) } } diff --git a/crates/turbopack-dev/src/chunking_context.rs b/crates/turbopack-dev/src/chunking_context.rs index ba12520468d54..b6da1bc788659 100644 --- a/crates/turbopack-dev/src/chunking_context.rs +++ b/crates/turbopack-dev/src/chunking_context.rs @@ -1,4 +1,4 @@ -use anyhow::Result; +use anyhow::{bail, Result}; use indexmap::IndexSet; use turbo_tasks::{ graph::{AdjacencyMap, GraphTraversal}, @@ -7,13 +7,14 @@ use turbo_tasks::{ }; use turbo_tasks_fs::FileSystemPathVc; use turbopack_core::{ - asset::{Asset, AssetVc, AssetsVc}, + asset::{Asset, AssetVc}, chunk::{ Chunk, ChunkVc, ChunkableModule, ChunkingContext, ChunkingContextVc, ChunksVc, EvaluatableAssetsVc, }, environment::EnvironmentVc, ident::AssetIdentVc, + output::{OutputAssetVc, OutputAssetsVc}, }; use turbopack_css::chunk::{CssChunkVc, CssChunksVc}; use turbopack_ecmascript::chunk::{ @@ -157,9 +158,9 @@ impl DevChunkingContextVc { fn generate_evaluate_chunk( self_vc: DevChunkingContextVc, entry_chunk: ChunkVc, - other_chunks: AssetsVc, + other_chunks: OutputAssetsVc, evaluatable_assets: EvaluatableAssetsVc, - ) -> AssetVc { + ) -> OutputAssetVc { EcmascriptDevEvaluateChunkVc::new(self_vc, entry_chunk, other_chunks, evaluatable_assets) .into() } @@ -168,19 +169,21 @@ impl DevChunkingContextVc { fn generate_chunk_list_register_chunk( self_vc: DevChunkingContextVc, entry_chunk: ChunkVc, - other_chunks: AssetsVc, + other_chunks: OutputAssetsVc, source: Value, - ) -> AssetVc { + ) -> OutputAssetVc { EcmascriptDevChunkListVc::new(self_vc, entry_chunk, other_chunks, source).into() } #[turbo_tasks::function] - async fn generate_chunk(self, chunk: ChunkVc) -> Result { + async fn generate_chunk(self, chunk: ChunkVc) -> Result { Ok( if let Some(ecmascript_chunk) = EcmascriptChunkVc::resolve_from(chunk).await? { EcmascriptDevChunkVc::new(self, ecmascript_chunk).into() + } else if let Some(output_asset) = OutputAssetVc::resolve_from(chunk).await? { + output_asset } else { - chunk.into() + bail!("Unable to generate output asset for chunk"); }, ) } @@ -284,12 +287,15 @@ impl ChunkingContext for DevChunkingContext { } #[turbo_tasks::function] - async fn chunk_group(self_vc: DevChunkingContextVc, entry_chunk: ChunkVc) -> Result { + async fn chunk_group( + self_vc: DevChunkingContextVc, + entry_chunk: ChunkVc, + ) -> Result { let parallel_chunks = get_parallel_chunks([entry_chunk]).await?; let optimized_chunks = get_optimized_chunks(parallel_chunks).await?; - let mut assets: Vec = optimized_chunks + let mut assets: Vec = optimized_chunks .await? .iter() .map(|chunk| self_vc.generate_chunk(*chunk)) @@ -297,11 +303,11 @@ impl ChunkingContext for DevChunkingContext { assets.push(self_vc.generate_chunk_list_register_chunk( entry_chunk, - AssetsVc::cell(assets.clone()), + OutputAssetsVc::cell(assets.clone()), Value::new(EcmascriptDevChunkListSource::Dynamic), )); - Ok(AssetsVc::cell(assets)) + Ok(OutputAssetsVc::cell(assets)) } #[turbo_tasks::function] @@ -309,7 +315,7 @@ impl ChunkingContext for DevChunkingContext { self_vc: DevChunkingContextVc, entry_chunk: ChunkVc, evaluatable_assets: EvaluatableAssetsVc, - ) -> Result { + ) -> Result { let evaluatable_assets_ref = evaluatable_assets.await?; let mut entry_assets: IndexSet<_> = evaluatable_assets_ref @@ -333,13 +339,13 @@ impl ChunkingContext for DevChunkingContext { let optimized_chunks = get_optimized_chunks(parallel_chunks).await?; - let mut assets: Vec = optimized_chunks + let mut assets: Vec = optimized_chunks .await? .iter() .map(|chunk| self_vc.generate_chunk(*chunk)) .collect(); - let other_assets = AssetsVc::cell(assets.clone()); + let other_assets = OutputAssetsVc::cell(assets.clone()); assets.push(self_vc.generate_chunk_list_register_chunk( entry_chunk, @@ -349,7 +355,7 @@ impl ChunkingContext for DevChunkingContext { assets.push(self_vc.generate_evaluate_chunk(entry_chunk, other_assets, evaluatable_assets)); - Ok(AssetsVc::cell(assets)) + Ok(OutputAssetsVc::cell(assets)) } } diff --git a/crates/turbopack-dev/src/ecmascript/chunk.rs b/crates/turbopack-dev/src/ecmascript/chunk.rs index aa14726146ba5..891beb45e4b4b 100644 --- a/crates/turbopack-dev/src/ecmascript/chunk.rs +++ b/crates/turbopack-dev/src/ecmascript/chunk.rs @@ -9,6 +9,7 @@ use turbopack_core::{ }, ident::AssetIdentVc, introspect::{Introspectable, IntrospectableChildrenVc, IntrospectableVc}, + output::{OutputAsset, OutputAssetVc}, reference::AssetReferencesVc, source_map::{ GenerateSourceMap, GenerateSourceMapVc, OptionSourceMapVc, SourceMapAssetReferenceVc, @@ -77,6 +78,9 @@ impl EcmascriptDevChunkVc { } } +#[turbo_tasks::value_impl] +impl OutputAsset for EcmascriptDevChunk {} + #[turbo_tasks::value_impl] impl Asset for EcmascriptDevChunk { #[turbo_tasks::function] diff --git a/crates/turbopack-dev/src/ecmascript/evaluate/chunk.rs b/crates/turbopack-dev/src/ecmascript/evaluate/chunk.rs index 3ba53f403a533..f8f8d1a94113c 100644 --- a/crates/turbopack-dev/src/ecmascript/evaluate/chunk.rs +++ b/crates/turbopack-dev/src/ecmascript/evaluate/chunk.rs @@ -6,12 +6,13 @@ use serde::Serialize; use turbo_tasks::{primitives::StringVc, TryJoinIterExt, Value, ValueToString, ValueToStringVc}; use turbo_tasks_fs::File; use turbopack_core::{ - asset::{Asset, AssetContentVc, AssetVc, AssetsVc}, + asset::{Asset, AssetContentVc, AssetVc}, chunk::{ ChunkDataVc, ChunkVc, ChunkingContext, ChunksDataVc, EvaluatableAssetsVc, ModuleIdReadRef, }, code_builder::{CodeBuilder, CodeVc}, ident::AssetIdentVc, + output::{OutputAsset, OutputAssetVc, OutputAssetsVc}, reference::AssetReferencesVc, source_map::{ GenerateSourceMap, GenerateSourceMapVc, OptionSourceMapVc, SourceMapAssetReferenceVc, @@ -32,7 +33,7 @@ use crate::DevChunkingContextVc; pub(crate) struct EcmascriptDevEvaluateChunk { chunking_context: DevChunkingContextVc, entry_chunk: ChunkVc, - other_chunks: AssetsVc, + other_chunks: OutputAssetsVc, evaluatable_assets: EvaluatableAssetsVc, } @@ -43,7 +44,7 @@ impl EcmascriptDevEvaluateChunkVc { pub fn new( chunking_context: DevChunkingContextVc, entry_chunk: ChunkVc, - other_chunks: AssetsVc, + other_chunks: OutputAssetsVc, evaluatable_assets: EvaluatableAssetsVc, ) -> Self { EcmascriptDevEvaluateChunk { @@ -175,6 +176,9 @@ fn modifier() -> StringVc { StringVc::cell("ecmascript dev evaluate chunk".to_string()) } +#[turbo_tasks::value_impl] +impl OutputAsset for EcmascriptDevEvaluateChunk {} + #[turbo_tasks::value_impl] impl Asset for EcmascriptDevEvaluateChunk { #[turbo_tasks::function] diff --git a/crates/turbopack-dev/src/ecmascript/list/asset.rs b/crates/turbopack-dev/src/ecmascript/list/asset.rs index bd41f53655214..1286234afc6e1 100644 --- a/crates/turbopack-dev/src/ecmascript/list/asset.rs +++ b/crates/turbopack-dev/src/ecmascript/list/asset.rs @@ -2,9 +2,10 @@ use anyhow::Result; use serde::Serialize; use turbo_tasks::{primitives::StringVc, Value, ValueToString, ValueToStringVc}; use turbopack_core::{ - asset::{Asset, AssetContentVc, AssetVc, AssetsVc}, + asset::{Asset, AssetContentVc, AssetVc}, chunk::{ChunkVc, ChunkingContext}, ident::AssetIdentVc, + output::{OutputAsset, OutputAssetVc, OutputAssetsVc}, reference::{AssetReferencesVc, SingleAssetReferenceVc}, version::{VersionedContent, VersionedContentVc}, }; @@ -27,7 +28,7 @@ use crate::DevChunkingContextVc; pub(crate) struct EcmascriptDevChunkList { pub(super) chunking_context: DevChunkingContextVc, pub(super) entry_chunk: ChunkVc, - pub(super) chunks: AssetsVc, + pub(super) chunks: OutputAssetsVc, pub(super) source: EcmascriptDevChunkListSource, } @@ -38,7 +39,7 @@ impl EcmascriptDevChunkListVc { pub fn new( chunking_context: DevChunkingContextVc, entry_chunk: ChunkVc, - chunks: AssetsVc, + chunks: OutputAssetsVc, source: Value, ) -> Self { EcmascriptDevChunkList { @@ -74,6 +75,9 @@ fn chunk_list_chunk_reference_description() -> StringVc { StringVc::cell("chunk list chunk".to_string()) } +#[turbo_tasks::value_impl] +impl OutputAsset for EcmascriptDevChunkList {} + #[turbo_tasks::value_impl] impl Asset for EcmascriptDevChunkList { #[turbo_tasks::function] @@ -98,9 +102,12 @@ impl Asset for EcmascriptDevChunkList { self.chunks .await? .iter() - .map(|chunk| { - SingleAssetReferenceVc::new(*chunk, chunk_list_chunk_reference_description()) - .into() + .map(|&chunk| { + SingleAssetReferenceVc::new( + chunk.into(), + chunk_list_chunk_reference_description(), + ) + .into() }) .collect(), )) diff --git a/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs b/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs index 0993d063f287f..b9c5f2dee6413 100644 --- a/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs +++ b/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs @@ -3,7 +3,7 @@ use indexmap::IndexSet; use turbo_tasks::{primitives::StringVc, TryJoinIterExt, Value, ValueToString}; use turbo_tasks_fs::{File, FileSystemPathVc}; use turbopack_core::{ - asset::{Asset, AssetContentVc, AssetVc, AssetsVc}, + asset::{Asset, AssetContentVc, AssetVc}, chunk::{ availability_info::AvailabilityInfo, ChunkItem, ChunkItemVc, ChunkVc, ChunkableModule, ChunkableModuleVc, ChunkingContext, ChunkingContextVc, EvaluatableAssetsVc, @@ -14,6 +14,7 @@ use turbopack_core::{ Introspectable, IntrospectableChildrenVc, IntrospectableVc, }, module::{Module, ModuleVc}, + output::OutputAssetsVc, reference::{AssetReferenceVc, AssetReferencesVc, SingleAssetReferenceVc}, }; @@ -134,7 +135,7 @@ struct ChunkGroupFilesChunkItem { #[turbo_tasks::value_impl] impl ChunkGroupFilesChunkItemVc { #[turbo_tasks::function] - async fn chunks(self) -> Result { + async fn chunks(self) -> Result { let this = self.await?; let module = this.inner.await?; let chunks = @@ -212,7 +213,10 @@ impl ChunkItem for ChunkGroupFilesChunkItem { .iter() .copied() .map(|chunk| { - SingleAssetReferenceVc::new(chunk, chunk_group_chunk_reference_description()) + SingleAssetReferenceVc::new( + chunk.into(), + chunk_group_chunk_reference_description(), + ) }) .map(Into::into) .collect(), diff --git a/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs b/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs index 66d8d46b7cbb5..80287a98d3956 100644 --- a/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs +++ b/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs @@ -1,13 +1,14 @@ use anyhow::Result; use turbo_tasks::{primitives::StringVc, Value}; use turbopack_core::{ - asset::{Asset, AssetContentVc, AssetVc, AssetsVc}, + asset::{Asset, AssetContentVc, AssetVc}, chunk::{ availability_info::AvailabilityInfo, ChunkVc, ChunkableModule, ChunkableModuleVc, ChunkingContext, ChunkingContextVc, }, ident::AssetIdentVc, module::{Module, ModuleVc}, + output::OutputAssetsVc, reference::{AssetReferencesVc, SingleAssetReferenceVc}, }; @@ -64,13 +65,13 @@ impl ManifestChunkAssetVc { } #[turbo_tasks::function] - pub(super) async fn chunks(self) -> Result { + pub(super) async fn chunks(self) -> Result { let this = self.await?; Ok(this.chunking_context.chunk_group(self.entry_chunk())) } #[turbo_tasks::function] - pub async fn manifest_chunks(self) -> Result { + pub async fn manifest_chunks(self) -> Result { let this = self.await?; Ok(this.chunking_context.chunk_group(self.as_chunk( this.chunking_context.into(), @@ -106,8 +107,11 @@ impl Asset for ManifestChunkAsset { .iter() .copied() .map(|chunk| { - SingleAssetReferenceVc::new(chunk, manifest_chunk_reference_description()) - .into() + SingleAssetReferenceVc::new( + chunk.into(), + manifest_chunk_reference_description(), + ) + .into() }) .collect(), )) diff --git a/crates/turbopack-ecmascript/src/manifest/loader_item.rs b/crates/turbopack-ecmascript/src/manifest/loader_item.rs index a44a2255c74b8..f5cb01bd3b1de 100644 --- a/crates/turbopack-ecmascript/src/manifest/loader_item.rs +++ b/crates/turbopack-ecmascript/src/manifest/loader_item.rs @@ -82,9 +82,12 @@ impl ChunkItem for ManifestLoaderItem { let mut references: Vec<_> = chunks .await? .iter() - .map(|chunk| { - SingleAssetReferenceVc::new(*chunk, manifest_loader_chunk_reference_description()) - .into() + .map(|&chunk| { + SingleAssetReferenceVc::new( + chunk.into(), + manifest_loader_chunk_reference_description(), + ) + .into() }) .collect(); diff --git a/crates/turbopack-node/src/bootstrap.rs b/crates/turbopack-node/src/bootstrap.rs index 0c805dc32c329..982066bd5d816 100644 --- a/crates/turbopack-node/src/bootstrap.rs +++ b/crates/turbopack-node/src/bootstrap.rs @@ -4,9 +4,10 @@ use anyhow::Result; use turbo_tasks::primitives::StringVc; use turbo_tasks_fs::{File, FileSystemPathVc}; use turbopack_core::{ - asset::{Asset, AssetContentVc, AssetVc, AssetsVc}, + asset::{Asset, AssetContentVc, AssetVc}, chunk::{ChunkVc, ChunkingContext, ChunkingContextVc, EvaluatableAssetsVc}, ident::AssetIdentVc, + output::OutputAssetsVc, reference::{AssetReferencesVc, SingleAssetReferenceVc}, }; use turbopack_ecmascript::utils::StringifyJs; @@ -25,7 +26,7 @@ fn node_js_bootstrap_chunk_reference_description() -> StringVc { } impl NodeJsBootstrapAsset { - fn chunks(&self) -> AssetsVc { + fn chunks(&self) -> OutputAssetsVc { self.chunking_context .evaluated_chunk_group(self.entry, self.evaluatable_assets) } @@ -62,10 +63,10 @@ impl Asset for NodeJsBootstrapAsset { async fn references(&self) -> Result { let chunks = self.chunks().await?; let mut references = Vec::new(); - for chunk in chunks.iter() { + for &chunk in chunks.iter() { references.push( SingleAssetReferenceVc::new( - *chunk, + chunk.into(), node_js_bootstrap_chunk_reference_description(), ) .into(), diff --git a/crates/turbopack-static/src/fixed.rs b/crates/turbopack-static/src/fixed.rs index a2360130033cf..5268fa11189ef 100644 --- a/crates/turbopack-static/src/fixed.rs +++ b/crates/turbopack-static/src/fixed.rs @@ -3,6 +3,7 @@ use turbo_tasks_fs::FileSystemPathVc; use turbopack_core::{ asset::{Asset, AssetContentVc, AssetVc}, ident::AssetIdentVc, + output::{OutputAsset, OutputAssetVc}, source::SourceVc, }; @@ -26,6 +27,9 @@ impl FixedStaticAssetVc { } } +#[turbo_tasks::value_impl] +impl OutputAsset for FixedStaticAsset {} + #[turbo_tasks::value_impl] impl Asset for FixedStaticAsset { #[turbo_tasks::function] diff --git a/crates/turbopack-static/src/lib.rs b/crates/turbopack-static/src/lib.rs index 4eb34176a89be..4edd4532cebe5 100644 --- a/crates/turbopack-static/src/lib.rs +++ b/crates/turbopack-static/src/lib.rs @@ -24,6 +24,7 @@ use turbopack_core::{ context::AssetContextVc, ident::AssetIdentVc, module::{Module, ModuleVc}, + output::{OutputAsset, OutputAssetVc}, reference::{AssetReferencesVc, SingleAssetReferenceVc}, source::SourceVc, }; @@ -139,6 +140,9 @@ struct StaticAsset { source: SourceVc, } +#[turbo_tasks::value_impl] +impl OutputAsset for StaticAsset {} + #[turbo_tasks::value_impl] impl Asset for StaticAsset { #[turbo_tasks::function] diff --git a/crates/turbopack-tests/tests/snapshot.rs b/crates/turbopack-tests/tests/snapshot.rs index 6a47e84230a80..ebba6c95b4c5f 100644 --- a/crates/turbopack-tests/tests/snapshot.rs +++ b/crates/turbopack-tests/tests/snapshot.rs @@ -31,7 +31,7 @@ use turbopack::{ }; use turbopack_build::BuildChunkingContextVc; use turbopack_core::{ - asset::{Asset, AssetVc, AssetsVc}, + asset::Asset, chunk::{ ChunkableModule, ChunkableModuleVc, ChunkingContext, ChunkingContextVc, EvaluatableAssetVc, EvaluatableAssetsVc, @@ -42,6 +42,7 @@ use turbopack_core::{ environment::{BrowserEnvironment, EnvironmentVc, ExecutionEnvironment, NodeJsEnvironment}, file_source::FileSourceVc, issue::IssueVc, + output::{OutputAssetVc, OutputAssetsVc}, reference::all_referenced_assets, reference_type::{EntryReferenceSubType, ReferenceType}, source::SourceVc, @@ -327,46 +328,47 @@ async fn run_test(resource: &str) -> Result { Value::new(ReferenceType::Entry(EntryReferenceSubType::Undefined)), ); - let chunks = - if let Some(ecmascript) = EcmascriptModuleAssetVc::resolve_from(entry_module).await? { - // TODO: Load runtime entries from snapshots - match options.runtime { - Runtime::Dev => chunking_context.evaluated_chunk_group( - ecmascript.as_root_chunk(chunking_context), - runtime_entries - .unwrap_or_else(EvaluatableAssetsVc::empty) - .with_entry(ecmascript.into()), - ), - Runtime::Build => { - AssetsVc::cell(vec![BuildChunkingContextVc::resolve_from(chunking_context) - .await? - .unwrap() - .entry_chunk( - // `expected` expects a completely flat output directory. - chunk_root_path - .join( - entry_module - .ident() - .path() - .file_stem() - .await? - .as_deref() - .unwrap(), - ) - .with_extension("entry.js"), - ecmascript.into(), - runtime_entries - .unwrap_or_else(EvaluatableAssetsVc::empty) - .with_entry(ecmascript.into()), - )]) - } + let chunks = if let Some(ecmascript) = + EcmascriptModuleAssetVc::resolve_from(entry_module).await? + { + // TODO: Load runtime entries from snapshots + match options.runtime { + Runtime::Dev => chunking_context.evaluated_chunk_group( + ecmascript.as_root_chunk(chunking_context), + runtime_entries + .unwrap_or_else(EvaluatableAssetsVc::empty) + .with_entry(ecmascript.into()), + ), + Runtime::Build => { + OutputAssetsVc::cell(vec![BuildChunkingContextVc::resolve_from(chunking_context) + .await? + .unwrap() + .entry_chunk( + // `expected` expects a completely flat output directory. + chunk_root_path + .join( + entry_module + .ident() + .path() + .file_stem() + .await? + .as_deref() + .unwrap(), + ) + .with_extension("entry.js"), + ecmascript.into(), + runtime_entries + .unwrap_or_else(EvaluatableAssetsVc::empty) + .with_entry(ecmascript.into()), + )]) } - } else if let Some(chunkable) = ChunkableModuleVc::resolve_from(entry_module).await? { - chunking_context.chunk_group(chunkable.as_root_chunk(chunking_context)) - } else { - // TODO convert into a serve-able asset - bail!("Entry module is not chunkable, so it can't be used to bootstrap the application") - }; + } + } else if let Some(chunkable) = ChunkableModuleVc::resolve_from(entry_module).await? { + chunking_context.chunk_group(chunkable.as_root_chunk(chunking_context)) + } else { + // TODO convert into a serve-able asset + bail!("Entry module is not chunkable, so it can't be used to bootstrap the application") + }; let mut seen = HashSet::new(); let mut queue: VecDeque<_> = chunks.await?.iter().copied().collect(); @@ -393,10 +395,10 @@ async fn run_test(resource: &str) -> Result { } async fn walk_asset( - asset: AssetVc, + asset: OutputAssetVc, output_path: &FileSystemPathReadRef, seen: &mut HashSet, - queue: &mut VecDeque, + queue: &mut VecDeque, ) -> Result<()> { let path = asset.ident().path().resolve().await?; @@ -409,7 +411,17 @@ async fn walk_asset( diff(path, asset.content()).await?; } - queue.extend(&*all_referenced_assets(asset).await?); + queue.extend( + all_referenced_assets(asset.into()) + .await? + .iter() + .copied() + .map(|asset| async move { Ok(OutputAssetVc::resolve_from(asset).await?) }) + .try_join() + .await? + .into_iter() + .flatten(), + ); Ok(()) } diff --git a/crates/turbopack/src/rebase/mod.rs b/crates/turbopack/src/rebase/mod.rs index ed259c433db5a..8000a4e86d5eb 100644 --- a/crates/turbopack/src/rebase/mod.rs +++ b/crates/turbopack/src/rebase/mod.rs @@ -6,6 +6,7 @@ use turbo_tasks_fs::FileSystemPathVc; use turbopack_core::{ asset::{Asset, AssetContentVc, AssetVc}, ident::AssetIdentVc, + output::{OutputAsset, OutputAssetVc}, reference::{AssetReference, AssetReferenceVc, AssetReferencesVc}, resolve::ResolveResultVc, }; @@ -30,6 +31,9 @@ impl RebasedAssetVc { } } +#[turbo_tasks::value_impl] +impl OutputAsset for RebasedAsset {} + #[turbo_tasks::value_impl] impl Asset for RebasedAsset { #[turbo_tasks::function]