Skip to content

Commit

Permalink
server: re-land bundled runtimes (vercel#55139)
Browse files Browse the repository at this point in the history
see vercel#52997

also added a fix by @jridgewell to fix turbopack





Co-authored-by: Justin Ridgewell <[email protected]>
  • Loading branch information
feedthejim and jridgewell authored Sep 8, 2023
1 parent 5b85a40 commit 5217e7e
Show file tree
Hide file tree
Showing 160 changed files with 1,570 additions and 951 deletions.
5 changes: 4 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,10 @@
},
{
"files": ["packages/**"],
"excludedFiles": ["packages/next/taskfile.js"],
"excludedFiles": [
"packages/next/taskfile*.js",
"packages/next/webpack.config.js"
],
"rules": {
"no-shadow": ["warn", { "builtinGlobals": false }],
"import/no-extraneous-dependencies": [
Expand Down
5 changes: 5 additions & 0 deletions bench/basic-app/app/api/app/route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export function GET() {
return { name: 'John Doe' }
}

export const dynamic = 'force-dynamic'
12 changes: 12 additions & 0 deletions bench/basic-app/app/layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react'

export default function Layout({ children }) {
return (
<html>
<head>
<title>My App</title>
</head>
<body>{children}</body>
</html>
)
}
7 changes: 7 additions & 0 deletions bench/basic-app/app/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react'

export default function Page() {
return <h1>My Page</h1>
}

export const dynamic = 'force-dynamic'
5 changes: 5 additions & 0 deletions bench/basic-app/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
experimental: {
serverMinification: true,
},
}
3 changes: 3 additions & 0 deletions bench/basic-app/pages/api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}
7 changes: 7 additions & 0 deletions bench/basic-app/pages/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default () => 'Hello World'

export function getServerSideProps() {
return {
props: {},
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// the other imports
import startOperationStreamHandler from '../internal/operation-stream'

import 'next/dist/server/node-polyfill-fetch'

import { join } from 'path'
import { parse as parseUrl } from 'node:url'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import startOperationStreamHandler from '../internal/operation-stream'

import '../polyfill/app-polyfills.ts'
// TODO: when actions are supported, this should be removed/changed
process.env.__NEXT_PRIVATE_PREBUNDLED_REACT = 'next'
import 'next/dist/server/require-hook'

import type { IncomingMessage } from 'node:http'

import type { RenderData } from 'types/turbopack'
import type { RenderOpts } from 'next/dist/server/app-render/types'

import { renderToHTMLOrFlight } from 'next/dist/server/app-render/app-render'
import { RSC_VARY_HEADER } from 'next/dist/client/components/app-router-headers'
import { headersFromEntries, initProxiedHeaders } from '../internal/headers'
import { parse, ParsedUrlQuery } from 'node:querystring'
Expand All @@ -23,6 +25,10 @@ import { join } from 'node:path'
import { nodeFs } from 'next/dist/server/lib/node-fs-methods'
import { IncrementalCache } from 'next/dist/server/lib/incremental-cache'

const {
renderToHTMLOrFlight,
} = require('next/dist/compiled/next-server/app-page.runtime.dev')

installRequireAndChunkLoad()

const MIME_TEXT_HTML_UTF8 = 'text/html; charset=utf-8'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { createFromReadableStream } from 'next/dist/compiled/react-server-dom-we
import { callServer } from 'next/dist/client/app-call-server'
import { linkGc } from 'next/dist/client/app-link-gc'

import { HeadManagerContext } from 'next/dist/shared/lib/head-manager-context'
import { HeadManagerContext } from 'next/dist/shared/lib/head-manager-context.shared-runtime'

import { initializeHMR } from '@vercel/turbopack-next/dev/client'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import { IPC } from '@vercel/turbopack-node/ipc/index'

import 'next/dist/server/node-polyfill-fetch.js'
import 'next/dist/server/require-hook'
import './shims'

import type { IncomingMessage, ServerResponse } from 'node:http'

import { renderToHTML, RenderOpts } from 'next/dist/server/render'
import type { RenderOpts } from 'next/dist/server/render'
import { getRedirectStatus } from 'next/dist/lib/redirect-status'
import { PERMANENT_REDIRECT_STATUS } from 'next/dist/shared/lib/constants'
import { buildStaticPaths } from 'next/dist/build/utils'
Expand All @@ -21,6 +22,9 @@ import type { RenderData } from 'types/turbopack'
import type { ChunkGroup } from 'types/next'
import type { NextComponentType } from 'next/types'
import { parse } from 'node:querystring'
const {
renderToHTML,
} = require('next/dist/compiled/next-server/pages.runtime.dev')

const ipc = IPC as Ipc<IpcIncomingMessage, IpcOutgoingMessage>

Expand Down
17 changes: 11 additions & 6 deletions packages/next-swc/crates/next-core/src/app_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{collections::HashMap, io::Write as _, iter::once};

use anyhow::{bail, Result};
use indexmap::indexmap;
use indoc::indoc;
use indoc::formatdoc;
use serde_json::Value as JsonValue;
use turbo_tasks::Vc;
use turbopack_binding::{
Expand Down Expand Up @@ -964,13 +964,18 @@ impl AppRenderer {
.emit();
}

let mut result = RopeBuilder::from(indoc! {"
\"TURBOPACK { chunking-type: isolatedParallel; transition: next-edge-server-component }\";
let mut result = RopeBuilder::from(
formatdoc!(
"
\"TURBOPACK {{ chunking-type: isolatedParallel; transition: {rsc_transition} }}\";
import GlobalErrorMod from \"next/dist/client/components/error-boundary\"
const { GlobalError } = GlobalErrorMod;
\"TURBOPACK { chunking-type: isolatedParallel; transition: next-edge-server-component }\";
const {{ GlobalError }} = GlobalErrorMod;
\"TURBOPACK {{ chunking-type: isolatedParallel; transition: {rsc_transition} }}\";
import base from \"next/dist/server/app-render/entry-base\"\n
"});
"
)
.into_bytes(),
);

for import in loader_tree_module.imports {
writeln!(result, "{import}")?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ use crate::{
get_next_client_resolved_map, mdx_import_source_file,
},
next_shared::{
resolve::{ModuleFeatureReportResolvePlugin, UnsupportedModulesResolvePlugin},
resolve::{
ModuleFeatureReportResolvePlugin, NextSharedRuntimeResolvePlugin,
UnsupportedModulesResolvePlugin,
},
transforms::{
emotion::get_emotion_transform_plugin, get_relay_transform_plugin,
styled_components::get_styled_components_transform_plugin,
Expand Down Expand Up @@ -148,6 +151,7 @@ pub async fn get_client_resolve_options_context(
plugins: vec![
Vc::upcast(ModuleFeatureReportResolvePlugin::new(project_path)),
Vc::upcast(UnsupportedModulesResolvePlugin::new(project_path)),
Vc::upcast(NextSharedRuntimeResolvePlugin::new(project_path)),
],
..Default::default()
};
Expand Down
13 changes: 8 additions & 5 deletions packages/next-swc/crates/next-core/src/next_edge/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ use crate::{
next_config::NextConfig,
next_import_map::get_next_edge_import_map,
next_server::context::ServerContextType,
next_shared::resolve::{ModuleFeatureReportResolvePlugin, UnsupportedModulesResolvePlugin},
next_shared::resolve::{
ModuleFeatureReportResolvePlugin, NextSharedRuntimeResolvePlugin,
UnsupportedModulesResolvePlugin,
},
util::foreign_code_context_condition,
};

Expand Down Expand Up @@ -96,10 +99,9 @@ pub async fn get_edge_resolve_options_context(
];

match ty {
ServerContextType::AppRSC { .. } | ServerContextType::AppRoute { .. } => {
custom_conditions.push("react-server".to_string())
}
ServerContextType::Pages { .. }
ServerContextType::AppRSC { .. } => custom_conditions.push("react-server".to_string()),
ServerContextType::AppRoute { .. }
| ServerContextType::Pages { .. }
| ServerContextType::PagesData { .. }
| ServerContextType::AppSSR { .. }
| ServerContextType::Middleware { .. } => {}
Expand All @@ -114,6 +116,7 @@ pub async fn get_edge_resolve_options_context(
plugins: vec![
Vc::upcast(ModuleFeatureReportResolvePlugin::new(project_path)),
Vc::upcast(UnsupportedModulesResolvePlugin::new(project_path)),
Vc::upcast(NextSharedRuntimeResolvePlugin::new(project_path)),
],
..Default::default()
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,26 @@ impl Transition for NextEdgeRouteTransition {

#[turbo_tasks::function]
async fn process_module(
&self,
self: Vc<Self>,
asset: Vc<Box<dyn Module>>,
context: Vc<ModuleAssetContext>,
) -> Result<Vc<Box<dyn Module>>> {
let new_context = self.process_context(context);
let this = self.await?;
let new_asset = route_bootstrap(
asset,
Vc::upcast(context),
self.base_path,
self.bootstrap_asset,
Vc::upcast(new_context),
this.base_path,
this.bootstrap_asset,
Vc::cell(indexmap! {
"NAME".to_string() => self.entry_name.clone(),
"NAME".to_string() => this.entry_name.clone(),
}),
);

let asset = ChunkGroupFilesAsset {
module: Vc::upcast(new_asset),
client_root: self.output_path,
chunking_context: self.edge_chunking_context,
client_root: this.output_path,
chunking_context: this.edge_chunking_context,
runtime_entries: None,
};

Expand Down
66 changes: 45 additions & 21 deletions packages/next-swc/crates/next-core/src/next_import_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,32 +216,34 @@ pub async fn get_next_server_import_map(
let ty = ty.into_value();

insert_next_server_special_aliases(&mut import_map, ty, mode, NextRuntime::NodeJs).await?;
let external = ImportMapping::External(None).cell();
let external: Vc<ImportMapping> = ImportMapping::External(None).cell();

import_map.insert_exact_alias("next/dist/server/require-hook", external);
match ty {
ServerContextType::Pages { .. } | ServerContextType::PagesData { .. } => {
import_map.insert_exact_alias("next", external);
import_map.insert_wildcard_alias("next/", external);
import_map.insert_exact_alias("react", external);
import_map.insert_wildcard_alias("react/", external);
import_map.insert_exact_alias("react-dom", external);
import_map.insert_wildcard_alias("react-dom/", external);
import_map.insert_exact_alias("styled-jsx", external);
import_map.insert_wildcard_alias("styled-jsx/", external);
import_map.insert_exact_alias("react-server-dom-webpack/", external);
import_map.insert_wildcard_alias("react-server-dom-webpack/", external);
// TODO: we should not bundle next/dist/build/utils in the pages renderer at all
import_map.insert_wildcard_alias("next/dist/build/utils", external);
}
ServerContextType::AppSSR { .. }
| ServerContextType::AppRSC { .. }
| ServerContextType::AppRoute { .. } => {
match mode {
NextMode::Development | NextMode::Build => {
NextMode::Build => {
import_map.insert_wildcard_alias("next/dist/server/", external);
import_map.insert_wildcard_alias("next/dist/shared/", external);
}
NextMode::DevServer => {
// The sandbox can't be bundled and needs to be external
import_map.insert_exact_alias("next/dist/server/web/sandbox", external);
}
NextMode::Development => {}
}
import_map.insert_exact_alias(
"next/head",
Expand Down Expand Up @@ -377,6 +379,11 @@ async fn insert_next_server_special_aliases(
NextRuntime::Edge => request_to_import_mapping(context_dir, request),
NextRuntime::NodeJs => external_request_to_import_mapping(request),
};
let passthrough_external_if_node =
move |context_dir: Vc<FileSystemPath>, request: &str| match runtime {
NextRuntime::Edge => request_to_import_mapping(context_dir, request),
NextRuntime::NodeJs => ImportMapping::External(None).cell(),
};
match (mode, ty) {
(_, ServerContextType::Pages { pages_dir }) => {
import_map.insert_exact_alias(
Expand Down Expand Up @@ -413,12 +420,7 @@ async fn insert_next_server_special_aliases(
(_, ServerContextType::PagesData { .. }) => {}
// In development, we *always* use the bundled version of React, even in
// SSR, since we're bundling Next.js alongside it.
(
NextMode::DevServer,
ServerContextType::AppSSR { app_dir }
| ServerContextType::AppRSC { app_dir, .. }
| ServerContextType::AppRoute { app_dir },
) => {
(NextMode::DevServer, ServerContextType::AppSSR { app_dir }) => {
import_map.insert_exact_alias(
"@opentelemetry/api",
// TODO(WEB-625) this actually need to prefer the local version of
Expand All @@ -427,28 +429,40 @@ async fn insert_next_server_special_aliases(
);
import_map.insert_exact_alias(
"react",
request_to_import_mapping(app_dir, "next/dist/compiled/react"),
passthrough_external_if_node(app_dir, "next/dist/compiled/react"),
);
import_map.insert_wildcard_alias(
"react/",
request_to_import_mapping(app_dir, "next/dist/compiled/react/*"),
passthrough_external_if_node(app_dir, "next/dist/compiled/react/*"),
);
import_map.insert_exact_alias(
"react-dom",
request_to_import_mapping(
passthrough_external_if_node(
app_dir,
"next/dist/compiled/react-dom/server-rendering-stub.js",
),
);
import_map.insert_wildcard_alias(
"react-dom/",
request_to_import_mapping(app_dir, "next/dist/compiled/react-dom/*"),
passthrough_external_if_node(app_dir, "next/dist/compiled/react-dom/*"),
);
import_map.insert_exact_alias(
"styled-jsx",
passthrough_external_if_node(app_dir, "next/dist/compiled/styled-jsx"),
);
import_map.insert_wildcard_alias(
"styled-jsx/",
passthrough_external_if_node(app_dir, "next/dist/compiled/styled-jsx/*"),
);
import_map.insert_wildcard_alias(
"react-server-dom-webpack/",
request_to_import_mapping(app_dir, "next/dist/compiled/react-server-dom-webpack/*"),
passthrough_external_if_node(
app_dir,
"next/dist/compiled/react-server-dom-webpack/*",
),
);
}

// NOTE(alexkirsz) This logic maps loosely to
// `next.js/packages/next/src/build/webpack-config.ts`, where:
//
Expand All @@ -460,7 +474,7 @@ async fn insert_next_server_special_aliases(
// * passes through (react|react-dom|react-server-dom-webpack)/(.*) to
// next/dist/compiled/$1/$2
(
NextMode::Build | NextMode::Development,
NextMode::Build | NextMode::Development | NextMode::DevServer,
ServerContextType::AppRSC { app_dir, .. } | ServerContextType::AppRoute { app_dir },
) => {
import_map.insert_exact_alias(
Expand All @@ -469,10 +483,20 @@ async fn insert_next_server_special_aliases(
// @opentelemetry/api
request_to_import_mapping(app_dir, "next/dist/compiled/@opentelemetry/api"),
);
import_map.insert_exact_alias(
"react",
request_to_import_mapping(app_dir, "next/dist/compiled/react/react.shared-subset"),
);
if matches!(ty, ServerContextType::AppRSC { .. }) {
import_map.insert_exact_alias(
"react",
request_to_import_mapping(
app_dir,
"next/dist/compiled/react/react.shared-subset",
),
);
} else {
import_map.insert_exact_alias(
"react",
request_to_import_mapping(app_dir, "next/dist/compiled/react"),
);
}
import_map.insert_exact_alias(
"react-dom",
request_to_import_mapping(
Expand Down
Loading

0 comments on commit 5217e7e

Please sign in to comment.