Skip to content

Commit

Permalink
Process middleware for edge computation
Browse files Browse the repository at this point in the history
  • Loading branch information
jridgewell committed Feb 11, 2023
1 parent a710363 commit 5b6ccbe
Show file tree
Hide file tree
Showing 12 changed files with 160 additions and 18 deletions.
16 changes: 14 additions & 2 deletions crates/next-core/js/src/entry/router.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import type { Ipc } from "@vercel/turbopack-next/ipc/index";
import type { IncomingMessage, ServerResponse } from "node:http";
import { Buffer } from "node:buffer";
import { join } from "node:path";
import { createServer, makeRequest } from "@vercel/turbopack-next/ipc/server";
import { makeResolver } from "next/dist/server/router.js";
import loadConfig from "next/dist/server/config";
import { PHASE_DEVELOPMENT_SERVER } from "next/dist/shared/lib/constants";

import "next/dist/server/node-polyfill-fetch.js";
import * as middleware from "MIDDLEWARE_CONFIG";

import middlewareChunkGroup from "MIDDLEWARE_CHUNK_GROUP";

type RouterRequest = {
method: string;
Expand Down Expand Up @@ -66,7 +68,17 @@ async function getResolveRoute(
true
);

return await makeResolver(dir, nextConfig, middleware);
const edgeInfo = {
name: "edge",
paths: middlewareChunkGroup.map((chunk: string) =>
join(process.cwd(), chunk)
),
wasm: [],
env: [],
assets: [],
};
console.log(edgeInfo);
return await makeResolver(dir, nextConfig, edgeInfo);
}

export default async function route(
Expand Down
2 changes: 1 addition & 1 deletion crates/next-core/src/next_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ pub async fn load_next_config(execution_context: ExecutionContextVc) -> Result<N
import_map.insert_exact_alias("styled-jsx", ImportMapping::External(None).into());
import_map.insert_wildcard_alias("styled-jsx/", ImportMapping::External(None).into());

let context = node_evaluate_asset_context(Some(import_map.cell()));
let context = node_evaluate_asset_context(Some(import_map.cell()), None);
let find_config_result = find_context_file(project_root, next_configs());
let config_asset = match &*find_config_result.await? {
FindContextFileResult::Found(config_path, _) => Some(SourceAssetVc::new(*config_path)),
Expand Down
7 changes: 5 additions & 2 deletions crates/next-core/src/next_edge/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ use crate::{
};

#[turbo_tasks::function]
pub fn get_edge_environment(server_addr: ServerAddrVc) -> EnvironmentVc {
pub fn get_edge_environment(
server_addr: ServerAddrVc,
intention: Value<EnvironmentIntention>,
) -> EnvironmentVc {
EnvironmentVc::new(
Value::new(ExecutionEnvironment::EdgeWorker(
EdgeWorkerEnvironment { server_addr }.into(),
)),
Value::new(EnvironmentIntention::Api),
intention,
)
}

Expand Down
2 changes: 2 additions & 0 deletions crates/next-core/src/next_import_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ pub async fn get_next_server_import_map(
);
}
}
ServerContextType::Middleware => {}
}

Ok(import_map.cell())
Expand Down Expand Up @@ -329,6 +330,7 @@ pub async fn insert_next_server_special_aliases(
request_to_import_mapping(app_dir, "next/dist/compiled/react-dom/*"),
);
}
ServerContextType::Middleware => {}
}
Ok(())
}
Expand Down
41 changes: 41 additions & 0 deletions crates/next-core/src/next_server/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub enum ServerContextType {
PagesData { pages_dir: FileSystemPathVc },
AppSSR { app_dir: FileSystemPathVc },
AppRSC { app_dir: FileSystemPathVc },
Middleware,
}

#[turbo_tasks::function]
Expand Down Expand Up @@ -107,6 +108,26 @@ pub async fn get_server_resolve_options_context(
..resolve_options_context
}
}
ServerContextType::Middleware => {
let resolve_options_context = ResolveOptionsContext {
enable_node_modules: true,
enable_node_externals: true,
enable_node_native_modules: true,
module: true,
custom_conditions: vec!["development".to_string()],
import_map: Some(next_server_import_map),
..Default::default()
};
ResolveOptionsContext {
enable_typescript: true,
enable_react: true,
rules: vec![(
foreign_code_context_condition,
resolve_options_context.clone().cell(),
)],
..resolve_options_context
}
}
}
.cell())
}
Expand All @@ -127,6 +148,7 @@ pub fn get_server_environment(
}
ServerContextType::AppSSR { .. } => Value::new(EnvironmentIntention::Prerendering),
ServerContextType::AppRSC { .. } => Value::new(EnvironmentIntention::ServerRendering),
ServerContextType::Middleware => Value::new(EnvironmentIntention::Middleware),
},
)
}
Expand Down Expand Up @@ -206,6 +228,25 @@ pub async fn get_server_module_options_context(
..module_options_context
}
}
ServerContextType::Middleware => {
let module_options_context = ModuleOptionsContext {
execution_context: Some(execution_context),
..Default::default()
};
ModuleOptionsContext {
enable_jsx: true,
enable_styled_jsx: true,
enable_postcss_transform,
enable_webpack_loaders,
enable_typescript_transform: true,
rules: vec![(
foreign_code_context_condition,
module_options_context.clone().cell(),
)],
custom_rules,
..module_options_context
}
}
}
.cell();

Expand Down
1 change: 1 addition & 0 deletions crates/next-core/src/next_server/transforms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub async fn get_next_server_transforms_rules(
}
ServerContextType::AppSSR { .. } => (false, None),
ServerContextType::AppRSC { .. } => (true, None),
ServerContextType::Middleware { .. } => (false, None),
};

rules.push(get_next_dynamic_transform_rule(
Expand Down
4 changes: 2 additions & 2 deletions crates/next-core/src/page_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use turbopack_core::{
asset::{Asset, AssetVc},
chunk::{dev::DevChunkingContextVc, ChunkingContextVc},
context::{AssetContext, AssetContextVc},
environment::ServerAddrVc,
environment::{EnvironmentIntention, ServerAddrVc},
reference_type::{EntryReferenceSubType, ReferenceType},
source_asset::SourceAssetVc,
virtual_asset::VirtualAssetVc,
Expand Down Expand Up @@ -132,7 +132,7 @@ pub async fn create_page_source(
.cell()
.into();

let edge_environment = get_edge_environment(server_addr);
let edge_environment = get_edge_environment(server_addr, Value::new(EnvironmentIntention::Api));

let edge_chunking_context = DevChunkingContextVc::builder(
project_path,
Expand Down
76 changes: 72 additions & 4 deletions crates/next-core/src/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ use turbo_tasks::{
use turbo_tasks_fs::{
json::parse_json_rope_with_source_context, to_sys_path, File, FileSystemPathVc,
};
use turbopack::evaluate_context::node_evaluate_asset_context;
use turbopack::{evaluate_context::node_evaluate_asset_context, transition::TransitionsByNameVc};
use turbopack_core::{
asset::AssetVc,
chunk::dev::DevChunkingContextVc,
context::{AssetContext, AssetContextVc},
environment::{EnvironmentIntention::Middleware, ServerAddrVc},
reference_type::{ReferenceType::TypeScript, TypeScriptReferenceSubType},
resolve::{find_context_file, FindContextFileResult},
source_asset::SourceAssetVc,
virtual_asset::VirtualAssetVc,
Expand All @@ -31,7 +34,12 @@ use turbopack_node::{
use crate::{
embed_js::{next_asset, wrap_with_next_js_fs},
next_config::NextConfigVc,
next_edge::{
context::{get_edge_environment, get_edge_resolve_options_context},
transition::NextEdgeTransition,
},
next_import_map::get_next_build_import_map,
next_server::context::ServerContextType,
};

#[turbo_tasks::function]
Expand Down Expand Up @@ -181,7 +189,13 @@ async fn config_assets(
let mut inner = HashMap::new();

let middleware_config = get_config(context, project_path, middleware_files(page_extensions));
inner.insert("MIDDLEWARE_CONFIG".to_string(), middleware_config.into());
inner.insert(
"MIDDLEWARE_CHUNK_GROUP".to_string(),
context.with_transition("next-edge").process(
middleware_config.into(),
Value::new(TypeScript(TypeScriptReferenceSubType::Undefined)),
),
);

Ok(InnerAssetsVc::cell(inner))
}
Expand All @@ -203,22 +217,76 @@ fn route_executor(
.into()
}

#[turbo_tasks::function]
fn edge_transition_map(
server_addr: ServerAddrVc,
project_path: FileSystemPathVc,
output_path: FileSystemPathVc,
next_config: NextConfigVc,
) -> TransitionsByNameVc {
let edge_environment = get_edge_environment(server_addr, Value::new(Middleware));

let edge_chunking_context = DevChunkingContextVc::builder(
project_path,
output_path.join("edge"),
output_path.join("edge/chunks"),
output_path.join("edge/assets"),
edge_environment,
)
.build();

let edge_resolve_options_context = get_edge_resolve_options_context(
project_path,
Value::new(ServerContextType::Middleware),
next_config,
);

let next_edge_transition = NextEdgeTransition {
edge_environment,
edge_chunking_context,
edge_resolve_options_context,
output_path,
base_path: project_path,
}
.cell()
.into();

TransitionsByNameVc::cell(
[("next-edge".to_string(), next_edge_transition)]
.into_iter()
.collect(),
)
}

#[turbo_tasks::function]
pub async fn route(
execution_context: ExecutionContextVc,
request: RouterRequestVc,
next_config: NextConfigVc,
server_addr: ServerAddrVc,
) -> Result<RouterResultVc> {
let ExecutionContext {
project_root,
intermediate_output_path,
} = *execution_context.await?;
let project_path = wrap_with_next_js_fs(project_root);
let context = node_evaluate_asset_context(Some(get_next_build_import_map(project_path)));
let intermediate_output_path = intermediate_output_path.join("router");

let context = node_evaluate_asset_context(
Some(get_next_build_import_map(project_path)),
Some(edge_transition_map(
server_addr,
project_path,
intermediate_output_path,
next_config,
)),
);

let configs = config_assets(context, project_path, next_config.page_extensions());
let router_asset = route_executor(context, project_path, configs);

// dbg!(router_asset.dbg().await?);

// TODO this is a hack to get these files watched.
let next_config = watch_files_hack(context, project_path);

Expand All @@ -232,7 +300,7 @@ pub async fn route(
project_root,
project_root,
context,
intermediate_output_path.join("router"),
intermediate_output_path,
Some(next_config),
vec![
JsonValueVc::cell(request),
Expand Down
15 changes: 13 additions & 2 deletions crates/next-core/src/router_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use std::collections::HashSet;

use anyhow::Result;
use turbo_tasks::{primitives::StringVc, Value};
use turbopack_core::introspect::{Introspectable, IntrospectableChildrenVc, IntrospectableVc};
use turbopack_core::{
environment::ServerAddrVc,
introspect::{Introspectable, IntrospectableChildrenVc, IntrospectableVc},
};
use turbopack_dev_server::source::{
ContentSource, ContentSourceContent, ContentSourceData, ContentSourceDataVary,
ContentSourceResultVc, ContentSourceVc, NeededData, ProxyResult, RewriteVc,
Expand All @@ -20,6 +23,7 @@ pub struct NextRouterContentSource {
inner: ContentSourceVc,
execution_context: ExecutionContextVc,
next_config: NextConfigVc,
server_addr: ServerAddrVc,
}

#[turbo_tasks::value_impl]
Expand All @@ -29,11 +33,13 @@ impl NextRouterContentSourceVc {
inner: ContentSourceVc,
execution_context: ExecutionContextVc,
next_config: NextConfigVc,
server_addr: ServerAddrVc,
) -> NextRouterContentSourceVc {
NextRouterContentSource {
inner,
execution_context,
next_config,
server_addr,
}
.cell()
}
Expand Down Expand Up @@ -83,7 +89,12 @@ impl ContentSource for NextRouterContentSource {
}
.cell();

let res = route(this.execution_context, request, this.next_config);
let res = route(
this.execution_context,
request,
this.next_config,
this.server_addr,
);
let Ok(res) = res.await else {
return Ok(this
.inner
Expand Down
3 changes: 2 additions & 1 deletion crates/next-dev/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,8 @@ async fn source(
)
.into();
let router_source =
NextRouterContentSourceVc::new(main_source, execution_context, next_config).into();
NextRouterContentSourceVc::new(main_source, execution_context, next_config, server_addr)
.into();
let source = RouterContentSource {
routes: vec![
("__turbopack__/".to_string(), introspect),
Expand Down
7 changes: 5 additions & 2 deletions crates/turbopack/src/evaluate_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ use crate::{
};

#[turbo_tasks::function]
pub fn node_evaluate_asset_context(import_map: Option<ImportMapVc>) -> AssetContextVc {
pub fn node_evaluate_asset_context(
import_map: Option<ImportMapVc>,
transitions: Option<TransitionsByNameVc>,
) -> AssetContextVc {
ModuleAssetContextVc::new(
TransitionsByNameVc::cell(Default::default()),
transitions.unwrap_or_else(|| TransitionsByNameVc::cell(Default::default())),
EnvironmentVc::new(
Value::new(ExecutionEnvironment::NodeJsBuildTime(
NodeJsEnvironment::default().cell(),
Expand Down
4 changes: 2 additions & 2 deletions crates/turbopack/src/module_options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ impl ModuleOptionsVc {
};
Some(ModuleRuleEffect::SourceTransforms(
SourceTransformsVc::cell(vec![PostCssTransformVc::new(
node_evaluate_asset_context(Some(import_map)),
node_evaluate_asset_context(Some(import_map), None),
execution_context,
)
.into()]),
Expand Down Expand Up @@ -253,7 +253,7 @@ impl ModuleOptionsVc {
ModuleRuleEffect::ModuleType(ModuleType::Ecmascript(app_transforms)),
ModuleRuleEffect::SourceTransforms(SourceTransformsVc::cell(vec![
WebpackLoadersVc::new(
node_evaluate_asset_context(None),
node_evaluate_asset_context(None, None),
execution_context,
*loaders,
)
Expand Down

0 comments on commit 5b6ccbe

Please sign in to comment.