Skip to content

Commit 61baae1

Browse files
authored
fix Next.rs API (vercel#53456)
### What? * fixes problems in Next.rs API introduced by vercel#52846 * adds test infrastructure for experimental turbo testing * adds two test cases to verify the infrastructure * add grouping of output logs in run-tests * simplify template loading ### Why? ### How?
1 parent eecd8dc commit 61baae1

27 files changed

Lines changed: 1877 additions & 1772 deletions

.github/workflows/build_and_test.yml

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,15 @@ jobs:
125125
afterBuild: turbo run rust-check
126126
secrets: inherit
127127

128+
test-experimental-turbopack-dev:
129+
name: test experimental turbopack dev
130+
needs: ['build-native', 'build-next']
131+
uses: ./.github/workflows/build_reusable.yml
132+
with:
133+
skipForDocsOnly: 'yes'
134+
afterBuild: RUST_BACKTRACE=0 NEXT_EXTERNAL_TESTS_FILTERS="$(pwd)/test/turbopack-tests-manifest.js" EXPERIMENTAL_TURBOPACK=1 NEXT_E2E_TEST_TIMEOUT=240000 NEXT_TEST_MODE=dev node run-tests.js --test-pattern '^(test\/development)/.*\.test\.(js|jsx|ts|tsx)$' --timings -c ${TEST_CONCURRENCY}
135+
secrets: inherit
136+
128137
test-turbopack-dev:
129138
name: test turbopack dev
130139
needs: ['build-native', 'build-next']
@@ -134,6 +143,21 @@ jobs:
134143
afterBuild: RUST_BACKTRACE=0 NEXT_EXTERNAL_TESTS_FILTERS="$(pwd)/packages/next-swc/crates/next-dev-tests/tests-manifest.js" TURBOPACK=1 __INTERNAL_CUSTOM_TURBOPACK_BINDINGS="$(pwd)/packages/next-swc/native/next-swc.linux-x64-gnu.node" NEXT_E2E_TEST_TIMEOUT=240000 NEXT_TEST_MODE=dev node run-tests.js --test-pattern '^(test\/development)/.*\.test\.(js|jsx|ts|tsx)$' --timings -c ${TEST_CONCURRENCY}
135144
secrets: inherit
136145

146+
test-experimental-turbopack-integration:
147+
name: test experimental turbopack integration
148+
needs: ['build-native', 'build-next']
149+
strategy:
150+
fail-fast: false
151+
matrix:
152+
group: [1]
153+
154+
uses: ./.github/workflows/build_reusable.yml
155+
with:
156+
nodeVersion: 16
157+
skipForDocsOnly: 'yes'
158+
afterBuild: RUST_BACKTRACE=0 NEXT_EXTERNAL_TESTS_FILTERS="$(pwd)/test/turbopack-tests-manifest.js" EXPERIMENTAL_TURBOPACK=1 node run-tests.js --timings -g ${{ matrix.group }}/1 -c ${TEST_CONCURRENCY} --type integration
159+
secrets: inherit
160+
137161
test-turbopack-integration:
138162
name: test turbopack integration
139163
needs: ['build-native', 'build-next']
@@ -148,7 +172,6 @@ jobs:
148172
skipForDocsOnly: 'yes'
149173
afterBuild: RUST_BACKTRACE=0 NEXT_EXTERNAL_TESTS_FILTERS="$(pwd)/packages/next-swc/crates/next-dev-tests/tests-manifest.js" TURBOPACK=1 __INTERNAL_CUSTOM_TURBOPACK_BINDINGS="$(pwd)/packages/next-swc/native/next-swc.linux-x64-gnu.node" node run-tests.js --timings -g ${{ matrix.group }}/5 -c ${TEST_CONCURRENCY} --type integration
150174
secrets: inherit
151-
152175
test-next-swc-wasm:
153176
name: test next-swc wasm
154177
needs: ['build-native', 'build-next']
@@ -244,7 +267,9 @@ jobs:
244267
'rust-check',
245268
'test-next-swc-wasm',
246269
'test-turbopack-dev',
270+
'test-experimental-turbopack-dev',
247271
'test-turbopack-integration',
272+
'test-experimental-turbopack-integration',
248273
]
249274

250275
if: always()

packages/next-swc/crates/next-api/src/app.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ impl AppEndpoint {
451451
loader_tree,
452452
self.app_project.app_dir(),
453453
self.pathname.clone(),
454+
self.original_name.clone(),
454455
self.app_project.project().project_path(),
455456
)
456457
}
@@ -462,6 +463,7 @@ impl AppEndpoint {
462463
self.app_project.edge_rsc_module_context(),
463464
Vc::upcast(FileSource::new(path)),
464465
self.pathname.clone(),
466+
self.original_name.clone(),
465467
self.app_project.project().project_path(),
466468
)
467469
}

packages/next-swc/crates/next-api/src/pages.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,7 @@ impl PageEndpoint {
641641
.project()
642642
.node_root()
643643
.join("server".to_string()),
644-
this.path.root(),
644+
this.pages_project.project().project_path(),
645645
this.pages_project.ssr_module_context(),
646646
this.pages_project.edge_ssr_module_context(),
647647
this.pages_project.project().ssr_chunking_context(),
@@ -660,7 +660,7 @@ impl PageEndpoint {
660660
.project()
661661
.node_root()
662662
.join("server-data".to_string()),
663-
this.path.root(),
663+
this.pages_project.project().project_path(),
664664
this.pages_project.ssr_data_module_context(),
665665
this.pages_project.edge_ssr_data_module_context(),
666666
this.pages_project.project().ssr_data_chunking_context(),
@@ -681,7 +681,7 @@ impl PageEndpoint {
681681
.project()
682682
.node_root()
683683
.join("server".to_string()),
684-
this.path.root(),
684+
this.pages_project.project().project_path(),
685685
this.pages_project.ssr_module_context(),
686686
this.pages_project.edge_ssr_module_context(),
687687
this.pages_project.project().ssr_chunking_context(),

packages/next-swc/crates/next-build/src/next_app/app_entries.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ pub async fn get_app_entries(
190190
.map(|(pathname, entrypoint)| async move {
191191
Ok(match entrypoint {
192192
Entrypoint::AppPage {
193-
original_name: _,
193+
original_name,
194194
loader_tree,
195195
} => get_app_page_entry(
196196
rsc_context,
@@ -199,17 +199,19 @@ pub async fn get_app_entries(
199199
*loader_tree,
200200
app_dir,
201201
pathname.clone(),
202+
original_name.clone(),
202203
project_root,
203204
),
204205
Entrypoint::AppRoute {
205-
original_name: _,
206+
original_name,
206207
path,
207208
} => get_app_route_entry(
208209
rsc_context,
209210
// TODO add edge support
210211
rsc_context,
211212
Vc::upcast(FileSource::new(*path)),
212213
pathname.clone(),
214+
original_name.clone(),
213215
project_root,
214216
),
215217
})

packages/next-swc/crates/next-core/src/next_app/app_favicon_entry.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ pub async fn get_app_route_favicon_entry(
8585
Vc::upcast(source),
8686
// TODO(alexkirsz) Get this from the metadata?
8787
"/favicon.ico".to_string(),
88+
"/favicon.ico".to_string(),
8889
project_root,
8990
))
9091
}

packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use turbopack_binding::{
66
turbo::tasks_fs::{rope::RopeBuilder, File, FileSystemPath},
77
turbopack::{
88
core::{
9-
asset::AssetContent, context::AssetContext, issue::IssueExt, module::Module,
9+
asset::AssetContent, context::AssetContext, issue::IssueExt,
1010
reference_type::ReferenceType, virtual_source::VirtualSource,
1111
},
1212
ecmascript::{chunk::EcmascriptChunkPlaceable, utils::StringifyJs},
@@ -22,7 +22,7 @@ use crate::{
2222
next_app::UnsupportedDynamicMetadataIssue,
2323
next_server_component::NextServerComponentTransition,
2424
parse_segment_config_from_loader_tree,
25-
util::{load_next_js, resolve_next_module, NextRuntime},
25+
util::{load_next_js_template, virtual_next_js_template_path, NextRuntime},
2626
};
2727

2828
/// Computes the entry for a Next.js app page.
@@ -33,6 +33,7 @@ pub async fn get_app_page_entry(
3333
loader_tree: Vc<LoaderTree>,
3434
app_dir: Vc<FileSystemPath>,
3535
pathname: String,
36+
original_name: String,
3637
project_root: Vc<FileSystemPath>,
3738
) -> Result<Vc<AppEntry>> {
3839
let config = parse_segment_config_from_loader_tree(loader_tree, Vc::upcast(nodejs_context));
@@ -77,12 +78,12 @@ pub async fn get_app_page_entry(
7778

7879
let pages = pages.iter().map(|page| page.to_string()).try_join().await?;
7980

80-
let original_name = get_original_page_name(&pathname);
81+
let original_page_name = get_original_page_name(&original_name);
8182

82-
let template_file = "/dist/esm/build/webpack/loaders/next-route-loader/templates/app-page.js";
83+
let template_file = "build/webpack/loaders/next-route-loader/templates/app-page.js";
8384

8485
// Load the file from the next.js codebase.
85-
let file = load_next_js(project_root, template_file).await?.await?;
86+
let file = load_next_js_template(project_root, template_file.to_string()).await?;
8687

8788
let mut file = file
8889
.to_str()?
@@ -96,7 +97,7 @@ pub async fn get_app_page_entry(
9697
)
9798
.replace(
9899
"\"VAR_ORIGINAL_PATHNAME\"",
99-
&StringifyJs(&original_name).to_string(),
100+
&StringifyJs(&original_page_name).to_string(),
100101
)
101102
// TODO(alexkirsz) Support custom global error.
102103
.replace(
@@ -129,13 +130,7 @@ pub async fn get_app_page_entry(
129130

130131
let file = File::from(result.build());
131132

132-
let resolve_result = resolve_next_module(project_root, template_file).await?;
133-
134-
let Some(template_path) = *resolve_result.first_module().await? else {
135-
bail!("Expected to find module");
136-
};
137-
138-
let template_path = template_path.ident().path();
133+
let template_path = virtual_next_js_template_path(project_root, template_file.to_string());
139134

140135
let source = VirtualSource::new(template_path, AssetContent::file(file.into()));
141136

@@ -152,7 +147,7 @@ pub async fn get_app_page_entry(
152147

153148
Ok(AppEntry {
154149
pathname: pathname.to_string(),
155-
original_name,
150+
original_name: original_page_name,
156151
rsc_entry,
157152
config,
158153
}

packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use turbopack_binding::{
77
core::{
88
asset::AssetContent,
99
context::AssetContext,
10-
module::Module,
1110
reference_type::{
1211
EcmaScriptModulesReferenceSubType, EntryReferenceSubType, ReferenceType,
1312
},
@@ -22,7 +21,7 @@ use turbopack_binding::{
2221
use crate::{
2322
next_app::AppEntry,
2423
parse_segment_config_from_source,
25-
util::{load_next_js, resolve_next_module, NextRuntime},
24+
util::{load_next_js_template, virtual_next_js_template_path, NextRuntime},
2625
};
2726

2827
/// Computes the entry for a Next.js app route.
@@ -32,6 +31,7 @@ pub async fn get_app_route_entry(
3231
edge_context: Vc<ModuleAssetContext>,
3332
source: Vc<Box<dyn Source>>,
3433
pathname: String,
34+
original_name: String,
3535
project_root: Vc<FileSystemPath>,
3636
) -> Result<Vc<AppEntry>> {
3737
let config = parse_segment_config_from_source(
@@ -49,13 +49,13 @@ pub async fn get_app_route_entry(
4949

5050
let mut result = RopeBuilder::default();
5151

52-
let original_name = get_original_route_name(&pathname);
52+
let original_page_name = get_original_route_name(&original_name);
5353
let path = source.ident().path();
5454

55-
let template_file = "/dist/esm/build/webpack/loaders/next-route-loader/templates/app-route.js";
55+
let template_file = "build/webpack/loaders/next-route-loader/templates/app-route.js";
5656

5757
// Load the file from the next.js codebase.
58-
let file = load_next_js(project_root, template_file).await?.await?;
58+
let file = load_next_js_template(project_root, template_file.to_string()).await?;
5959

6060
let mut file = file
6161
.to_str()?
@@ -78,7 +78,7 @@ pub async fn get_app_route_entry(
7878
)
7979
.replace(
8080
"\"VAR_ORIGINAL_PATHNAME\"",
81-
&StringifyJs(&original_name).to_string(),
81+
&StringifyJs(&original_page_name).to_string(),
8282
)
8383
.replace(
8484
"\"VAR_RESOLVED_PAGE_PATH\"",
@@ -98,13 +98,7 @@ pub async fn get_app_route_entry(
9898

9999
let file = File::from(result.build());
100100

101-
let resolve_result = resolve_next_module(project_root, template_file).await?;
102-
103-
let Some(template_path) = *resolve_result.first_module().await? else {
104-
bail!("Expected to find module");
105-
};
106-
107-
let template_path = template_path.ident().path();
101+
let template_path = virtual_next_js_template_path(project_root, template_file.to_string());
108102

109103
let virtual_source = VirtualSource::new(template_path, AssetContent::file(file.into()));
110104

@@ -132,7 +126,7 @@ pub async fn get_app_route_entry(
132126

133127
Ok(AppEntry {
134128
pathname: pathname.to_string(),
135-
original_name,
129+
original_name: original_page_name,
136130
rsc_entry,
137131
config,
138132
}

packages/next-swc/crates/next-core/src/next_font/google/font_fallback.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::{
2020
issue::NextFontIssue,
2121
util::{get_scoped_font_family, FontFamilyType},
2222
},
23-
util::load_next_json,
23+
util::load_next_js_templateon,
2424
};
2525

2626
/// An entry in the Google fonts metrics map
@@ -54,8 +54,11 @@ pub(super) async fn get_font_fallback(
5454
Ok(match &options.fallback {
5555
Some(fallback) => FontFallback::Manual(Vc::cell(fallback.clone())).cell(),
5656
None => {
57-
let metrics_json =
58-
load_next_json(context, "/dist/server/capsize-font-metrics.json").await?;
57+
let metrics_json = load_next_js_templateon(
58+
context,
59+
"dist/server/capsize-font-metrics.json".to_string(),
60+
)
61+
.await?;
5962
let fallback = lookup_fallback(
6063
&options.font_family,
6164
metrics_json,

packages/next-swc/crates/next-core/src/next_font/google/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ use super::{
4848
get_request_hash, get_request_id, get_scoped_font_family, FontCssProperties, FontFamilyType,
4949
},
5050
};
51-
use crate::{embed_js::next_js_file_path, util::load_next_json};
51+
use crate::{embed_js::next_js_file_path, util::load_next_js_templateon};
5252

5353
pub mod font_fallback;
5454
pub mod options;
@@ -266,9 +266,9 @@ impl ImportMappingReplacement for NextFontGoogleCssModuleReplacer {
266266

267267
#[turbo_tasks::function]
268268
async fn load_font_data(project_root: Vc<FileSystemPath>) -> Result<Vc<FontData>> {
269-
let data: FontData = load_next_json(
269+
let data: FontData = load_next_js_templateon(
270270
project_root,
271-
"/dist/compiled/@next/font/dist/google/font-data.json",
271+
"dist/compiled/@next/font/dist/google/font-data.json".to_string(),
272272
)
273273
.await?;
274274

packages/next-swc/crates/next-core/src/next_import_map.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,16 @@ pub async fn get_next_server_import_map(
229229
ServerContextType::AppSSR { .. }
230230
| ServerContextType::AppRSC { .. }
231231
| ServerContextType::AppRoute { .. } => {
232+
match mode {
233+
NextMode::Development | NextMode::Build => {
234+
import_map.insert_wildcard_alias("next/dist/server/", external);
235+
import_map.insert_wildcard_alias("next/dist/shared/", external);
236+
}
237+
NextMode::DevServer => {
238+
// The sandbox can't be bundled and needs to be external
239+
import_map.insert_exact_alias("next/dist/server/web/sandbox", external);
240+
}
241+
}
232242
import_map.insert_exact_alias(
233243
"next/head",
234244
request_to_import_mapping(project_path, "next/dist/client/components/noop-head"),
@@ -237,9 +247,6 @@ pub async fn get_next_server_import_map(
237247
"next/dynamic",
238248
request_to_import_mapping(project_path, "next/dist/shared/lib/app-dynamic"),
239249
);
240-
241-
// The sandbox can't be bundled and needs to be external
242-
import_map.insert_exact_alias("next/dist/server/web/sandbox", external);
243250
}
244251
ServerContextType::Middleware => {}
245252
}
@@ -620,17 +627,19 @@ async fn package_lookup_resolve_options(
620627
}
621628

622629
#[turbo_tasks::function]
623-
pub async fn get_next_package(project_path: Vc<FileSystemPath>) -> Result<Vc<FileSystemPath>> {
630+
pub async fn get_next_package(context_directory: Vc<FileSystemPath>) -> Result<Vc<FileSystemPath>> {
624631
let result = resolve(
625-
project_path,
632+
context_directory,
626633
Request::parse(Value::new(Pattern::Constant(
627634
"next/package.json".to_string(),
628635
))),
629-
package_lookup_resolve_options(project_path),
636+
package_lookup_resolve_options(context_directory),
630637
);
631-
let assets = result.primary_sources().await?;
632-
let asset = *assets.first().context("Next.js package not found")?;
633-
Ok(asset.ident().path().parent())
638+
let source = result
639+
.first_source()
640+
.await?
641+
.context("Next.js package not found")?;
642+
Ok(source.ident().path().parent())
634643
}
635644

636645
pub async fn insert_alias_option<const N: usize>(

0 commit comments

Comments
 (0)