Skip to content

Commit

Permalink
OutputAsset trait (#5507)
Browse files Browse the repository at this point in the history
### Description

adding a trait to all assets in the output graph

next.js PR: vercel/next.js#52606
  • Loading branch information
sokra committed Jul 13, 2023
1 parent fcac7be commit 4022f2b
Show file tree
Hide file tree
Showing 30 changed files with 287 additions and 113 deletions.
4 changes: 4 additions & 0 deletions crates/node-file-trace/src/nft_json.rs
Expand Up @@ -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,
};

Expand All @@ -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]
Expand Down
23 changes: 13 additions & 10 deletions crates/turbopack-build/src/chunking_context.rs
Expand Up @@ -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::{
Expand Down Expand Up @@ -119,7 +120,7 @@ impl BuildChunkingContextVc {
path: FileSystemPathVc,
module: EcmascriptChunkPlaceableVc,
evaluatable_assets: EvaluatableAssetsVc,
) -> Result<AssetVc> {
) -> Result<OutputAssetVc> {
let entry_chunk = module.as_root_chunk(self_vc.into());

let other_chunks = self_vc
Expand All @@ -129,7 +130,7 @@ impl BuildChunkingContextVc {
let asset = EcmascriptBuildNodeEntryChunkVc::new(
path,
self_vc,
AssetsVc::cell(other_chunks),
OutputAssetsVc::cell(other_chunks),
evaluatable_assets,
module,
)
Expand All @@ -139,12 +140,14 @@ impl BuildChunkingContextVc {
}

#[turbo_tasks::function]
async fn generate_chunk(self, chunk: ChunkVc) -> Result<AssetVc> {
async fn generate_chunk(self, chunk: ChunkVc) -> Result<OutputAssetVc> {
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");
},
)
}
Expand All @@ -155,7 +158,7 @@ impl BuildChunkingContextVc {
self,
entry_chunk: ChunkVc,
evaluatable_assets: EvaluatableAssetsVc,
) -> Result<Vec<AssetVc>> {
) -> Result<Vec<OutputAssetVc>> {
let evaluatable_assets_ref = evaluatable_assets.await?;

let mut chunks: IndexSet<_> = evaluatable_assets_ref
Expand Down Expand Up @@ -270,26 +273,26 @@ impl ChunkingContext for BuildChunkingContext {
async fn chunk_group(
self_vc: BuildChunkingContextVc,
entry_chunk: ChunkVc,
) -> Result<AssetsVc> {
) -> Result<OutputAssetsVc> {
let parallel_chunks = get_parallel_chunks([entry_chunk]).await?;

let optimized_chunks = get_optimized_chunks(parallel_chunks).await?;

let assets: Vec<AssetVc> = optimized_chunks
let assets: Vec<OutputAssetVc> = optimized_chunks
.await?
.iter()
.map(|chunk| self_vc.generate_chunk(*chunk))
.collect();

Ok(AssetsVc::cell(assets))
Ok(OutputAssetsVc::cell(assets))
}

#[turbo_tasks::function]
async fn evaluated_chunk_group(
_self_vc: BuildChunkingContextVc,
_entry_chunk: ChunkVc,
_evaluatable_assets: EvaluatableAssetsVc,
) -> Result<AssetsVc> {
) -> Result<OutputAssetsVc> {
// 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")
Expand Down
4 changes: 4 additions & 0 deletions crates/turbopack-build/src/ecmascript/node/chunk.rs
Expand Up @@ -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,
Expand Down Expand Up @@ -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]
Expand Down
15 changes: 10 additions & 5 deletions crates/turbopack-build/src/ecmascript/node/entry/chunk.rs
Expand Up @@ -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,
Expand All @@ -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,
}
Expand All @@ -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 {
Expand Down Expand Up @@ -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]
Expand All @@ -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(),
);
}

Expand Down
4 changes: 4 additions & 0 deletions crates/turbopack-build/src/ecmascript/node/entry/runtime.rs
Expand Up @@ -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::{
Expand Down Expand Up @@ -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]
Expand Down
8 changes: 3 additions & 5 deletions crates/turbopack-core/src/chunk/chunking_context.rs
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
7 changes: 4 additions & 3 deletions crates/turbopack-core/src/chunk/data.rs
Expand Up @@ -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},
};

Expand Down Expand Up @@ -37,7 +38,7 @@ impl ChunkDataVc {
#[turbo_tasks::function]
pub async fn from_asset(
output_root: FileSystemPathVc,
chunk: AssetVc,
chunk: OutputAssetVc,
) -> Result<ChunkDataOptionVc> {
let output_root = output_root.await?;
let path = chunk.ident().path().await?;
Expand Down Expand Up @@ -127,7 +128,7 @@ impl ChunkDataVc {
#[turbo_tasks::function]
pub async fn from_assets(
output_root: FileSystemPathVc,
chunks: AssetsVc,
chunks: OutputAssetsVc,
) -> Result<ChunksDataVc> {
Ok(ChunksDataVc::cell(
chunks
Expand Down
5 changes: 3 additions & 2 deletions crates/turbopack-core/src/chunk/mod.rs
Expand Up @@ -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},
};
Expand Down Expand Up @@ -208,7 +209,7 @@ impl ChunkGroupReferenceVc {
}

#[turbo_tasks::function]
async fn chunks(self) -> Result<AssetsVc> {
async fn chunks(self) -> Result<OutputAssetsVc> {
let this = self.await?;
Ok(this.chunking_context.chunk_group(this.entry))
}
Expand All @@ -218,7 +219,7 @@ impl ChunkGroupReferenceVc {
impl AssetReference for ChunkGroupReference {
#[turbo_tasks::function]
async fn resolve_reference(self_vc: ChunkGroupReferenceVc) -> Result<ResolveResultVc> {
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())
}
}
Expand Down
2 changes: 2 additions & 0 deletions crates/turbopack-core/src/lib.rs
Expand Up @@ -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;
Expand Down
29 changes: 29 additions & 0 deletions 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<OutputAssetVc>);

#[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> {
OutputAssetVc::resolve_from(asset)
.await?
.context("Asset must be a OutputAsset")
}
4 changes: 4 additions & 0 deletions crates/turbopack-core/src/proxied_asset.rs
Expand Up @@ -4,6 +4,7 @@ use turbo_tasks_fs::FileSystemPathVc;
use crate::{
asset::{Asset, AssetContentVc, AssetVc},
ident::AssetIdentVc,
output::{OutputAsset, OutputAssetVc},
reference::AssetReferencesVc,
version::VersionedContentVc,
};
Expand All @@ -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]
Expand Down
37 changes: 37 additions & 0 deletions 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()
}
}
4 changes: 4 additions & 0 deletions crates/turbopack-core/src/source_map/source_map_asset.rs
Expand Up @@ -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},
Expand All @@ -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]
Expand Down

1 comment on commit 4022f2b

@vercel
Copy link

@vercel vercel bot commented on 4022f2b Jul 13, 2023

Choose a reason for hiding this comment

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

Please sign in to comment.