Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/next-stats-action.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ RUN corepack enable
FROM base AS pnpm-deploy

WORKDIR /dot-github
COPY pnpm-lock.yaml pnpm-workspace.yaml .
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY --exclude=actions/*/node_modules \
actions/next-stats-action actions/next-stats-action
RUN pnpm deploy --filter=next-stats-action --production /next-stats
Expand Down
5 changes: 5 additions & 0 deletions .github/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "next-github-workflows",
"private": true,
"packageManager": "pnpm@10.33.0"
}
2 changes: 2 additions & 0 deletions .github/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/next-api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ fn main() -> anyhow::Result<()> {
.target_triple(true)
.build()?;
vergen::Emitter::default()
.add_instructions(&cargo)?
.fail_on_error()
.add_instructions(&cargo)?
.emit()?;

Ok(())
Expand Down
83 changes: 55 additions & 28 deletions crates/next-core/src/app_page_loader_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@ impl AppPageLoaderTreeBuilder {
&mut self,
module_type: AppDirModuleType,
path: Option<FileSystemPath>,
depth: u32,
) -> Result<()> {
if let Some(path) = path {
let tuple_code = self
.base
.create_module_tuple_code(module_type, path)
.create_module_tuple_code(module_type, path, depth)
.await?;

writeln!(
Expand All @@ -71,6 +72,7 @@ impl AppPageLoaderTreeBuilder {
app_page: &AppPage,
metadata: &Metadata,
global_metadata: Option<&GlobalMetadata>,
depth: u32,
) -> Result<()> {
if metadata.is_empty()
&& global_metadata
Expand Down Expand Up @@ -107,13 +109,13 @@ impl AppPageLoaderTreeBuilder {
icon.clone()
};

self.write_metadata_items(app_page, "icon", icon.iter())
self.write_metadata_items(app_page, "icon", icon.iter(), depth)
.await?;
self.write_metadata_items(app_page, "apple", apple.iter())
self.write_metadata_items(app_page, "apple", apple.iter(), depth)
.await?;
self.write_metadata_items(app_page, "twitter", twitter.iter())
self.write_metadata_items(app_page, "twitter", twitter.iter(), depth)
.await?;
self.write_metadata_items(app_page, "openGraph", open_graph.iter())
self.write_metadata_items(app_page, "openGraph", open_graph.iter(), depth)
.await?;

if let Some(global_metadata) = global_metadata {
Expand Down Expand Up @@ -151,14 +153,16 @@ impl AppPageLoaderTreeBuilder {
app_page: &AppPage,
name: &str,
it: impl Iterator<Item = &'a MetadataWithAltItem>,
depth: u32,
) -> Result<()> {
let mut it = it.peekable();
if it.peek().is_none() {
return Ok(());
}
writeln!(self.loader_tree_code, " {name}: [")?;
for item in it {
self.write_metadata_item(app_page, name, item).await?;
self.write_metadata_item(app_page, name, item, depth)
.await?;
}
writeln!(self.loader_tree_code, " ],")?;
Ok(())
Expand All @@ -169,6 +173,7 @@ impl AppPageLoaderTreeBuilder {
app_page: &AppPage,
name: &str,
item: &MetadataWithAltItem,
depth: u32,
) -> Result<()> {
match item {
MetadataWithAltItem::Static { path, alt_path } => {
Expand All @@ -178,6 +183,7 @@ impl AppPageLoaderTreeBuilder {
item,
path.clone(),
alt_path.clone(),
depth,
)
.await?;
}
Expand All @@ -189,13 +195,14 @@ impl AppPageLoaderTreeBuilder {
// This should use the same importing mechanism as create_module_tuple_code, so that
// the relative order of items is retained (which isn't the case
// when mixing ESM imports and requires).
self.base.imports.push(
self.base.imports.push((
depth,
format!(
"const {identifier} = () => require(/*turbopackChunkingType: \
shared*/\"{inner_module_id}\");"
)
.into(),
);
));

let source = dynamic_image_metadata_source(
*ResolvedVc::upcast(self.base.module_asset_context),
Expand Down Expand Up @@ -226,6 +233,7 @@ impl AppPageLoaderTreeBuilder {
item: &MetadataWithAltItem,
path: FileSystemPath,
alt_path: Option<FileSystemPath>,
depth: u32,
) -> Result<()> {
let i = self.base.unique_number();

Expand All @@ -235,13 +243,14 @@ impl AppPageLoaderTreeBuilder {
// This should use the same importing mechanism as create_module_tuple_code, so that the
// relative order of items is retained (which isn't the case when mixing ESM imports and
// requires).
self.base.imports.push(
self.base.imports.push((
depth,
format!(
"const {identifier} = () => require(/*turbopackChunkingType: \
shared*/\"{inner_module_id}\");"
)
.into(),
);
));
let module = StructuredImageModuleType::create_module(
Vc::upcast(FileSource::new(path.clone())),
BlurPlaceholderMode::None,
Expand All @@ -259,13 +268,14 @@ impl AppPageLoaderTreeBuilder {
// This should use the same importing mechanism as create_module_tuple_code, so that the
// relative order of items is retained (which isn't the case when mixing ESM imports and
// requires).
self.base.imports.push(
self.base.imports.push((
depth,
format!(
"const {identifier} = () => require(/*turbopackChunkingType: \
shared*/\"{inner_module_id}\");"
)
.into(),
);
));

let module = self
.base
Expand Down Expand Up @@ -342,7 +352,12 @@ impl AppPageLoaderTreeBuilder {
Ok(())
}

async fn walk_tree(&mut self, loader_tree: &AppPageLoaderTree, root: bool) -> Result<()> {
async fn walk_tree(
&mut self,
loader_tree: &AppPageLoaderTree,
root: bool,
depth: u32,
) -> Result<()> {
use std::fmt::Write;

let AppPageLoaderTree {
Expand Down Expand Up @@ -385,38 +400,48 @@ impl AppPageLoaderTreeBuilder {
app_page,
metadata,
if root { Some(global_metadata) } else { None },
depth,
)
.await?;

self.write_modules_entry(AppDirModuleType::Layout, layout.clone())
self.write_modules_entry(AppDirModuleType::Layout, layout.clone(), depth)
.await?;
self.write_modules_entry(AppDirModuleType::Error, error.clone())
self.write_modules_entry(AppDirModuleType::Error, error.clone(), depth)
.await?;
self.write_modules_entry(AppDirModuleType::Loading, loading.clone())
self.write_modules_entry(AppDirModuleType::Loading, loading.clone(), depth)
.await?;
self.write_modules_entry(AppDirModuleType::Template, template.clone())
self.write_modules_entry(AppDirModuleType::Template, template.clone(), depth)
.await?;
self.write_modules_entry(AppDirModuleType::NotFound, not_found.clone())
self.write_modules_entry(AppDirModuleType::NotFound, not_found.clone(), depth)
.await?;
self.write_modules_entry(AppDirModuleType::Forbidden, forbidden.clone())
self.write_modules_entry(AppDirModuleType::Forbidden, forbidden.clone(), depth)
.await?;
self.write_modules_entry(AppDirModuleType::Unauthorized, unauthorized.clone())
self.write_modules_entry(AppDirModuleType::Unauthorized, unauthorized.clone(), depth)
.await?;
self.write_modules_entry(AppDirModuleType::Page, page.clone())
self.write_modules_entry(AppDirModuleType::Page, page.clone(), depth)
.await?;
self.write_modules_entry(AppDirModuleType::DefaultPage, default.clone())
self.write_modules_entry(AppDirModuleType::DefaultPage, default.clone(), depth)
.await?;
self.write_modules_entry(AppDirModuleType::GlobalError, global_error.clone())
.await?;
self.write_modules_entry(AppDirModuleType::GlobalNotFound, global_not_found.clone())
self.write_modules_entry(AppDirModuleType::GlobalError, global_error.clone(), depth)
.await?;
self.write_modules_entry(
AppDirModuleType::GlobalNotFound,
global_not_found.clone(),
depth,
)
.await?;

let modules_code = replace(&mut self.loader_tree_code, temp_loader_tree_code);

// add parallel_routes
for (key, parallel_route) in parallel_routes.iter() {
write!(self.loader_tree_code, "{key}: ", key = StringifyJs(key))?;
Box::pin(self.walk_tree(parallel_route, false)).await?;
let next_depth = if key.as_str() == "children" {
depth + 1
} else {
depth
};
Box::pin(self.walk_tree(parallel_route, false, next_depth)).await?;
writeln!(self.loader_tree_code, ",")?;
}
writeln!(self.loader_tree_code, "}}, {{")?;
Expand Down Expand Up @@ -454,9 +479,11 @@ impl AppPageLoaderTreeBuilder {
.insert(GLOBAL_NOT_FOUND.into(), module);
};

self.walk_tree(loader_tree, true).await?;
self.walk_tree(loader_tree, true, 0).await?;
let mut imports = self.base.imports;
imports.sort_by_key(|(position, _)| *position);
Ok(AppPageLoaderTreeModule {
imports: self.base.imports,
imports: imports.into_iter().map(|(_, import)| import).collect(),
loader_tree_code: self.loader_tree_code.into(),
inner_assets: self.base.inner_assets,
})
Expand Down
8 changes: 5 additions & 3 deletions crates/next-core/src/base_loader_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use turbopack_ecmascript::{magic_identifier, utils::StringifyJs};
pub struct BaseLoaderTreeBuilder {
pub inner_assets: FxIndexMap<RcStr, ResolvedVc<Box<dyn Module>>>,
counter: usize,
pub imports: Vec<RcStr>,
pub imports: Vec<(u32, RcStr)>,
pub module_asset_context: ResolvedVc<ModuleAssetContext>,
pub server_component_transition: ResolvedVc<Box<dyn Transition>>,
}
Expand Down Expand Up @@ -91,12 +91,14 @@ impl BaseLoaderTreeBuilder {
&mut self,
module_type: AppDirModuleType,
path: FileSystemPath,
position: u32,
) -> Result<String> {
let name = module_type.name();
let i = self.unique_number();
let identifier = magic_identifier::mangle(&format!("{name} #{i}"));

self.imports.push(
self.imports.push((
position,
formatdoc!(
r#"
const {} = () => require(/*turbopackChunkingType: shared*/"MODULE_{}");
Expand All @@ -105,7 +107,7 @@ impl BaseLoaderTreeBuilder {
i
)
.into(),
);
));

let module = self
.process_source(Vc::upcast(FileSource::new(path.clone())))
Expand Down
9 changes: 7 additions & 2 deletions crates/next-napi-bindings/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,22 @@ fn main() -> anyhow::Result<()> {
)
.build()?;
vergen_gitcl::Emitter::default()
.fail_on_error()
.add_instructions(&cargo)?
.add_instructions(&git)?
.fail_on_error()
.emit()?;

match Command::new("git").args(["rev-parse", "HEAD"]).output() {
Ok(out) if out.status.success() => println!(
"cargo:warning=git HEAD: {}",
str::from_utf8(&out.stdout).unwrap()
),
_ => println!("cargo:warning=`git rev-parse HEAD` failed"),
Ok(out) => println!(
"cargo:warning=`git rev-parse HEAD` failed with status {}: {}",
out.status,
str::from_utf8(&out.stderr).unwrap()
),
Err(e) => println!("cargo:warning=`git rev-parse HEAD` could not be spawned: {e}"),
}

if !is_macos_target {
Expand Down
14 changes: 7 additions & 7 deletions docs/04-community/01-contribution-guide.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -243,17 +243,17 @@ Most examples in the docs are written in `tsx` and `jsx`, and a few in `bash`. H

When writing JavaScript code blocks, we use the following language and extension combinations.

| | Language | Extension |
| ------------------------------ | -------- | --------- |
| JavaScript files with JSX code | ```jsx | .js |
| JavaScript files without JSX | ```js | .js |
| TypeScript files with JSX | ```tsx | .tsx |
| TypeScript files without JSX | ```ts | .ts |
| | Language | Extension |
| ------------------------------ | ---------- | --------- |
| JavaScript files with JSX code | ` ```jsx ` | .js |
| JavaScript files without JSX | ` ```js ` | .js |
| TypeScript files with JSX | ` ```tsx ` | .tsx |
| TypeScript files without JSX | ` ```ts ` | .ts |

> **Good to know**:
>
> - Make sure to use **`.js`** extension for JavaScript files with **JSX** code.
> - For example, ```jsx filename="app/layout.js"
> - For example, ` ```jsx filename="app/layout.js" `

### TS and JS Switcher

Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "16.3.0-canary.13"
"version": "16.3.0-canary.14"
}
2 changes: 1 addition & 1 deletion packages/create-next-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-next-app",
"version": "16.3.0-canary.13",
"version": "16.3.0-canary.14",
"keywords": [
"react",
"next",
Expand Down
4 changes: 2 additions & 2 deletions packages/eslint-config-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-config-next",
"version": "16.3.0-canary.13",
"version": "16.3.0-canary.14",
"description": "ESLint configuration used by Next.js.",
"license": "MIT",
"repository": {
Expand All @@ -12,7 +12,7 @@
"dist"
],
"dependencies": {
"@next/eslint-plugin-next": "16.3.0-canary.13",
"@next/eslint-plugin-next": "16.3.0-canary.14",
"eslint-import-resolver-node": "^0.3.6",
"eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-import": "^2.32.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-internal/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@next/eslint-plugin-internal",
"private": true,
"version": "16.3.0-canary.13",
"version": "16.3.0-canary.14",
"description": "ESLint plugin for working on Next.js.",
"exports": {
".": "./src/eslint-plugin-internal.js"
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/eslint-plugin-next",
"version": "16.3.0-canary.13",
"version": "16.3.0-canary.14",
"description": "ESLint plugin for Next.js.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/font/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@next/font",
"private": true,
"version": "16.3.0-canary.13",
"version": "16.3.0-canary.14",
"repository": {
"url": "vercel/next.js",
"directory": "packages/font"
Expand Down
Loading
Loading