Skip to content

Commit

Permalink
finalize support for edge routes
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Aug 1, 2023
1 parent faaa78d commit 9fbf170
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 38 deletions.
6 changes: 1 addition & 5 deletions packages/next-swc/crates/next-api/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -680,8 +680,6 @@ impl AppEndpoint {
.try_flat_join()
.await?;

println!("files_paths_from_root: {:?}", files_paths_from_root);

let server_path_value = server_path.await?;
let files_paths_from_server = files
.await?
Expand All @@ -698,8 +696,6 @@ impl AppEndpoint {
.await?;
let base_file = files_paths_from_server[0].to_string();

println!("files_paths_from_server: {:?}", files_paths_from_server);

// create middleware manifest
// TODO(alexkirsz) This should be shared with next build.
let named_regex = get_named_middleware_regex(&app_entry.pathname);
Expand All @@ -710,7 +706,7 @@ impl AppEndpoint {
};
let edge_function_definition = EdgeFunctionDefinition {
files: files_paths_from_root,
name: "".to_string(),
name: app_entry.original_name.to_string(),
page: app_entry.original_name.clone(),
regions: app_entry
.config
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub async fn get_app_route_favicon_entry(
let file = File::from(code.build());
let source =
// TODO(alexkirsz) Figure out how to name this virtual source.
VirtualSource::new(project_root.join("todo.tsx".to_string()), AssetContent::file(file.into()));
VirtualSource::new(project_root.join("favicon-entry.tsx".to_string()), AssetContent::file(file.into()));

Ok(get_app_route_entry(
nodejs_context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ pub async fn get_app_page_entry(
project_root: Vc<FileSystemPath>,
) -> Result<Vc<AppEntry>> {
let config = parse_segment_config_from_loader_tree(loader_tree, Vc::upcast(nodejs_context));
let context = if matches!(config.await?.runtime, Some(NextRuntime::Edge)) {
let is_edge = matches!(config.await?.runtime, Some(NextRuntime::Edge));
let context = if is_edge {
edge_context
} else {
nodejs_context
Expand Down Expand Up @@ -144,6 +145,10 @@ pub async fn get_app_page_entry(
Value::new(ReferenceType::Internal(Vc::cell(inner_assets))),
);

if is_edge {
todo!("edge pages are not supported yet")
}

let Some(rsc_entry) =
Vc::try_resolve_downcast::<Box<dyn EcmascriptChunkPlaceable>>(rsc_entry).await?
else {
Expand Down
72 changes: 41 additions & 31 deletions packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,37 +118,7 @@ pub async fn get_app_route_entry(
);

if is_edge {
let mut source = RopeBuilder::default();
writedoc!(
source,
r#"
import {{ EdgeRouteModuleWrapper }} from 'next/dist/esm/server/web/edge-route-module-wrapper'
import * as module from "MODULE"
export const ComponentMod = module
console.log("loaded edge route module")
self._ENTRIES ||= {{}}
self._ENTRIES.middleware_ = {{
ComponentMod: module,
default: EdgeRouteModuleWrapper.wrap(module.routeModule),
}}
"#
)?;
let file = File::from(source.build());
// TODO(alexkirsz) Figure out how to name this virtual asset.
let virtual_source = VirtualSource::new(
project_root.join("edge-wrapper.js".to_string()),
AssetContent::file(file.into()),
);
let inner_assets = indexmap! {
"MODULE".to_string() => rsc_entry
};

rsc_entry = context.process(
Vc::upcast(virtual_source),
Value::new(ReferenceType::Internal(Vc::cell(inner_assets))),
);
rsc_entry = wrap_edge_entry(context, project_root, rsc_entry, original_name.clone());
}

let Some(rsc_entry) =
Expand All @@ -166,6 +136,46 @@ pub async fn get_app_route_entry(
.cell())
}

#[turbo_tasks::function]
pub async fn wrap_edge_entry(
context: Vc<ModuleAssetContext>,
project_root: Vc<FileSystemPath>,
entry: Vc<Box<dyn Module>>,
original_name: String,
) -> Result<Vc<Box<dyn Module>>> {
let mut source = RopeBuilder::default();
writedoc!(
source,
r#"
import {{ EdgeRouteModuleWrapper }} from 'next/dist/esm/server/web/edge-route-module-wrapper'
import * as module from "MODULE"
export const ComponentMod = module
self._ENTRIES ||= {{}}
self._ENTRIES[{}] = {{
ComponentMod: module,
default: EdgeRouteModuleWrapper.wrap(module.routeModule),
}}
"#,
StringifyJs(&format_args!("middleware_{}", original_name))
)?;
let file = File::from(source.build());
// TODO(alexkirsz) Figure out how to name this virtual asset.
let virtual_source = VirtualSource::new(
project_root.join("edge-wrapper.js".to_string()),
AssetContent::file(file.into()),
);
let inner_assets = indexmap! {
"MODULE".to_string() => entry
};

Ok(context.process(
Vc::upcast(virtual_source),
Value::new(ReferenceType::Internal(Vc::cell(inner_assets))),
))
}

fn get_original_route_name(pathname: &str) -> String {
match pathname {
"/" => "/route".to_string(),
Expand Down
1 change: 1 addition & 0 deletions packages/next/src/server/app-render/app-render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ export async function renderToHTMLOrFlight(
allCapturedErrors,
})

console.log(ComponentMod)
patchFetch(ComponentMod)
/**
* Rules of Static & Dynamic HTML:
Expand Down

0 comments on commit 9fbf170

Please # to comment.