Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

server: bundle vendored react #55362

Merged
merged 59 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
9d114d5
toast
feedthejim Sep 14, 2023
a12c76a
types
feedthejim Sep 14, 2023
906896c
Merge remote-tracking branch 'origin/canary' into feedthejim/bundle-r…
feedthejim Sep 14, 2023
9c45cf0
Revert "types"
feedthejim Sep 14, 2023
1e44d52
fix edge
feedthejim Sep 14, 2023
8193d1b
tree shake typeof window
feedthejim Sep 14, 2023
5c33d38
fix actions
feedthejim Sep 14, 2023
d48d793
update test
feedthejim Sep 14, 2023
eac661a
temporary HMR fix
feedthejim Sep 14, 2023
1425474
Merge remote-tracking branch 'origin/canary' into feedthejim/bundle-r…
feedthejim Sep 14, 2023
3eef508
fix server actions build
feedthejim Sep 14, 2023
886279b
fix bundled react in pages
feedthejim Sep 14, 2023
1eeadc6
tentative require cache fix
feedthejim Sep 14, 2023
8b0c25b
add env var
feedthejim Sep 14, 2023
a3ceceb
fix server config
feedthejim Sep 14, 2023
c5b5e51
fix hmr
feedthejim Sep 14, 2023
f4dd6ee
Revert "tentative require cache fix"
feedthejim Sep 14, 2023
d8b8a96
Merge branch 'canary' into feedthejim/bundle-react
feedthejim Sep 14, 2023
e303a7e
fix use flight response
feedthejim Sep 14, 2023
80e946b
tentatively fix shared-runtimes
feedthejim Sep 14, 2023
1824110
Merge remote-tracking branch 'origin/canary' into feedthejim/bundle-r…
feedthejim Sep 14, 2023
8bc4fcb
update vendored stub
feedthejim Sep 14, 2023
9771525
re-do vendored contexts
feedthejim Sep 14, 2023
f0a4124
simplify require hook
feedthejim Sep 14, 2023
0e0ee06
Merge remote-tracking branch 'origin/canary' into feedthejim/bundle-r…
feedthejim Sep 14, 2023
a4dc693
disable require hook in worker
feedthejim Sep 14, 2023
b92c0e8
add server inserted HTML to pages
feedthejim Sep 14, 2023
a598f5e
fix require hook
feedthejim Sep 14, 2023
bf86e06
add other aliases for react
feedthejim Sep 14, 2023
57bb3bc
fix require hook (again)
feedthejim Sep 14, 2023
25a9a8f
update import map
feedthejim Sep 14, 2023
2f3f315
Merge branch 'canary' into feedthejim/bundle-react
feedthejim Sep 15, 2023
3a13db1
revert scheduler rewrites
feedthejim Sep 15, 2023
57a2cfe
add new resolve plugin
feedthejim Sep 15, 2023
90541a9
undo require changes
feedthejim Sep 15, 2023
1cd252d
fix import mappings
feedthejim Sep 15, 2023
dab2ad1
fix contexts load in turbo
feedthejim Sep 15, 2023
99caa9e
fix edge
feedthejim Sep 15, 2023
615a8d6
fix typo in import map
feedthejim Sep 15, 2023
0673756
move worker env init higher
feedthejim Sep 15, 2023
2237523
fix worker runtime usage
feedthejim Sep 15, 2023
a927bca
try to disable wildcard rule
feedthejim Sep 15, 2023
6b04748
fix hmr
feedthejim Sep 15, 2023
827bb43
clean up
feedthejim Sep 15, 2023
1874883
fix HMR
feedthejim Sep 15, 2023
65d43d6
big cleanup
feedthejim Sep 15, 2023
db67e63
dead code
feedthejim Sep 15, 2023
84825ce
Merge branch 'canary' into feedthejim/bundle-react
kodiakhq[bot] Sep 15, 2023
f9f6945
Merge branch 'canary' into feedthejim/bundle-react
kodiakhq[bot] Sep 15, 2023
485f0ae
manually include vendored contexts files
ijjk Sep 15, 2023
e2db79b
Merge branch 'feedthejim/bundle-react' of github.com:vercel/next.js i…
ijjk Sep 15, 2023
320bc74
Update packages/next-swc/crates/next-core/src/next_shared/resolve.rs
feedthejim Sep 15, 2023
6de51b2
address comments
feedthejim Sep 15, 2023
a2acaed
fix trace path
ijjk Sep 15, 2023
05e7d8b
Merge branch 'feedthejim/bundle-react' of github.com:vercel/next.js i…
ijjk Sep 15, 2023
bf1ad0b
revert vendored react changes
feedthejim Sep 15, 2023
33ec18b
remove typeof window define
feedthejim Sep 15, 2023
dcef2aa
Merge branch 'canary' into feedthejim/bundle-react
kodiakhq[bot] Sep 15, 2023
4a967fa
bump
ijjk Sep 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
279 changes: 192 additions & 87 deletions packages/next-swc/crates/next-core/src/next_import_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,7 @@ pub async fn get_next_server_import_map(
| ServerContextType::AppRSC { .. }
| ServerContextType::AppRoute { .. } => {
match mode {
NextMode::Build => {
import_map.insert_wildcard_alias("next/dist/server/", external);
import_map.insert_wildcard_alias("next/dist/shared/", external);
}
NextMode::Build => {}
NextMode::DevServer => {
// The sandbox can't be bundled and needs to be external
import_map.insert_exact_alias("next/dist/server/web/sandbox", external);
Expand Down Expand Up @@ -431,61 +428,138 @@ 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 }) => {
// the logic closely follows the one in createRSCAliases in webpack-config.ts
(
NextMode::DevServer | NextMode::Build | NextMode::Development,
ServerContextType::AppSSR { app_dir },
) => {
import_map.insert_exact_alias(
"@opentelemetry/api",
// TODO(WEB-625) this actually need to prefer the local version of
// @opentelemetry/api
request_to_import_mapping(app_dir, "next/dist/compiled/@opentelemetry/api"),
);
import_map.insert_exact_alias(
"react",
passthrough_external_if_node(app_dir, "next/dist/compiled/react"),
"styled-jsx",
passthrough_external_if_node(app_dir, "next/dist/compiled/styled-jsx"),
);
import_map.insert_wildcard_alias(
"react/",
passthrough_external_if_node(app_dir, "next/dist/compiled/react/*"),
"styled-jsx/",
passthrough_external_if_node(app_dir, "next/dist/compiled/styled-jsx/*"),
);
import_map.insert_exact_alias(
"react/jsx-runtime",
request_to_import_mapping(
app_dir,
match runtime {
NextRuntime::Edge => "next/dist/compiled/react/jsx-runtime",
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/shared/\
react-jsx-runtime"
}
},
),
);
import_map.insert_exact_alias(
"react/jsx-dev-runtime",
request_to_import_mapping(
app_dir,
match runtime {
NextRuntime::Edge => "next/dist/compiled/react/jsx-dev-runtime",
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/shared/\
react-jsx-dev-runtime"
}
},
),
);
import_map.insert_exact_alias(
"react",
request_to_import_mapping(
app_dir,
match runtime {
NextRuntime::Edge => "next/dist/compiled/react",
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/ssr/react"
}
},
),
);
import_map.insert_exact_alias(
"react-dom",
passthrough_external_if_node(
request_to_import_mapping(
app_dir,
"next/dist/compiled/react-dom/server-rendering-stub.js",
match runtime {
NextRuntime::Edge => "next/dist/compiled/react-dom",
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/ssr/react-dom"
}
},
),
);
import_map.insert_wildcard_alias(
"react-dom/",
passthrough_external_if_node(app_dir, "next/dist/compiled/react-dom/*"),
import_map.insert_exact_alias(
"react-server-dom-webpack/client.edge",
request_to_import_mapping(
app_dir,
match runtime {
NextRuntime::Edge => {
"next/dist/compiled/react-server-dom-webpack/client.edge"
}
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/ssr/\
react-server-dom-webpack-client-edge"
}
},
),
);
// some code also imports react-server-dom-webpack/client on the server
// it should never run so it's fine to just point it to the same place as
// react-server-dom-webpack/client.edge
import_map.insert_exact_alias(
"styled-jsx",
passthrough_external_if_node(app_dir, "next/dist/compiled/styled-jsx"),
"react-server-dom-webpack/client",
request_to_import_mapping(
app_dir,
match runtime {
NextRuntime::Edge => {
"next/dist/compiled/react-server-dom-webpack/client.edge"
}
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/ssr/\
react-server-dom-webpack-client-edge"
}
},
),
);
import_map.insert_wildcard_alias(
"styled-jsx/",
passthrough_external_if_node(app_dir, "next/dist/compiled/styled-jsx/*"),
// not essential but we're providing this alias for people who might use it.
// A note here is that this will point toward the ReactDOMServer on the SSR
// layer TODO: add the rests
import_map.insert_exact_alias(
"react-dom/server",
request_to_import_mapping(
app_dir,
match runtime {
NextRuntime::Edge => "next/dist/compiled/react-dom/server.edge",
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/ssr/\
react-dom-server-edge"
}
},
),
);
import_map.insert_wildcard_alias(
"react-server-dom-webpack/",
passthrough_external_if_node(
import_map.insert_exact_alias(
"react-dom/server.edge",
request_to_import_mapping(
app_dir,
"next/dist/compiled/react-server-dom-webpack/*",
match runtime {
NextRuntime::Edge => "next/dist/compiled/react-dom/server.edge",
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/ssr/\
react-dom-server-edge"
}
},
),
);
}

// NOTE(alexkirsz) This logic maps loosely to
// `next.js/packages/next/src/build/webpack-config.ts`, where:
//
// ## RSC
//
// * always bundles
// * maps react -> react/shared-subset (through the "react-server" exports condition)
// * maps react-dom -> react-dom/server-rendering-stub
// * passes through (react|react-dom|react-server-dom-webpack)/(.*) to
// next/dist/compiled/$1/$2
(
NextMode::Build | NextMode::Development | NextMode::DevServer,
ServerContextType::AppRSC { app_dir, .. } | ServerContextType::AppRoute { app_dir },
Expand All @@ -496,72 +570,103 @@ async fn insert_next_server_special_aliases(
// @opentelemetry/api
request_to_import_mapping(app_dir, "next/dist/compiled/@opentelemetry/api"),
);
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",
"react/jsx-runtime",
request_to_import_mapping(
app_dir,
"next/dist/compiled/react-dom/server-rendering-stub",
match runtime {
NextRuntime::Edge => "next/dist/compiled/react/jsx-runtime",
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/shared/\
react-jsx-runtime"
}
},
),
);
for (wildcard_alias, request) in [
("react/", "next/dist/compiled/react/*"),
("react-dom/", "next/dist/compiled/react-dom/*"),
(
"react-server-dom-webpack/",
"next/dist/compiled/react-server-dom-webpack/*",
import_map.insert_exact_alias(
"react/jsx-dev-runtime",
request_to_import_mapping(
app_dir,
match runtime {
NextRuntime::Edge => "next/dist/compiled/react/jsx-dev-runtime",
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/shared/\
react-jsx-dev-runtime"
}
},
),
] {
import_map.insert_wildcard_alias(
wildcard_alias,
request_to_import_mapping(app_dir, request),
);
}
}
// ## SSR
//
// * always uses externals, to ensure we're using the same React instance as the Next.js
// runtime
// * maps react-dom -> react-dom/server-rendering-stub
// * passes through react and (react|react-dom|react-server-dom-webpack)/(.*) to
// next/dist/compiled/react and next/dist/compiled/$1/$2 resp.
(NextMode::Build | NextMode::Development, ServerContextType::AppSSR { app_dir }) => {
);
import_map.insert_exact_alias(
"react",
external_if_node(app_dir, "next/dist/compiled/react"),
request_to_import_mapping(
app_dir,
match runtime {
NextRuntime::Edge => "next/dist/compiled/react",
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/rsc/react"
}
},
),
);
import_map.insert_exact_alias(
"react-dom",
external_if_node(
request_to_import_mapping(
app_dir,
"next/dist/compiled/react-dom/server-rendering-stub",
match runtime {
NextRuntime::Edge => "next/dist/compiled/react-dom",
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/rsc/react-dom"
}
},
),
);

for (wildcard_alias, request) in [
("react/", "next/dist/compiled/react/*"),
("react-dom/", "next/dist/compiled/react-dom/*"),
(
"react-server-dom-webpack/",
"next/dist/compiled/react-server-dom-webpack/*",
import_map.insert_exact_alias(
"react-server-dom-webpack/server.edge",
request_to_import_mapping(
app_dir,
match runtime {
NextRuntime::Edge => {
"next/dist/compiled/react-server-dom-webpack/server.edge"
}
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/rsc/\
react-server-dom-webpack-server-edge"
}
},
),
] {
let import_mapping = external_if_node(app_dir, request);
import_map.insert_wildcard_alias(wildcard_alias, import_mapping);
}
);
import_map.insert_exact_alias(
"react-server-dom-webpack/server.node",
request_to_import_mapping(
app_dir,
match runtime {
NextRuntime::Edge => {
"next/dist/compiled/react-server-dom-webpack/server.node"
}
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/rsc/\
react-server-dom-webpack-server-node"
}
},
),
);
// not essential but we're providing this alias for people who might use it.
// A note here is that this will point toward the ReactDOMServer on the SSR
// layer TODO: add the rests
import_map.insert_exact_alias(
"react-dom/server.edge",
request_to_import_mapping(
app_dir,
match runtime {
NextRuntime::Edge => "next/dist/compiled/react-dom/server.edge",
NextRuntime::NodeJs => {
"next/dist/server/future/route-modules/app-page/vendored/ssr/\
react-dom-server-edge"
}
},
),
);
}
(_, ServerContextType::Middleware) => {}
}
Expand Down
9 changes: 7 additions & 2 deletions packages/next-swc/crates/next-core/src/next_server/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ use crate::{
next_shared::{
resolve::{
ModuleFeatureReportResolvePlugin, NextExternalResolvePlugin,
UnsupportedModulesResolvePlugin,
NextNodeSharedRuntimeResolvePlugin, UnsupportedModulesResolvePlugin,
},
transforms::{
emotion::get_emotion_transform_plugin, get_relay_transform_plugin,
Expand Down Expand Up @@ -125,6 +125,8 @@ pub async fn get_server_resolve_options_context(
);

let next_external_plugin = NextExternalResolvePlugin::new(project_path);
let next_node_shared_runtime_plugin =
NextNodeSharedRuntimeResolvePlugin::new(project_path, Value::new(ty));

let plugins = match ty {
ServerContextType::Pages { .. } | ServerContextType::PagesData { .. } => {
Expand All @@ -133,6 +135,7 @@ pub async fn get_server_resolve_options_context(
Vc::upcast(external_cjs_modules_plugin),
Vc::upcast(unsupported_modules_resolve_plugin),
Vc::upcast(next_external_plugin),
Vc::upcast(next_node_shared_runtime_plugin),
]
}
ServerContextType::AppSSR { .. }
Expand All @@ -144,6 +147,7 @@ pub async fn get_server_resolve_options_context(
Vc::upcast(server_component_externals_plugin),
Vc::upcast(unsupported_modules_resolve_plugin),
Vc::upcast(next_external_plugin),
Vc::upcast(next_node_shared_runtime_plugin),
]
}
};
Expand Down Expand Up @@ -175,7 +179,8 @@ fn defines(mode: NextMode) -> CompileTimeDefines {
process.turbopack = true,
process.env.NODE_ENV = mode.node_env(),
process.env.__NEXT_CLIENT_ROUTER_FILTER_ENABLED = false,
process.env.NEXT_RUNTIME = "nodejs"
process.env.NEXT_RUNTIME = "nodejs",
process.env.__NEXT_EXPERIMENTAL_REACT = false,
feedthejim marked this conversation as resolved.
Show resolved Hide resolved
)
// TODO(WEB-937) there are more defines needed, see
// packages/next/src/build/webpack-config.ts
Expand Down
Loading
Loading