Skip to content

Commit

Permalink
Merge branch 'canary' into fix-redirect-type
Browse files Browse the repository at this point in the history
  • Loading branch information
ztanner authored Sep 20, 2024
2 parents 3bba5ce + d2274c1 commit 9e75a30
Show file tree
Hide file tree
Showing 8 changed files with 202 additions and 153 deletions.
8 changes: 4 additions & 4 deletions crates/next-api/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use next_core::{
all_assets_from_entries,
app_segment_config::NextSegmentConfig,
app_structure::{
get_entrypoints, Entrypoint as AppEntrypoint, Entrypoints as AppEntrypoints, LoaderTree,
MetadataItem,
get_entrypoints, AppPageLoaderTree, Entrypoint as AppEntrypoint,
Entrypoints as AppEntrypoints, MetadataItem,
},
get_edge_resolve_options_context, get_next_package,
next_app::{
Expand Down Expand Up @@ -696,7 +696,7 @@ enum AppPageEndpointType {
enum AppEndpointType {
Page {
ty: AppPageEndpointType,
loader_tree: Vc<LoaderTree>,
loader_tree: Vc<AppPageLoaderTree>,
},
Route {
path: Vc<FileSystemPath>,
Expand All @@ -717,7 +717,7 @@ struct AppEndpoint {
#[turbo_tasks::value_impl]
impl AppEndpoint {
#[turbo_tasks::function]
fn app_page_entry(&self, loader_tree: Vc<LoaderTree>) -> Vc<AppEntry> {
fn app_page_entry(&self, loader_tree: Vc<AppPageLoaderTree>) -> Vc<AppEntry> {
get_app_page_entry(
self.app_project.rsc_module_context(),
self.app_project.edge_rsc_module_context(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ use std::{

use anyhow::Result;
use indexmap::IndexMap;
use indoc::formatdoc;
use turbo_tasks::{RcStr, Value, ValueToString, Vc};
use turbo_tasks::{RcStr, Value, Vc};
use turbo_tasks_fs::FileSystemPath;
use turbopack::{transition::Transition, ModuleAssetContext};
use turbopack_core::{
Expand All @@ -19,117 +18,59 @@ use turbopack_ecmascript::{magic_identifier, text::TextContentFileSource, utils:

use crate::{
app_structure::{
get_metadata_route_name, Components, GlobalMetadata, LoaderTree, Metadata, MetadataItem,
MetadataWithAltItem,
get_metadata_route_name, AppPageLoaderTree, Components, GlobalMetadata, Metadata,
MetadataItem, MetadataWithAltItem,
},
base_loader_tree::{BaseLoaderTreeBuilder, ComponentType},
next_app::{
metadata::{get_content_type, image::dynamic_image_metadata_source},
AppPage,
},
next_image::module::{BlurPlaceholderMode, StructuredImageModuleType},
};

pub struct LoaderTreeBuilder {
inner_assets: IndexMap<RcStr, Vc<Box<dyn Module>>>,
counter: usize,
imports: Vec<RcStr>,
pub struct AppPageLoaderTreeBuilder {
base: BaseLoaderTreeBuilder,
loader_tree_code: String,
module_asset_context: Vc<ModuleAssetContext>,
server_component_transition: Vc<Box<dyn Transition>>,
pages: Vec<Vc<FileSystemPath>>,
/// next.config.js' basePath option to construct og metadata.
base_path: Option<RcStr>,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum ComponentType {
Page,
DefaultPage,
Error,
Layout,
Loading,
Template,
NotFound,
}

impl ComponentType {
fn name(&self) -> &'static str {
match self {
ComponentType::Page => "page",
ComponentType::DefaultPage => "defaultPage",
ComponentType::Error => "error",
ComponentType::Layout => "layout",
ComponentType::Loading => "loading",
ComponentType::Template => "template",
ComponentType::NotFound => "not-found",
}
}
}

impl LoaderTreeBuilder {
impl AppPageLoaderTreeBuilder {
fn new(
module_asset_context: Vc<ModuleAssetContext>,
server_component_transition: Vc<Box<dyn Transition>>,
base_path: Option<RcStr>,
) -> Self {
LoaderTreeBuilder {
inner_assets: IndexMap::new(),
counter: 0,
imports: Vec::new(),
AppPageLoaderTreeBuilder {
base: BaseLoaderTreeBuilder::new(module_asset_context, server_component_transition),
loader_tree_code: String::new(),
module_asset_context,
server_component_transition,
pages: Vec::new(),
base_path,
}
}

fn unique_number(&mut self) -> usize {
let i = self.counter;
self.counter += 1;
i
}

async fn write_component(
&mut self,
ty: ComponentType,
component: Option<Vc<FileSystemPath>>,
component_type: ComponentType,
path: Option<Vc<FileSystemPath>>,
) -> Result<()> {
if let Some(component) = component {
if matches!(ty, ComponentType::Page) {
self.pages.push(component);
if let Some(path) = path {
if matches!(component_type, ComponentType::Page) {
self.pages.push(path);
}

let name = ty.name();
let i = self.unique_number();
let identifier = magic_identifier::mangle(&format!("{name} #{i}"));

let module = process_module(
&self.module_asset_context,
&self.server_component_transition,
component,
);
let tuple_code = self
.base
.create_component_tuple_code(component_type, path)
.await?;

writeln!(
self.loader_tree_code,
" {name}: [() => {identifier}, {path}],",
name = StringifyJs(name),
path = StringifyJs(&module.ident().path().to_string().await?)
" {name}: {tuple_code},",
name = StringifyJs(component_type.name())
)?;

self.imports.push(
formatdoc!(
r#"
import * as {} from "COMPONENT_{}";
"#,
identifier,
i
)
.into(),
);

self.inner_assets
.insert(format!("COMPONENT_{i}").into(), module);
}
Ok(())
}
Expand Down Expand Up @@ -237,21 +178,23 @@ impl LoaderTreeBuilder {
.await?;
}
MetadataWithAltItem::Dynamic { path, .. } => {
let i = self.unique_number();
let i = self.base.unique_number();
let identifier = magic_identifier::mangle(&format!("{name} #{i}"));
let inner_module_id = format!("METADATA_{i}");

self.imports
self.base
.imports
.push(format!("import {identifier} from \"{inner_module_id}\";").into());

let source = dynamic_image_metadata_source(
Vc::upcast(self.module_asset_context),
Vc::upcast(self.base.module_asset_context),
*path,
name.into(),
app_page.clone(),
);

let module = self
.base
.module_asset_context
.process(
source,
Expand All @@ -260,7 +203,9 @@ impl LoaderTreeBuilder {
)),
)
.module();
self.inner_assets.insert(inner_module_id.into(), module);
self.base
.inner_assets
.insert(inner_module_id.into(), module);

let s = " ";
writeln!(self.loader_tree_code, "{s}{identifier},")?;
Expand All @@ -277,26 +222,27 @@ impl LoaderTreeBuilder {
path: Vc<FileSystemPath>,
alt_path: Option<Vc<FileSystemPath>>,
) -> Result<()> {
let i = self.unique_number();
let i = self.base.unique_number();

let identifier = magic_identifier::mangle(&format!("{name} #{i}"));
let inner_module_id = format!("METADATA_{i}");
let helper_import: RcStr = "import { fillMetadataSegment } from \
\"next/dist/lib/metadata/get-metadata-route\""
.into();

if !self.imports.contains(&helper_import) {
self.imports.push(helper_import);
if !self.base.imports.contains(&helper_import) {
self.base.imports.push(helper_import);
}

self.imports
self.base
.imports
.push(format!("import {identifier} from \"{inner_module_id}\";").into());
self.inner_assets.insert(
self.base.inner_assets.insert(
inner_module_id.into(),
Vc::upcast(StructuredImageModuleType::create_module(
Vc::upcast(FileSource::new(path)),
BlurPlaceholderMode::None,
self.module_asset_context,
self.base.module_asset_context,
)),
);

Expand Down Expand Up @@ -333,9 +279,13 @@ impl LoaderTreeBuilder {
if let Some(alt_path) = alt_path {
let identifier = magic_identifier::mangle(&format!("{name} alt text #{i}"));
let inner_module_id = format!("METADATA_ALT_{i}");
self.imports

self.base
.imports
.push(format!("import {identifier} from \"{inner_module_id}\";").into());

let module = self
.base
.module_asset_context
.process(
Vc::upcast(TextContentFileSource::new(Vc::upcast(FileSource::new(
Expand All @@ -344,7 +294,10 @@ impl LoaderTreeBuilder {
Value::new(ReferenceType::Internal(InnerAssets::empty())),
)
.module();
self.inner_assets.insert(inner_module_id.into(), module);

self.base
.inner_assets
.insert(inner_module_id.into(), module);

writeln!(self.loader_tree_code, "{s} alt: {identifier},")?;
}
Expand All @@ -354,10 +307,10 @@ impl LoaderTreeBuilder {
Ok(())
}

async fn walk_tree(&mut self, loader_tree: &LoaderTree, root: bool) -> Result<()> {
async fn walk_tree(&mut self, loader_tree: &AppPageLoaderTree, root: bool) -> Result<()> {
use std::fmt::Write;

let LoaderTree {
let AppPageLoaderTree {
page: app_page,
segment,
parallel_routes,
Expand Down Expand Up @@ -423,62 +376,46 @@ impl LoaderTreeBuilder {
Ok(())
}

async fn build(mut self, loader_tree: Vc<LoaderTree>) -> Result<LoaderTreeModule> {
async fn build(
mut self,
loader_tree: Vc<AppPageLoaderTree>,
) -> Result<AppPageLoaderTreeModule> {
let loader_tree = &*loader_tree.await?;

let components = &loader_tree.components;
if let Some(global_error) = components.global_error {
let module = process_module(
&self.module_asset_context,
&self.server_component_transition,
global_error,
);
self.inner_assets.insert(GLOBAL_ERROR.into(), module);
let module = self.base.process_module(global_error);
self.base.inner_assets.insert(GLOBAL_ERROR.into(), module);
};

self.walk_tree(loader_tree, true).await?;
Ok(LoaderTreeModule {
imports: self.imports,
Ok(AppPageLoaderTreeModule {
imports: self.base.imports,
loader_tree_code: self.loader_tree_code.into(),
inner_assets: self.inner_assets,
inner_assets: self.base.inner_assets,
pages: self.pages,
})
}
}

pub struct LoaderTreeModule {
pub struct AppPageLoaderTreeModule {
pub imports: Vec<RcStr>,
pub loader_tree_code: RcStr,
pub inner_assets: IndexMap<RcStr, Vc<Box<dyn Module>>>,
pub pages: Vec<Vc<FileSystemPath>>,
}

impl LoaderTreeModule {
impl AppPageLoaderTreeModule {
pub async fn build(
loader_tree: Vc<LoaderTree>,
loader_tree: Vc<AppPageLoaderTree>,
module_asset_context: Vc<ModuleAssetContext>,
server_component_transition: Vc<Box<dyn Transition>>,
base_path: Option<RcStr>,
) -> Result<Self> {
LoaderTreeBuilder::new(module_asset_context, server_component_transition, base_path)
AppPageLoaderTreeBuilder::new(module_asset_context, server_component_transition, base_path)
.build(loader_tree)
.await
}
}

pub const GLOBAL_ERROR: &str = "GLOBAL_ERROR_MODULE";

fn process_module(
&context: &Vc<ModuleAssetContext>,
&server_component_transition: &Vc<Box<dyn Transition>>,
component: Vc<FileSystemPath>,
) -> Vc<Box<dyn Module>> {
let source = Vc::upcast(FileSource::new(component));
let reference_ty = Value::new(ReferenceType::EcmaScriptModules(
EcmaScriptModulesReferenceSubType::Undefined,
));

server_component_transition
.process(source, context, reference_ty)
.module()
}
6 changes: 3 additions & 3 deletions crates/next-core/src/app_segment_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use turbopack_ecmascript::{
EcmascriptInputTransforms, EcmascriptModuleAssetType,
};

use crate::{app_structure::LoaderTree, util::NextRuntime};
use crate::{app_structure::AppPageLoaderTree, util::NextRuntime};

#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, TraceRawVcs, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
Expand Down Expand Up @@ -468,7 +468,7 @@ fn parse_config_value(

#[turbo_tasks::function]
pub async fn parse_segment_config_from_loader_tree(
loader_tree: Vc<LoaderTree>,
loader_tree: Vc<AppPageLoaderTree>,
) -> Result<Vc<NextSegmentConfig>> {
let loader_tree = &*loader_tree.await?;

Expand All @@ -478,7 +478,7 @@ pub async fn parse_segment_config_from_loader_tree(
}

pub async fn parse_segment_config_from_loader_tree_internal(
loader_tree: &LoaderTree,
loader_tree: &AppPageLoaderTree,
) -> Result<NextSegmentConfig> {
let mut config = NextSegmentConfig::default();

Expand Down
Loading

0 comments on commit 9e75a30

Please sign in to comment.