Skip to content

Commit f1786af

Browse files
ijjkForsakenHarmony
authored andcommitted
Stabilize outputFileTracing configs (#68464)
These configs have been being validated for quite a while now and they are pretty crucial to handle edge-cases without our output tracing setup since we can't always trace 100% of cases. No functional changes are made here expect removal of long deprecated `experimental.outputFileTracingIgnores` and upgrading from experimental for `outputFileTracingRoot`, `outputFileTracingIncludes`, and `outputFileTracingExcludes`. Closes: NDX-166
1 parent f7b33d5 commit f1786af

File tree

11 files changed

+194
-128
lines changed

11 files changed

+194
-128
lines changed

docs/02-app/02-api-reference/05-next-config-js/output.mdx

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ Additionally, a minimal `server.js` file is also output which can be used instea
4040
> **Good to know**:
4141
>
4242
> - If your project needs to listen to a specific port or hostname, you can define `PORT` or `HOSTNAME` environment variables before running `server.js`. For example, run `PORT=8080 HOSTNAME=0.0.0.0 node server.js` to start the server on `http://0.0.0.0:8080`.
43-
> - If your project uses [Image Optimization](/docs/app/building-your-application/optimizing/images) with the default `loader`, you must install `sharp` as a dependency:
4443
4544
</AppOnly>
4645

@@ -50,54 +49,38 @@ Additionally, a minimal `server.js` file is also output which can be used instea
5049
>
5150
> - `next.config.js` is read during `next build` and serialized into the `server.js` output file. If the legacy [`serverRuntimeConfig` or `publicRuntimeConfig` options](/docs/pages/api-reference/next-config-js/runtime-configuration) are being used, the values will be specific to values at build time.
5251
> - If your project needs to listen to a specific port or hostname, you can define `PORT` or `HOSTNAME` environment variables before running `server.js`. For example, run `PORT=8080 HOSTNAME=0.0.0.0 node server.js` to start the server on `http://0.0.0.0:8080`.
53-
> - If your project uses [Image Optimization](/docs/pages/building-your-application/optimizing/images) with the default `loader`, you must install `sharp` as a dependency:
5452
5553
</PagesOnly>
5654

57-
```bash filename="Terminal"
58-
npm i sharp
59-
```
60-
61-
```bash filename="Terminal"
62-
yarn add sharp
63-
```
64-
65-
```bash filename="Terminal"
66-
pnpm add sharp
67-
```
68-
69-
```bash filename="Terminal"
70-
bun add sharp
71-
```
72-
7355
## Caveats
7456

75-
- While tracing in monorepo setups, the project directory is used for tracing by default. For `next build packages/web-app`, `packages/web-app` would be the tracing root and any files outside of that folder will not be included. To include files outside of this folder you can set `experimental.outputFileTracingRoot` in your `next.config.js`.
57+
- While tracing in monorepo setups, the project directory is used for tracing by default. For `next build packages/web-app`, `packages/web-app` would be the tracing root and any files outside of that folder will not be included. To include files outside of this folder you can set `outputFileTracingRoot` in your `next.config.js`.
7658

7759
```js filename="packages/web-app/next.config.js"
7860
module.exports = {
79-
experimental: {
80-
// this includes files from the monorepo base two directories up
81-
outputFileTracingRoot: path.join(__dirname, '../../'),
82-
},
61+
// this includes files from the monorepo base two directories up
62+
outputFileTracingRoot: path.join(__dirname, '../../'),
8363
}
8464
```
8565

86-
- There are some cases in which Next.js might fail to include required files, or might incorrectly include unused files. In those cases, you can leverage `experimental.outputFileTracingExcludes` and `experimental.outputFileTracingIncludes` respectively in `next.config.js`. Each config accepts an object with [minimatch globs](https://www.npmjs.com/package/minimatch) for the key to match specific pages and a value of an array with globs relative to the project's root to either include or exclude in the trace.
66+
- There are some cases in which Next.js might fail to include required files, or might incorrectly include unused files. In those cases, you can leverage `outputFileTracingExcludes` and `outputFileTracingIncludes` respectively in `next.config.js`. Each config accepts an object with [minimatch globs](https://www.npmjs.com/package/minimatch) for the key to match specific pages and a value of an array with globs relative to the project's root to either include or exclude in the trace.
8767

8868
```js filename="next.config.js"
8969
module.exports = {
90-
experimental: {
91-
outputFileTracingExcludes: {
92-
'/api/hello': ['./un-necessary-folder/**/*'],
93-
},
94-
outputFileTracingIncludes: {
95-
'/api/another': ['./necessary-folder/**/*'],
96-
},
70+
outputFileTracingExcludes: {
71+
'/api/hello': ['./un-necessary-folder/**/*'],
72+
},
73+
outputFileTracingIncludes: {
74+
'/api/another': ['./necessary-folder/**/*'],
75+
'/api/login/\\[\\[\\.\\.\\.slug\\]\\]': [
76+
'./node_modules/aws-crt/dist/bin/**/*',
77+
],
9778
},
9879
}
9980
```
10081

82+
**Note:** The key of `outputFileTracingIncludes`/`outputFileTracingExcludes` is a [glob](https://www.npmjs.com/package/picomatch#basic-globbing), so special characters need to be escaped.
83+
10184
- Currently, Next.js does not do anything with the emitted `.nft.json` files. The files must be read by your deployment platform, for example [Vercel](https://vercel.com), to create a minimal deployment. In a future release, a new command is planned to utilize these `.nft.json` files.
10285

10386
## Experimental `turbotrace`
@@ -127,8 +110,8 @@ module.exports = {
127110
logAll?: boolean
128111
// control the context directory of the turbotrace
129112
// files outside of the context directory will not be traced
130-
// set the `experimental.outputFileTracingRoot` has the same effect
131-
// if the `experimental.outputFileTracingRoot` and this option are both set, the `experimental.turbotrace.contextDirectory` will be used
113+
// set the `outputFileTracingRoot` has the same effect
114+
// if the `outputFileTracingRoot` and this option are both set, the `experimental.turbotrace.contextDirectory` will be used
132115
contextDirectory?: string
133116
// if there is `process.cwd()` expression in your code, you can set this option to tell `turbotrace` the value of `process.cwd()` while tracing.
134117
// for example the require(process.cwd() + '/package.json') will be traced as require('/path/to/cwd/package.json')

packages/next/src/build/collect-build-traces.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ export async function collectBuildTraces({
204204
}
205205

206206
const { outputFileTracingIncludes = {}, outputFileTracingExcludes = {} } =
207-
config.experimental
207+
config
208208
const excludeGlobKeys = Object.keys(outputFileTracingExcludes)
209209
const includeGlobKeys = Object.keys(outputFileTracingIncludes)
210210

@@ -319,7 +319,6 @@ export async function collectBuildTraces({
319319

320320
...(isStandalone ? [] : TRACE_IGNORES),
321321
...additionalIgnores,
322-
...(config.experimental.outputFileTracingIgnores || []),
323322
]
324323

325324
const sharedIgnoresFn = makeIgnoreFn(sharedIgnores)

packages/next/src/build/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,8 +1218,7 @@ export default async function build(
12181218

12191219
await writeEdgePartialPrerenderManifest(distDir, {})
12201220

1221-
const outputFileTracingRoot =
1222-
config.experimental.outputFileTracingRoot || dir
1221+
const outputFileTracingRoot = config.outputFileTracingRoot || dir
12231222

12241223
const pagesManifestPath = path.join(
12251224
distDir,
@@ -1344,7 +1343,7 @@ export default async function build(
13441343
const project = await bindings.turbo.createProject(
13451344
{
13461345
projectPath: dir,
1347-
rootPath: config.experimental.outputFileTracingRoot || dir,
1346+
rootPath: config.outputFileTracingRoot || dir,
13481347
nextConfig: config,
13491348
jsConfig: await getTurbopackJsConfig(dir, config),
13501349
watch: false,

packages/next/src/build/webpack-config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,11 +1793,11 @@ export default async function getBaseWebpackConfig(
17931793
appDir: appDir,
17941794
pagesDir: pagesDir,
17951795
esmExternals: config.experimental.esmExternals,
1796-
outputFileTracingRoot: config.experimental.outputFileTracingRoot,
1796+
outputFileTracingRoot: config.outputFileTracingRoot,
17971797
appDirEnabled: hasAppDir,
17981798
turbotrace: config.experimental.turbotrace,
17991799
optOutBundlingPackages,
1800-
traceIgnores: config.experimental.outputFileTracingIgnores || [],
1800+
traceIgnores: [],
18011801
flyingShuttle: !!config.experimental.flyingShuttle,
18021802
compilerType,
18031803
}

packages/next/src/server/config-schema.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -306,14 +306,6 @@ export const configSchema: zod.ZodType<NextConfig> = z.lazy(() =>
306306
// The critter option is unknown, use z.any() here
307307
optimizeCss: z.union([z.boolean(), z.any()]).optional(),
308308
optimisticClientCache: z.boolean().optional(),
309-
outputFileTracingRoot: z.string().optional(),
310-
outputFileTracingExcludes: z
311-
.record(z.string(), z.array(z.string()))
312-
.optional(),
313-
outputFileTracingIgnores: z.array(z.string()).optional(),
314-
outputFileTracingIncludes: z
315-
.record(z.string(), z.array(z.string()))
316-
.optional(),
317309
parallelServerCompiles: z.boolean().optional(),
318310
parallelServerBuildTraces: z.boolean().optional(),
319311
ppr: z
@@ -560,6 +552,13 @@ export const configSchema: zod.ZodType<NextConfig> = z.lazy(() =>
560552
.optional(),
561553
optimizeFonts: z.boolean().optional(),
562554
output: z.enum(['standalone', 'export']).optional(),
555+
outputFileTracingRoot: z.string().optional(),
556+
outputFileTracingExcludes: z
557+
.record(z.string(), z.array(z.string()))
558+
.optional(),
559+
outputFileTracingIncludes: z
560+
.record(z.string(), z.array(z.string()))
561+
.optional(),
563562
pageExtensions: z.array(z.string()).min(1).optional(),
564563
poweredByHeader: z.boolean().optional(),
565564
productionBrowserSourceMaps: z.boolean().optional(),

packages/next/src/server/config-shared.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,6 @@ export interface ExperimentalConfig {
267267
esmExternals?: boolean | 'loose'
268268
fullySpecified?: boolean
269269
urlImports?: NonNullable<webpack.Configuration['experiments']>['buildHttp']
270-
outputFileTracingRoot?: string
271-
outputFileTracingExcludes?: Record<string, string[]>
272-
outputFileTracingIgnores?: string[]
273-
outputFileTracingIncludes?: Record<string, string[]>
274270
swcTraceProfiling?: boolean
275271
forceSwcTransforms?: boolean
276272

@@ -882,6 +878,24 @@ export interface NextConfig extends Record<string, any> {
882878
* @see https://nextjs.org/docs/app/api-reference/next-config-js/serverExternalPackages
883879
*/
884880
serverExternalPackages?: string[]
881+
882+
/**
883+
* This is the repo root usually and only files above this
884+
* directory are traced and included.
885+
*/
886+
outputFileTracingRoot?: string
887+
888+
/**
889+
* This allows manually excluding traced files if too many
890+
* are included incorrectly on a per-page basis.
891+
*/
892+
outputFileTracingExcludes?: Record<string, string[]>
893+
894+
/**
895+
* This allows manually including traced files if some
896+
* were not detected on a per-page basis.
897+
*/
898+
outputFileTracingIncludes?: Record<string, string[]>
885899
}
886900

887901
export const defaultConfig: NextConfig = {
@@ -939,6 +953,7 @@ export const defaultConfig: NextConfig = {
939953
staticPageGenerationTimeout: 60,
940954
output: !!process.env.NEXT_PRIVATE_STANDALONE ? 'standalone' : undefined,
941955
modularizeImports: undefined,
956+
outputFileTracingRoot: process.env.NEXT_PRIVATE_OUTPUT_TRACE_ROOT || '',
942957
experimental: {
943958
appNavFailHandling: Boolean(process.env.NEXT_PRIVATE_FLYING_SHUTTLE),
944959
flyingShuttle: Boolean(process.env.NEXT_PRIVATE_FLYING_SHUTTLE),
@@ -973,7 +988,6 @@ export const defaultConfig: NextConfig = {
973988
craCompat: false,
974989
esmExternals: true,
975990
fullySpecified: false,
976-
outputFileTracingRoot: process.env.NEXT_PRIVATE_OUTPUT_TRACE_ROOT || '',
977991
swcTraceProfiling: false,
978992
forceSwcTransforms: false,
979993
swcPlugins: undefined,

0 commit comments

Comments
 (0)