This commit is contained in:
Kismet Hasanaj
2026-05-02 20:07:02 +02:00
parent ce8672e283
commit 34dc9aec52
9428 changed files with 1733330 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
<div align="center">
<a href="https://nextjs.org">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://assets.vercel.com/image/upload/v1662130559/nextjs/Icon_dark_background.png">
<img alt="Next.js logo" src="https://assets.vercel.com/image/upload/v1662130559/nextjs/Icon_light_background.png" height="128">
</picture>
</a>
<h1>Next.js</h1>
<a href="https://vercel.com"><img alt="Vercel logo" src="https://img.shields.io/badge/MADE%20BY%20Vercel-000000.svg?style=for-the-badge&logo=Vercel&labelColor=000"></a>
<a href="https://www.npmjs.com/package/next"><img alt="NPM version" src="https://img.shields.io/npm/v/next.svg?style=for-the-badge&labelColor=000000"></a>
<a href="https://github.com/vercel/next.js/blob/canary/license.md"><img alt="License" src="https://img.shields.io/npm/l/next.svg?style=for-the-badge&labelColor=000000"></a>
<a href="https://github.com/vercel/next.js/discussions"><img alt="Join the community on GitHub" src="https://img.shields.io/badge/Join%20the%20community-blueviolet.svg?style=for-the-badge&logo=Next.js&labelColor=000000&logoWidth=20"></a>
</div>
## Getting Started
Used by some of the world's largest companies, Next.js enables you to create full-stack web applications by extending the latest React features, and integrating powerful Rust-based JavaScript tooling for the fastest builds.
- Visit our [Learn Next.js](https://nextjs.org/learn) course to get started with Next.js.
- Visit the [Next.js Showcase](https://nextjs.org/showcase) to see more sites built with Next.js.
## Documentation
Visit [https://nextjs.org/docs](https://nextjs.org/docs) to view the full documentation.
## Community
The Next.js community can be found on [GitHub Discussions](https://github.com/vercel/next.js/discussions) where you can ask questions, voice ideas, and share your projects with other people.
To chat with other community members you can join the Next.js [Discord](https://nextjs.org/discord) server.
Do note that our [Code of Conduct](https://github.com/vercel/next.js/blob/canary/CODE_OF_CONDUCT.md) applies to all Next.js community channels. Users are **highly encouraged** to read and adhere to it to avoid repercussions.
## Contributing
Contributions to Next.js are welcome and highly appreciated. However, before you jump right into it, we would like you to review our [Contribution Guidelines](/contributing.md) to make sure you have a smooth experience contributing to Next.js.
### Good First Issues:
We have a list of **[good first issues](https://github.com/vercel/next.js/labels/good%20first%20issue)** that contain bugs that have a relatively limited scope. This is a great place for newcomers and beginners alike to get started, gain experience, and get familiar with our contribution process.
---
## Security
If you believe you have found a security vulnerability in Next.js, we encourage you to **_responsibly disclose this and NOT open a public issue_**.
To participate in our Open Source Software Bug Bounty program, please email [responsible.disclosure@vercel.com](mailto:responsible.disclosure@vercel.com). We will add you to the program and provide further instructions for submitting your report.
Generated Vendored
+3
View File
@@ -0,0 +1,3 @@
import App from './dist/pages/_app'
export * from './dist/pages/_app'
export default App
Generated Vendored
+1
View File
@@ -0,0 +1 @@
module.exports = require('./dist/pages/_app')
+1
View File
@@ -0,0 +1 @@
export * from './dist/build/babel/preset'
Generated Vendored
+1
View File
@@ -0,0 +1 @@
module.exports = require('./dist/build/babel/preset')
+154
View File
@@ -0,0 +1,154 @@
export { unstable_cache } from 'next/dist/server/web/spec-extension/unstable-cache'
export {
revalidatePath,
revalidateTag,
updateTag,
refresh,
} from 'next/dist/server/web/spec-extension/revalidate'
export { unstable_noStore } from 'next/dist/server/web/spec-extension/unstable-no-store'
import { cacheTag } from 'next/dist/server/use-cache/cache-tag'
export { cacheTag }
/**
* Cache this `"use cache"` for a timespan defined by the `"default"` profile.
* ```
* stale: 300 seconds (5 minutes)
* revalidate: 900 seconds (15 minutes)
* expire: never
* ```
*
* This cache may be stale on clients for 5 minutes before checking with the server.
* If the server receives a new request after 15 minutes, start revalidating new values in the background.
* It lives for the maximum age of the server cache. If this entry has no traffic for a while, it may serve an old value the next request.
*/
export function cacheLife(profile: 'default'): void
/**
* Cache this `"use cache"` for a timespan defined by the `"seconds"` profile.
* ```
* stale: 30 seconds
* revalidate: 1 second
* expire: 1 minute
* ```
*
* This cache may be stale on clients for 30 seconds before checking with the server.
* If the server receives a new request after 1 second, start revalidating new values in the background.
* If this entry has no traffic for 1 minute it will expire. The next request will recompute it.
*/
export function cacheLife(profile: 'seconds'): void
/**
* Cache this `"use cache"` for a timespan defined by the `"minutes"` profile.
* ```
* stale: 300 seconds (5 minutes)
* revalidate: 60 seconds (1 minute)
* expire: 3600 seconds (1 hour)
* ```
*
* This cache may be stale on clients for 5 minutes before checking with the server.
* If the server receives a new request after 1 minute, start revalidating new values in the background.
* If this entry has no traffic for 1 hour it will expire. The next request will recompute it.
*/
export function cacheLife(profile: 'minutes'): void
/**
* Cache this `"use cache"` for a timespan defined by the `"hours"` profile.
* ```
* stale: 300 seconds (5 minutes)
* revalidate: 3600 seconds (1 hour)
* expire: 86400 seconds (1 day)
* ```
*
* This cache may be stale on clients for 5 minutes before checking with the server.
* If the server receives a new request after 1 hour, start revalidating new values in the background.
* If this entry has no traffic for 1 day it will expire. The next request will recompute it.
*/
export function cacheLife(profile: 'hours'): void
/**
* Cache this `"use cache"` for a timespan defined by the `"days"` profile.
* ```
* stale: 300 seconds (5 minutes)
* revalidate: 86400 seconds (1 day)
* expire: 604800 seconds (1 week)
* ```
*
* This cache may be stale on clients for 5 minutes before checking with the server.
* If the server receives a new request after 1 day, start revalidating new values in the background.
* If this entry has no traffic for 1 week it will expire. The next request will recompute it.
*/
export function cacheLife(profile: 'days'): void
/**
* Cache this `"use cache"` for a timespan defined by the `"weeks"` profile.
* ```
* stale: 300 seconds (5 minutes)
* revalidate: 604800 seconds (1 week)
* expire: 2592000 seconds (30 days)
* ```
*
* This cache may be stale on clients for 5 minutes before checking with the server.
* If the server receives a new request after 1 week, start revalidating new values in the background.
* If this entry has no traffic for 30 days it will expire. The next request will recompute it.
*/
export function cacheLife(profile: 'weeks'): void
/**
* Cache this `"use cache"` for a timespan defined by the `"max"` profile.
* ```
* stale: 300 seconds (5 minutes)
* revalidate: 2592000 seconds (30 days)
* expire: never
* ```
*
* This cache may be stale on clients for 5 minutes before checking with the server.
* If the server receives a new request after 30 days, start revalidating new values in the background.
* It lives for the maximum age of the server cache. If this entry has no traffic for a while, it may serve an old value the next request.
*/
export function cacheLife(profile: 'max'): void
/**
* Cache this `"use cache"` using a custom profile "...".
* ```
* stale: ... // seconds
* revalidate: ... // seconds
* expire: ... // seconds
* ```
*
* You can define custom profiles in `next.config.ts`.
*/
export function cacheLife(profile: string): void
/**
* Cache this `"use cache"` using a custom timespan.
* ```
* stale: ... // seconds
* revalidate: ... // seconds
* expire: ... // seconds
* ```
*
* This is similar to Cache-Control: max-age=`stale`,s-max-age=`revalidate`,stale-while-revalidate=`expire-revalidate`
*
* If a value is left out, the lowest of other cacheLife() calls or the default, is used instead.
*/
export function cacheLife(profile: {
/**
* This cache may be stale on clients for ... seconds before checking with the server.
*/
stale?: number
/**
* If the server receives a new request after ... seconds, start revalidating new values in the background.
*/
revalidate?: number
/**
* If this entry has no traffic for ... seconds it will expire. The next request will recompute it.
*/
expire?: number
}): void
export const unstable_cacheLife: typeof cacheLife
export const unstable_cacheTag: typeof cacheTag
Generated Vendored
+94
View File
@@ -0,0 +1,94 @@
let cacheExports
if (process.env.NEXT_RUNTIME === '') {
const notAvailableInClient = (name) => {
return function notAvailable() {
throw new Error(`\`${name}\` is only available in a Server Component.`)
}
}
cacheExports = {
unstable_cache: function unstable_cache(cb) {
// Legacy behavior: allow importing/using unstable_cache from client bundles
// without pulling in server internals.
if (typeof cb !== 'function') return cb
return function cached() {
return cb.apply(this, arguments)
}
},
unstable_noStore: function unstable_noStore() {},
updateTag: notAvailableInClient('updateTag'),
revalidateTag: notAvailableInClient('revalidateTag'),
revalidatePath: notAvailableInClient('revalidatePath'),
refresh: notAvailableInClient('refresh'),
cacheLife: notAvailableInClient('cacheLife'),
cacheTag: notAvailableInClient('cacheTag'),
}
} else {
// Keep server requires in this branch so browser builds can DCE them.
cacheExports = {
unstable_cache:
require('next/dist/server/web/spec-extension/unstable-cache')
.unstable_cache,
updateTag: require('next/dist/server/web/spec-extension/revalidate')
.updateTag,
revalidateTag: require('next/dist/server/web/spec-extension/revalidate')
.revalidateTag,
revalidatePath: require('next/dist/server/web/spec-extension/revalidate')
.revalidatePath,
refresh: require('next/dist/server/web/spec-extension/revalidate').refresh,
unstable_noStore:
require('next/dist/server/web/spec-extension/unstable-no-store')
.unstable_noStore,
cacheLife: require('next/dist/server/use-cache/cache-life').cacheLife,
cacheTag: require('next/dist/server/use-cache/cache-tag').cacheTag,
}
}
let didWarnCacheLife = false
function unstable_cacheLife() {
if (!didWarnCacheLife) {
didWarnCacheLife = true
const error = new Error(
'`unstable_cacheLife` was recently stabilized and should be imported as `cacheLife`. The `unstable` prefixed form will be removed in a future version of Next.js.'
)
console.error(error)
}
return cacheExports.cacheLife.apply(this, arguments)
}
let didWarnCacheTag = false
function unstable_cacheTag() {
if (!didWarnCacheTag) {
didWarnCacheTag = true
const error = new Error(
'`unstable_cacheTag` was recently stabilized and should be imported as `cacheTag`. The `unstable` prefixed form will be removed in a future version of Next.js.'
)
console.error(error)
}
return cacheExports.cacheTag.apply(this, arguments)
}
cacheExports.unstable_cacheLife = unstable_cacheLife
cacheExports.unstable_cacheTag = unstable_cacheTag
// https://nodejs.org/api/esm.html#commonjs-namespaces
// When importing CommonJS modules, the module.exports object is provided as the default export
module.exports = cacheExports
// make import { xxx } from 'next/cache' work
exports.unstable_cache = cacheExports.unstable_cache
exports.revalidatePath = cacheExports.revalidatePath
exports.revalidateTag = cacheExports.revalidateTag
exports.updateTag = cacheExports.updateTag
exports.unstable_noStore = cacheExports.unstable_noStore
exports.cacheLife = cacheExports.cacheLife
exports.unstable_cacheLife = cacheExports.unstable_cacheLife
exports.cacheTag = cacheExports.cacheTag
exports.unstable_cacheTag = cacheExports.unstable_cacheTag
exports.refresh = cacheExports.refresh
+1
View File
@@ -0,0 +1 @@
export * from './dist/client/index'
+1
View File
@@ -0,0 +1 @@
module.exports = require('./dist/client/index')
+1
View File
@@ -0,0 +1 @@
export * from '../dist/client/compat/router'
+1
View File
@@ -0,0 +1 @@
module.exports = require('../dist/client/compat/router')
+1
View File
@@ -0,0 +1 @@
export * from './dist/shared/lib/constants'
+1
View File
@@ -0,0 +1 @@
module.exports = require('./dist/shared/lib/constants')
+1
View File
@@ -0,0 +1 @@
c5c94dffbf084e66b172a9c6ff23d80c24973764
+2
View File
@@ -0,0 +1,2 @@
export * from '../shared/lib/app-dynamic';
export { default } from '../shared/lib/app-dynamic';
+4
View File
@@ -0,0 +1,4 @@
export * from '../shared/lib/app-dynamic';
export { default } from '../shared/lib/app-dynamic';
//# sourceMappingURL=app-dynamic.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/app-dynamic.ts"],"sourcesContent":["export * from '../shared/lib/app-dynamic'\nexport { default } from '../shared/lib/app-dynamic'\n"],"names":["default"],"mappings":"AAAA,cAAc,4BAA2B;AACzC,SAASA,OAAO,QAAQ,4BAA2B","ignoreList":[0]}
+2
View File
@@ -0,0 +1,2 @@
export * from '../pages/_app';
export { default } from '../pages/_app';
+4
View File
@@ -0,0 +1,4 @@
export * from '../pages/_app';
export { default } from '../pages/_app';
//# sourceMappingURL=app.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/app.tsx"],"sourcesContent":["export * from '../pages/_app'\nexport { default } from '../pages/_app'\n"],"names":["default"],"mappings":"AAAA,cAAc,gBAAe;AAC7B,SAASA,OAAO,QAAQ,gBAAe","ignoreList":[0]}
+1
View File
@@ -0,0 +1 @@
export * from '../shared/lib/constants';
+3
View File
@@ -0,0 +1,3 @@
export * from '../shared/lib/constants';
//# sourceMappingURL=constants.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/constants.ts"],"sourcesContent":["export * from '../shared/lib/constants'\n"],"names":[],"mappings":"AAAA,cAAc,0BAAyB","ignoreList":[0]}
+2
View File
@@ -0,0 +1,2 @@
export * from '../pages/_document';
export { default } from '../pages/_document';
+4
View File
@@ -0,0 +1,4 @@
export * from '../pages/_document';
export { default } from '../pages/_document';
//# sourceMappingURL=document.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/document.tsx"],"sourcesContent":["export * from '../pages/_document'\nexport { default } from '../pages/_document'\n"],"names":["default"],"mappings":"AAAA,cAAc,qBAAoB;AAClC,SAASA,OAAO,QAAQ,qBAAoB","ignoreList":[0]}
+2
View File
@@ -0,0 +1,2 @@
export { default } from '../shared/lib/dynamic';
export * from '../shared/lib/dynamic';
+4
View File
@@ -0,0 +1,4 @@
export { default } from '../shared/lib/dynamic';
export * from '../shared/lib/dynamic';
//# sourceMappingURL=dynamic.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/dynamic.ts"],"sourcesContent":["export { default } from '../shared/lib/dynamic'\nexport * from '../shared/lib/dynamic'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,wBAAuB;AAC/C,cAAc,wBAAuB","ignoreList":[0]}
+4
View File
@@ -0,0 +1,4 @@
export { default } from '../pages/_error';
export * from '../pages/_error';
export { unstable_catchError } from '../client/components/catch-error';
export type { ErrorInfo } from '../client/components/error-boundary';
+6
View File
@@ -0,0 +1,6 @@
// Pages Router only
export { default } from '../pages/_error';
export * from '../pages/_error';
export { unstable_catchError } from '../client/components/catch-error';
//# sourceMappingURL=error.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/error.ts"],"sourcesContent":["// Pages Router only\nexport { default } from '../pages/_error'\nexport * from '../pages/_error'\n\nexport { unstable_catchError } from '../client/components/catch-error'\nexport type { ErrorInfo } from '../client/components/error-boundary'\n"],"names":["default","unstable_catchError"],"mappings":"AAAA,oBAAoB;AACpB,SAASA,OAAO,QAAQ,kBAAiB;AACzC,cAAc,kBAAiB;AAE/B,SAASC,mBAAmB,QAAQ,mCAAkC","ignoreList":[0]}
+2
View File
@@ -0,0 +1,2 @@
export declare function unstable_catchError(): never;
export type { ErrorInfo } from '../client/components/error-boundary';
+9
View File
@@ -0,0 +1,9 @@
export function unstable_catchError() {
throw Object.defineProperty(new Error('`unstable_catchError` can only be used in Client Components.'), "__NEXT_ERROR_CODE", {
value: "E1139",
enumerable: false,
configurable: true
});
}
//# sourceMappingURL=error.react-server.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/error.react-server.ts"],"sourcesContent":["export function unstable_catchError(): never {\n throw new Error(\n '`unstable_catchError` can only be used in Client Components.'\n )\n}\n\nexport type { ErrorInfo } from '../client/components/error-boundary'\n"],"names":["unstable_catchError","Error"],"mappings":"AAAA,OAAO,SAASA;IACd,MAAM,qBAEL,CAFK,IAAIC,MACR,iEADI,qBAAA;eAAA;oBAAA;sBAAA;IAEN;AACF","ignoreList":[0]}
+2
View File
@@ -0,0 +1,2 @@
export { default } from '../client/form';
export * from '../client/form';
+4
View File
@@ -0,0 +1,4 @@
export { default } from '../client/form';
export * from '../client/form';
//# sourceMappingURL=form.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/form.ts"],"sourcesContent":["export { default } from '../client/form'\nexport * from '../client/form'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,iBAAgB;AACxC,cAAc,iBAAgB","ignoreList":[0]}
+2
View File
@@ -0,0 +1,2 @@
export { default } from '../shared/lib/head';
export * from '../shared/lib/head';
+4
View File
@@ -0,0 +1,4 @@
export { default } from '../shared/lib/head';
export * from '../shared/lib/head';
//# sourceMappingURL=head.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/head.ts"],"sourcesContent":["export { default } from '../shared/lib/head'\nexport * from '../shared/lib/head'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,qBAAoB;AAC5C,cAAc,qBAAoB","ignoreList":[0]}
+3
View File
@@ -0,0 +1,3 @@
export * from '../server/request/cookies';
export * from '../server/request/headers';
export * from '../server/request/draft-mode';
+5
View File
@@ -0,0 +1,5 @@
export * from '../server/request/cookies';
export * from '../server/request/headers';
export * from '../server/request/draft-mode';
//# sourceMappingURL=headers.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/headers.ts"],"sourcesContent":["export * from '../server/request/cookies'\nexport * from '../server/request/headers'\nexport * from '../server/request/draft-mode'\n"],"names":[],"mappings":"AAAA,cAAc,4BAA2B;AACzC,cAAc,4BAA2B;AACzC,cAAc,+BAA8B","ignoreList":[0]}
+2
View File
@@ -0,0 +1,2 @@
export { default } from '../shared/lib/image-external';
export * from '../shared/lib/image-external';
+4
View File
@@ -0,0 +1,4 @@
export { default } from '../shared/lib/image-external';
export * from '../shared/lib/image-external';
//# sourceMappingURL=image.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/image.ts"],"sourcesContent":["export { default } from '../shared/lib/image-external'\nexport * from '../shared/lib/image-external'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,+BAA8B;AACtD,cAAc,+BAA8B","ignoreList":[0]}
+2
View File
@@ -0,0 +1,2 @@
export { default } from '../client/link';
export * from '../client/link';
+4
View File
@@ -0,0 +1,4 @@
export { default } from '../client/link';
export * from '../client/link';
//# sourceMappingURL=link.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/link.ts"],"sourcesContent":["export { default } from '../client/link'\nexport * from '../client/link'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,iBAAgB;AACxC,cAAc,iBAAgB","ignoreList":[0]}
+1
View File
@@ -0,0 +1 @@
export * from '../client/components/navigation';
+3
View File
@@ -0,0 +1,3 @@
export * from '../client/components/navigation';
//# sourceMappingURL=navigation.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/navigation.ts"],"sourcesContent":["export * from '../client/components/navigation'\n"],"names":[],"mappings":"AAAA,cAAc,kCAAiC","ignoreList":[0]}
+1
View File
@@ -0,0 +1 @@
export * from '../client/components/navigation.react-server';
+3
View File
@@ -0,0 +1,3 @@
export * from '../client/components/navigation.react-server';
//# sourceMappingURL=navigation.react-server.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/navigation.react-server.ts"],"sourcesContent":["export * from '../client/components/navigation.react-server'\n"],"names":[],"mappings":"AAAA,cAAc,+CAA8C","ignoreList":[0]}
+1
View File
@@ -0,0 +1 @@
export * from '../server/og/image-response';
+3
View File
@@ -0,0 +1,3 @@
export * from '../server/og/image-response';
//# sourceMappingURL=og.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/og.ts"],"sourcesContent":["export * from '../server/og/image-response'\n"],"names":[],"mappings":"AAAA,cAAc,8BAA6B","ignoreList":[0]}
+2
View File
@@ -0,0 +1,2 @@
export { default } from '../client/router';
export * from '../client/router';
+4
View File
@@ -0,0 +1,4 @@
export { default } from '../client/router';
export * from '../client/router';
//# sourceMappingURL=router.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/router.ts"],"sourcesContent":["export { default } from '../client/router'\nexport * from '../client/router'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,mBAAkB;AAC1C,cAAc,mBAAkB","ignoreList":[0]}
+2
View File
@@ -0,0 +1,2 @@
export { default } from '../client/script';
export * from '../client/script';
+4
View File
@@ -0,0 +1,4 @@
export { default } from '../client/script';
export * from '../client/script';
//# sourceMappingURL=script.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/script.ts"],"sourcesContent":["export { default } from '../client/script'\nexport * from '../client/script'\n"],"names":["default"],"mappings":"AAAA,SAASA,OAAO,QAAQ,mBAAkB;AAC1C,cAAc,mBAAkB","ignoreList":[0]}
+1
View File
@@ -0,0 +1 @@
export * from '../server/web/exports/index';
+3
View File
@@ -0,0 +1,3 @@
export * from '../server/web/exports/index';
//# sourceMappingURL=server.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/api/server.ts"],"sourcesContent":["export * from '../server/web/exports/index'\n"],"names":[],"mappings":"AAAA,cAAc,8BAA6B","ignoreList":[0]}
Generated Vendored Executable
+185
View File
@@ -0,0 +1,185 @@
#!/usr/bin/env node
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
require("../server/require-hook");
const _commander = require("next/dist/compiled/commander");
const _log = require("../build/output/log");
const _semver = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/semver"));
const _picocolors = require("../lib/picocolors");
const _formatclihelpoutput = require("../lib/format-cli-help-output");
const _constants = require("../lib/constants");
const _utils = require("../server/lib/utils");
const _nexttest = require("../cli/next-test.js");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
if (process.env.NEXT_RSPACK) {
// silent rspack's schema check
process.env.RSPACK_CONFIG_VALIDATE = 'loose-silent';
}
if (!_semver.default.satisfies(process.versions.node, ">=20.9.0", {
includePrerelease: true
})) {
console.error(`You are using Node.js ${process.versions.node}. For Next.js, Node.js version "${">=20.9.0"}" is required.`);
process.exit(1);
}
process.env.NEXT_PRIVATE_START_TIME = Date.now().toString();
for (const dependency of [
'react',
'react-dom'
]){
try {
// When 'npm link' is used it checks the clone location. Not the project.
require.resolve(dependency);
} catch (err) {
console.warn(`The module '${dependency}' was not found. Next.js requires that you include it in 'dependencies' of your 'package.json'. To add it, run 'npm install ${dependency}'`);
}
}
class NextRootCommand extends _commander.Command {
createCommand(name) {
const command = new _commander.Command(name);
command.hook('preAction', (event)=>{
const commandName = event.name();
const defaultEnv = commandName === 'dev' ? 'development' : 'production';
const standardEnv = [
'production',
'development',
'test'
];
if (process.env.NODE_ENV) {
const isNotStandard = !standardEnv.includes(process.env.NODE_ENV);
const shouldWarnCommands = process.env.NODE_ENV === 'development' ? [
'start',
'build'
] : process.env.NODE_ENV === 'production' ? [
'dev'
] : [];
if (isNotStandard || shouldWarnCommands.includes(commandName)) {
(0, _log.warn)(_constants.NON_STANDARD_NODE_ENV);
}
}
;
process.env.NODE_ENV = process.env.NODE_ENV || defaultEnv;
process.env.NEXT_RUNTIME = 'nodejs';
if (commandName !== 'dev' && commandName !== 'start' && event.getOptionValue('inspect') === true) {
console.error(`\`--inspect\` flag is deprecated. Use env variable NODE_OPTIONS instead: NODE_OPTIONS='--inspect' next ${commandName}`);
process.exit(1);
}
});
return command;
}
}
function parseValidInspectAddress(value) {
const address = (0, _utils.getParsedDebugAddress)(value);
if (Number.isNaN(address.port)) {
throw new _commander.InvalidArgumentError('The given value is not a valid inspect address. ' + 'Did you mean to pass an app path?\n' + `Try switching the order of the arguments or set the default address explicitly e.g.\n` + `next dev ${value} --inspect\n` + `next dev --inspect= ${value}`);
}
return address;
}
const program = new NextRootCommand();
program.name('next').description('The Next.js CLI allows you to develop, build, start your application, and more.').configureHelp({
formatHelp: (cmd, helper)=>(0, _formatclihelpoutput.formatCliHelpOutput)(cmd, helper),
subcommandTerm: (cmd)=>`${cmd.name()} ${cmd.usage()}`
}).helpCommand(false).helpOption('-h, --help', 'Displays this message.').version(`Next.js v${"16.2.0"}`, '-v, --version', 'Outputs the Next.js version.');
program.command('build').description('Creates an optimized production build of your application. The output displays information about each route.').argument('[directory]', `A directory on which to build the application. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).option('--experimental-analyze', 'Analyze bundle output. Only compatible with Turbopack.').option('-d, --debug', 'Enables a more verbose build output.').option('--debug-prerender', 'Enables debug mode for prerendering. Not for production use!').option('--no-mangling', 'Disables mangling.').option('--profile', 'Enables production profiling for React.').option('--experimental-app-only', 'Builds only App Router routes.').option('--turbo', 'Builds using Turbopack.').option('--turbopack', 'Builds using Turbopack.').option('--webpack', 'Builds using webpack.').addOption(new _commander.Option('--experimental-build-mode [mode]', 'Uses an experimental build mode.').choices([
'compile',
'generate',
'generate-env'
]).default('default')).option('--experimental-debug-memory-usage', 'Enables memory profiling features to debug memory consumption.').option('--experimental-upload-trace, <traceUrl>', 'Reports a subset of the debugging trace to a remote HTTP URL. Includes sensitive data.').option('--experimental-next-config-strip-types', 'Use Node.js native TypeScript resolution for next.config.(ts|mts)').option('--debug-build-paths <patterns>', 'Comma-separated glob patterns or explicit paths for selective builds. Use "!" prefix to exclude. Examples: "app/*", "app/page.tsx", "app/**/page.tsx", "app/**,!app/[slug]/**"').option('--experimental-cpu-prof', 'Enable CPU profiling. Profile is saved to .next/cpu-profiles/ on completion.').action((directory, options)=>{
if (options.debugPrerender) {
// @ts-expect-error not readonly
process.env.NODE_ENV = 'development';
}
if (options.experimentalNextConfigStripTypes) {
process.env.__NEXT_NODE_NATIVE_TS_LOADER_ENABLED = 'true';
}
if (options.experimentalCpuProf) {
process.env.NEXT_CPU_PROF = '1';
process.env.__NEXT_PRIVATE_CPU_PROFILE = 'build-main';
const { join } = require('path');
const dir = directory || process.cwd();
process.env.NEXT_CPU_PROF_DIR = join(dir, '.next', 'cpu-profiles');
}
// ensure process exits after build completes so open handles/connections
// don't cause process to hang
return import('../cli/next-build.js').then((mod)=>mod.nextBuild(options, directory).then(async ()=>{
// Save CPU profile before exiting if enabled
if (options.experimentalCpuProf) {
await mod.saveCpuProfile();
}
process.exit(0);
}));
}).usage('[directory] [options]');
program.command('experimental-analyze').description('Analyze production bundle output with an interactive web ui. Does not produce an application build. Only compatible with Turbopack.').argument('[directory]', `A directory on which to analyze the application. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).option('--no-mangling', 'Disables mangling.').option('--profile', 'Enables production profiling for React.').option('-o, --output', 'Only write analysis files to disk. Does not start the server.').addOption(new _commander.Option('--port <port>', 'Specify a port number to serve the analyzer on.').implies({
serve: true
}).argParser(_utils.parseValidPositiveInteger).default(4000).env('PORT')).action((directory, options)=>{
return import('../cli/next-analyze.js').then((mod)=>mod.nextAnalyze(options, directory)).then(()=>{
if (options.output) {
// The Next.js process is held open by something on the event loop. Exit manually like the `build` command does.
// TODO: Fix the underlying issue so this is not necessary.
process.exit(0);
}
});
});
program.command('dev', {
isDefault: true
}).description('Starts Next.js in development mode with hot-code reloading, error reporting, and more.').argument('[directory]', `A directory on which to build the application. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).addOption(new _commander.Option('--inspect [[host:]port]', 'Allows inspecting server-side code. See https://nextjs.org/docs/app/guides/debugging#server-side-code').argParser(parseValidInspectAddress)).option('--turbo', 'Starts development mode using Turbopack.').option('--turbopack', 'Starts development mode using Turbopack.').option('--webpack', 'Starts development mode using webpack.').addOption(new _commander.Option('-p, --port <port>', 'Specify a port number on which to start the application.').argParser(_utils.parseValidPositiveInteger).default(3000).env('PORT')).option('-H, --hostname <hostname>', 'Specify a hostname on which to start the application (default: 0.0.0.0).').option('--disable-source-maps', "Don't start the Dev server with `--enable-source-maps`.", false).option('--experimental-https', 'Starts the server with HTTPS and generates a self-signed certificate.').option('--experimental-https-key, <path>', 'Path to a HTTPS key file.').option('--experimental-https-cert, <path>', 'Path to a HTTPS certificate file.').option('--experimental-https-ca, <path>', 'Path to a HTTPS certificate authority file.').option('--no-server-fast-refresh', 'Disable server-side Fast Refresh').option('--experimental-upload-trace, <traceUrl>', 'Reports a subset of the debugging trace to a remote HTTP URL. Includes sensitive data.').option('--experimental-next-config-strip-types', 'Use Node.js native TypeScript resolution for next.config.(ts|mts)').option('--experimental-cpu-prof', 'Enable CPU profiling. Profiles are saved to .next/cpu-profiles/ on exit.').action((directory, options, { _optionValueSources })=>{
if (options.experimentalNextConfigStripTypes) {
process.env.__NEXT_NODE_NATIVE_TS_LOADER_ENABLED = 'true';
}
if (options.experimentalCpuProf) {
process.env.NEXT_CPU_PROF = '1';
process.env.__NEXT_PRIVATE_CPU_PROFILE = 'dev-main';
const { join } = require('path');
const dir = directory || process.cwd();
process.env.NEXT_CPU_PROF_DIR = join(dir, '.next', 'cpu-profiles');
}
const portSource = _optionValueSources.port;
import('../cli/next-dev.js').then((mod)=>mod.nextDev(options, portSource, directory));
}).usage('[directory] [options]');
program.command('export', {
hidden: true
}).action(()=>import('../cli/next-export.js').then((mod)=>mod.nextExport())).helpOption(false);
program.command('info').description('Prints relevant details about the current system which can be used to report Next.js bugs.').addHelpText('after', `\nLearn more: ${(0, _picocolors.cyan)('https://nextjs.org/docs/api-reference/cli#info')}`).option('--verbose', 'Collects additional information for debugging.').action((options)=>import('../cli/next-info.js').then((mod)=>mod.nextInfo(options)));
program.command('start').description('Starts Next.js in production mode. The application should be compiled with `next build` first.').argument('[directory]', `A directory on which to start the application. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).addOption(new _commander.Option('-p, --port <port>', 'Specify a port number on which to start the application.').argParser(_utils.parseValidPositiveInteger).default(3000).env('PORT')).option('-H, --hostname <hostname>', 'Specify a hostname on which to start the application (default: 0.0.0.0).').addOption(new _commander.Option('--inspect [[host:]port]', 'Allows inspecting server-side code. See https://nextjs.org/docs/app/guides/debugging#server-side-code').argParser(parseValidInspectAddress)).addOption(new _commander.Option('--keepAliveTimeout <keepAliveTimeout>', 'Specify the maximum amount of milliseconds to wait before closing inactive connections.').argParser(_utils.parseValidPositiveInteger)).option('--experimental-next-config-strip-types', 'Use Node.js native TypeScript resolution for next.config.(ts|mts)').option('--experimental-cpu-prof', 'Enable CPU profiling. Profiles are saved to .next/cpu-profiles/ on exit.').action((directory, options)=>{
if (options.experimentalNextConfigStripTypes) {
process.env.__NEXT_NODE_NATIVE_TS_LOADER_ENABLED = 'true';
}
if (options.experimentalCpuProf) {
process.env.NEXT_CPU_PROF = '1';
process.env.__NEXT_PRIVATE_CPU_PROFILE = 'start-main';
const { join } = require('path');
const dir = directory || process.cwd();
process.env.NEXT_CPU_PROF_DIR = join(dir, '.next', 'cpu-profiles');
}
return import('../cli/next-start.js').then((mod)=>mod.nextStart(options, directory));
}).usage('[directory] [options]');
program.command('telemetry').description(`Allows you to enable or disable Next.js' ${(0, _picocolors.bold)('completely anonymous')} telemetry collection.`).addArgument(new _commander.Argument('[arg]').choices([
'disable',
'enable',
'status'
])).addHelpText('after', `\nLearn more: ${(0, _picocolors.cyan)('https://nextjs.org/telemetry')}`).addOption(new _commander.Option('--enable', `Enables Next.js' telemetry collection.`).conflicts('disable')).option('--disable', `Disables Next.js' telemetry collection.`).action((arg, options)=>import('../cli/next-telemetry.js').then((mod)=>mod.nextTelemetry(options, arg)));
program.command('typegen').description('Generate TypeScript definitions for routes, pages, and layouts without running a full build.').argument('[directory]', `A directory on which to generate types. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).action((directory, options)=>// ensure process exits after typegen completes so open handles/connections
// don't cause process to hang
import('../cli/next-typegen.js').then((mod)=>mod.nextTypegen(options, directory).then(()=>process.exit(0)))).usage('[directory] [options]');
const nextVersion = "16.2.0" || 'unknown';
program.command('upgrade').description('Upgrade Next.js apps to desired versions with a single command.').argument('[directory]', `A Next.js project directory to upgrade. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).usage('[directory] [options]').option('--revision <revision>', 'Specify the target Next.js version using an NPM dist tag (e.g. "latest", "canary", "rc", "beta") or an exact version number (e.g. "15.0.0").', nextVersion.includes('-canary.') ? 'canary' : nextVersion.includes('-rc.') ? 'rc' : nextVersion.includes('-beta.') ? 'beta' : 'latest').option('--verbose', 'Verbose output', false).action(async (directory, options)=>{
const mod = await import('../cli/next-upgrade.js');
mod.spawnNextUpgrade(directory, options);
});
program.command('experimental-test').description(`Execute \`next/experimental/testmode\` tests using a specified test runner. The test runner defaults to 'playwright' if the \`experimental.defaultTestRunner\` configuration option or the \`--test-runner\` option are not set.`).argument('[directory]', `A Next.js project directory to execute the test runner on. ${(0, _picocolors.italic)('If no directory is provided, the current directory will be used.')}`).argument('[test-runner-args...]', 'Any additional arguments or options to pass down to the test runner `test` command.').option('--test-runner [test-runner]', `Any supported test runner. Options: ${(0, _picocolors.bold)(_nexttest.SUPPORTED_TEST_RUNNERS_LIST.join(', '))}. ${(0, _picocolors.italic)("If no test runner is provided, the Next.js config option `experimental.defaultTestRunner`, or 'playwright' will be used.")}`).allowUnknownOption().action((directory, testRunnerArgs, options)=>{
return import('../cli/next-test.js').then((mod)=>{
mod.nextTest(directory, testRunnerArgs, options);
});
}).usage('[directory] [options]');
const internal = program.command('internal').description('Internal debugging commands. Use with caution. Not covered by semver.');
internal.command('trace').alias('turbo-trace-server').argument('file', 'Trace file to serve.').addOption(new _commander.Option('-p, --port <port>', 'Override the port.').argParser(_utils.parseValidPositiveInteger)).action((file, options)=>{
return import('../cli/internal/turbo-trace-server.js').then((mod)=>mod.startTurboTraceServerCli(file, options.port));
});
program.parse(process.argv);
//# sourceMappingURL=next.map
+2
View File
@@ -0,0 +1,2 @@
#!/usr/bin/env node
import '../server/require-hook';
Generated Vendored Executable
+1
View File
File diff suppressed because one or more lines are too long
+349
View File
@@ -0,0 +1,349 @@
import { RenderingMode } from '../rendering-mode';
import type { RouteHas } from '../../lib/load-custom-routes';
import type { Revalidate } from '../../server/lib/cache-control';
import type { NextConfigComplete } from '../../server/config-shared';
import { AdapterOutputType, type PHASE_TYPE } from '../../shared/lib/constants';
import type { MiddlewareManifest } from '../webpack/plugins/middleware-plugin';
import type { RoutesManifest, PrerenderManifest, FunctionsConfigManifest, DynamicPrerenderManifestRoute } from '..';
import { Bundler } from '../../lib/bundler';
interface SharedRouteFields {
/**
* id is the unique identifier of the output
*/
id: string;
/**
* filePath is the location on disk of the built entrypoint asset
*/
filePath: string;
/**
* pathname is the URL pathname the asset should be served at
*/
pathname: string;
/**
* sourcePage is the original source in the app or pages folder
*/
sourcePage: string;
/**
* runtime is which runtime the entrypoint is built for
*/
runtime: 'nodejs' | 'edge';
/**
* assets are all necessary traced assets that could be
* loaded by the output to handle a request e.g. traced
* node_modules or necessary manifests for Next.js.
* The key is the relative path from the repo root and the value
* is the absolute path to the file
*/
assets: Record<string, string>;
/**
* wasmAssets are bundled wasm files with mapping of name
* to filePath on disk
*/
wasmAssets?: Record<string, string>;
/**
* edgeRuntime contains canonical entry metadata for invoking
* this output in an edge runtime.
*/
edgeRuntime?: {
/**
* modulePath is the canonical module path that registers this
* output in the edge runtime.
*/
modulePath: string;
/**
* entryKey is the canonical key used for the global edge entry registry.
*/
entryKey: string;
/**
* handlerExport is the export name to invoke on the edge entry.
*/
handlerExport: string;
};
/**
* config related to the route
*/
config: {
/**
* maxDuration is a segment config to signal the max
* execution duration a route should be allowed before
* it's timed out
*/
maxDuration?: number;
/**
* preferredRegion is a segment config to signal deployment
* region preferences to the provider being used
*/
preferredRegion?: string | string[];
/**
* env is the environment variables to expose, this is only
* populated for edge runtime currently
*/
env?: Record<string, string>;
};
}
export interface AdapterOutput {
/**
* `PAGES` represents all the React pages that are under `pages/`.
*/
PAGES: SharedRouteFields & {
type: AdapterOutputType.PAGES;
};
/**
* `PAGES_API` represents all the API routes under `pages/api/`.
*/
PAGES_API: SharedRouteFields & {
type: AdapterOutputType.PAGES_API;
};
/**
* `APP_PAGE` represents all the React pages that are under `app/` with the
* filename of `page.{j,t}s{,x}`.
*/
APP_PAGE: SharedRouteFields & {
type: AdapterOutputType.APP_PAGE;
};
/**
* `APP_ROUTE` represents all the API routes and metadata routes that are under `app/` with the
* filename of `route.{j,t}s{,x}`.
*/
APP_ROUTE: SharedRouteFields & {
type: AdapterOutputType.APP_ROUTE;
};
/**
* `PRERENDER` represents an ISR enabled route that might
* have a seeded cache entry or fallback generated during build
*/
PRERENDER: {
id: string;
pathname: string;
type: AdapterOutputType.PRERENDER;
/**
* For prerenders the parent output is the originating
* page that the prerender is created from
*/
parentOutputId: string;
/**
* groupId is the identifier for a group of prerenders that should be
* revalidated together
*/
groupId: number;
pprChain?: {
headers: Record<string, string>;
};
/**
* parentFallbackMode signals whether additional routes can be generated
* e.g. fallback: false or 'blocking' in getStaticPaths in pages router
*/
parentFallbackMode?: DynamicPrerenderManifestRoute['fallback'];
/**
* fallback is initial cache data generated during build for a prerender
*/
fallback?: {
/**
* path to the fallback file can be HTML/JSON/RSC,
*/
filePath: string | undefined;
/**
* initialStatus is the status code that should be applied
* when serving the fallback
*/
initialStatus?: number;
/**
* initialHeaders are the headers that should be sent when
* serving the fallback
*/
initialHeaders?: Record<string, string | string[]>;
/**
* initial expiration is how long until the fallback entry
* is considered expired and no longer valid to serve
*/
initialExpiration?: number;
/**
* initial revalidate is how long until the fallback is
* considered stale and should be revalidated
*/
initialRevalidate?: Revalidate;
/**
* postponedState is the PPR state when it postponed and is used for resuming
*/
postponedState: string | undefined;
};
/**
* config related to the route
*/
config: {
/**
* allowQuery is the allowed query values to be passed
* to an ISR function and what should be considered for the cacheKey
* e.g. for /blog/[slug], "slug" is the only allowQuery
*/
allowQuery?: string[];
/**
* allowHeader is the allowed headers to be passed to an
* ISR function to prevent accidentally poisoning the cache
* from leaking additional information that can impact the render
*/
allowHeader?: string[];
/**
* bypass for is a list of has conditions the cache
* should be bypassed and invoked directly e.g. action header
*/
bypassFor?: RouteHas[];
/**
* renderingMode signals PPR or not for a prerender
*/
renderingMode?: RenderingMode;
/**
* partialFallback signals this prerender serves a partial fallback shell
* and should be upgraded to a full route in the background.
*/
partialFallback?: boolean;
/**
* bypassToken is the generated token that signals a prerender cache
* should be bypassed
*/
bypassToken?: string;
};
};
/**
* `STATIC_FILE` represents a static file (ie /_next/static) or a purely
* static HTML asset e.g. an automatically statically optimized page
* that does not use ISR
*/
STATIC_FILE: {
id: string;
filePath: string;
pathname: string;
type: AdapterOutputType.STATIC_FILE;
/**
* If this static file is immutable (because its filename contains a content hash), then this
* field contains the untruncated content hash.
*/
immutableHash: string | undefined;
};
/**
* `MIDDLEWARE` represents the middleware output if present
*/
MIDDLEWARE: SharedRouteFields & {
type: AdapterOutputType.MIDDLEWARE;
/**
* config related to the route
*/
config: SharedRouteFields['config'] & {
/**
* matchers are the configured matchers for middleware
*/
matchers?: Array<{
source: string;
sourceRegex: string;
has: RouteHas[] | undefined;
missing: RouteHas[] | undefined;
}>;
};
};
}
export interface AdapterOutputs {
pages: Array<AdapterOutput['PAGES']>;
middleware?: AdapterOutput['MIDDLEWARE'];
appPages: Array<AdapterOutput['APP_PAGE']>;
pagesApi: Array<AdapterOutput['PAGES_API']>;
appRoutes: Array<AdapterOutput['APP_ROUTE']>;
prerenders: Array<AdapterOutput['PRERENDER']>;
staticFiles: Array<AdapterOutput['STATIC_FILE']>;
}
type Route = {
source?: string;
sourceRegex: string;
destination?: string;
headers?: Record<string, string>;
has?: RouteHas[];
missing?: RouteHas[];
status?: number;
priority?: boolean;
};
export interface NextAdapter {
name: string;
/**
* modifyConfig is called for any CLI command that loads the next.config
* to only apply for specific commands the "phase" should be used
* @param config
* @param ctx
* @returns
*/
modifyConfig?: (config: NextConfigComplete, ctx: {
phase: PHASE_TYPE;
/**
* nextVersion is the current version of Next.js being used
*/
nextVersion: string;
}) => Promise<NextConfigComplete> | NextConfigComplete;
onBuildComplete?: (ctx: {
routing: {
beforeMiddleware: Array<Route>;
beforeFiles: Array<Route>;
afterFiles: Array<Route>;
dynamicRoutes: Array<Route>;
onMatch: Array<Route>;
fallback: Array<Route>;
/**
* shouldNormalizeNextData indicates whether Next.js data URLs
* (e.g., /_next/data/BUILD_ID/page.json) should be normalized
* during route resolution. This is true when middleware is present
* and there are pages router items to resolve.
*/
shouldNormalizeNextData: boolean;
rsc: RoutesManifest['rsc'];
};
outputs: AdapterOutputs;
/**
* projectDir is the absolute directory the Next.js application is in
*/
projectDir: string;
/**
* repoRoot is the absolute path of the detected root of the repo
*/
repoRoot: string;
/**
* distDir is the absolute path to the dist directory
*/
distDir: string;
/**
* config is the loaded next.config (has modifyConfig applied)
*/
config: NextConfigComplete;
/**
* nextVersion is the current version of Next.js being used
*/
nextVersion: string;
/**
* buildId is the current unique ID for the build, this can be
* influenced by NextConfig.generateBuildId
*/
buildId: string;
}) => Promise<void> | void;
}
export declare function handleBuildComplete({ dir, config, appType, buildId, configOutDir, distDir, pageKeys, bundler, tracingRoot, adapterPath, appPageKeys, staticPages, nextVersion, hasStatic404, hasStatic500, routesManifest, serverPropsPages, hasNodeMiddleware, prerenderManifest, middlewareManifest, requiredServerFiles, hasInstrumentationHook, functionsConfigManifest, }: {
dir: string;
appType: 'app' | 'pages' | 'hybrid';
distDir: string;
buildId: string;
configOutDir: string;
adapterPath: string;
tracingRoot: string;
nextVersion: string;
hasStatic404: boolean;
hasStatic500: boolean;
bundler: Bundler;
staticPages: Set<string>;
hasNodeMiddleware: boolean;
config: NextConfigComplete;
pageKeys: readonly string[];
serverPropsPages: Set<string>;
requiredServerFiles: string[];
routesManifest: RoutesManifest;
hasInstrumentationHook: boolean;
prerenderManifest: PrerenderManifest;
middlewareManifest: MiddlewareManifest;
appPageKeys?: readonly string[] | undefined;
functionsConfigManifest: FunctionsConfigManifest;
}): Promise<void>;
export {};
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+15
View File
@@ -0,0 +1,15 @@
// This is a minimal import that initializes the node
// environment, it is traced automatically for entries
// and can be used to ensure Node.js APIs are setup
// as expected without require `next-server`
"use strict";
if (process.env.NEXT_RUNTIME !== 'edge') {
// eslint-disable-next-line @next/internal/typechecked-require
require('next/dist/server/node-environment');
// eslint-disable-next-line @next/internal/typechecked-require
require('next/dist/server/require-hook');
// eslint-disable-next-line @next/internal/typechecked-require
require('next/dist/server/node-polyfill-crypto');
}
//# sourceMappingURL=setup-node-env.external.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/build/adapter/setup-node-env.external.ts"],"sourcesContent":["// This is a minimal import that initializes the node\n// environment, it is traced automatically for entries\n// and can be used to ensure Node.js APIs are setup\n// as expected without require `next-server`\nif (process.env.NEXT_RUNTIME !== 'edge') {\n // eslint-disable-next-line @next/internal/typechecked-require\n require('next/dist/server/node-environment')\n // eslint-disable-next-line @next/internal/typechecked-require\n require('next/dist/server/require-hook')\n // eslint-disable-next-line @next/internal/typechecked-require\n require('next/dist/server/node-polyfill-crypto')\n}\n"],"names":["process","env","NEXT_RUNTIME","require"],"mappings":"AAAA,qDAAqD;AACrD,sDAAsD;AACtD,mDAAmD;AACnD,4CAA4C;;AAC5C,IAAIA,QAAQC,GAAG,CAACC,YAAY,KAAK,QAAQ;IACvC,8DAA8D;IAC9DC,QAAQ;IACR,8DAA8D;IAC9DA,QAAQ;IACR,8DAA8D;IAC9DA,QAAQ;AACV","ignoreList":[0]}
+12
View File
@@ -0,0 +1,12 @@
import type { NextConfigComplete } from '../server/config-shared';
import type { Span } from '../trace';
import type { Telemetry } from '../telemetry/storage';
export declare function runAfterProductionCompile({ config, buildSpan, telemetry, metadata, }: {
config: NextConfigComplete;
buildSpan: Span;
telemetry: Telemetry;
metadata: {
projectDir: string;
distDir: string;
};
}): Promise<void>;
+96
View File
@@ -0,0 +1,96 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "runAfterProductionCompile", {
enumerable: true,
get: function() {
return runAfterProductionCompile;
}
});
const _log = /*#__PURE__*/ _interop_require_wildcard(require("./output/log"));
const _spinner = /*#__PURE__*/ _interop_require_default(require("./spinner"));
const _iserror = /*#__PURE__*/ _interop_require_default(require("../lib/is-error"));
const _build = require("../telemetry/events/build");
const _durationtostring = require("./duration-to-string");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
async function runAfterProductionCompile({ config, buildSpan, telemetry, metadata }) {
const run = config.compiler.runAfterProductionCompile;
if (!run) {
return;
}
telemetry.record([
{
eventName: _build.EVENT_BUILD_FEATURE_USAGE,
payload: {
featureName: 'runAfterProductionCompile',
invocationCount: 1
}
}
]);
const afterBuildSpinner = (0, _spinner.default)('Running next.config.js provided runAfterProductionCompile');
try {
const startTime = process.hrtime.bigint();
await buildSpan.traceChild('after-production-compile').traceAsyncFn(async ()=>{
await run(metadata);
});
const duration = process.hrtime.bigint() - startTime;
const formattedDuration = (0, _durationtostring.hrtimeBigIntDurationToString)(duration);
_log.event(`Completed runAfterProductionCompile in ${formattedDuration}`);
} catch (err) {
// Handle specific known errors differently if needed
if ((0, _iserror.default)(err)) {
_log.error(`Failed to run runAfterProductionCompile: ${err.message}`);
}
throw err;
} finally{
afterBuildSpinner == null ? void 0 : afterBuildSpinner.stop();
}
}
//# sourceMappingURL=after-production-compile.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../src/build/after-production-compile.ts"],"sourcesContent":["import type { NextConfigComplete } from '../server/config-shared'\nimport type { Span } from '../trace'\n\nimport * as Log from './output/log'\nimport createSpinner from './spinner'\nimport isError from '../lib/is-error'\nimport type { Telemetry } from '../telemetry/storage'\nimport { EVENT_BUILD_FEATURE_USAGE } from '../telemetry/events/build'\nimport { hrtimeBigIntDurationToString } from './duration-to-string'\n\n// TODO: refactor this to account for more compiler lifecycle events\n// such as beforeProductionBuild, but for now this is the only one that is needed\nexport async function runAfterProductionCompile({\n config,\n buildSpan,\n telemetry,\n metadata,\n}: {\n config: NextConfigComplete\n buildSpan: Span\n telemetry: Telemetry\n metadata: {\n projectDir: string\n distDir: string\n }\n}): Promise<void> {\n const run = config.compiler.runAfterProductionCompile\n if (!run) {\n return\n }\n telemetry.record([\n {\n eventName: EVENT_BUILD_FEATURE_USAGE,\n payload: {\n featureName: 'runAfterProductionCompile',\n invocationCount: 1,\n },\n },\n ])\n const afterBuildSpinner = createSpinner(\n 'Running next.config.js provided runAfterProductionCompile'\n )\n\n try {\n const startTime = process.hrtime.bigint()\n await buildSpan\n .traceChild('after-production-compile')\n .traceAsyncFn(async () => {\n await run(metadata)\n })\n const duration = process.hrtime.bigint() - startTime\n const formattedDuration = hrtimeBigIntDurationToString(duration)\n Log.event(`Completed runAfterProductionCompile in ${formattedDuration}`)\n } catch (err) {\n // Handle specific known errors differently if needed\n if (isError(err)) {\n Log.error(`Failed to run runAfterProductionCompile: ${err.message}`)\n }\n\n throw err\n } finally {\n afterBuildSpinner?.stop()\n }\n}\n"],"names":["runAfterProductionCompile","config","buildSpan","telemetry","metadata","run","compiler","record","eventName","EVENT_BUILD_FEATURE_USAGE","payload","featureName","invocationCount","afterBuildSpinner","createSpinner","startTime","process","hrtime","bigint","traceChild","traceAsyncFn","duration","formattedDuration","hrtimeBigIntDurationToString","Log","event","err","isError","error","message","stop"],"mappings":";;;;+BAYsBA;;;eAAAA;;;6DATD;gEACK;gEACN;uBAEsB;kCACG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAItC,eAAeA,0BAA0B,EAC9CC,MAAM,EACNC,SAAS,EACTC,SAAS,EACTC,QAAQ,EAST;IACC,MAAMC,MAAMJ,OAAOK,QAAQ,CAACN,yBAAyB;IACrD,IAAI,CAACK,KAAK;QACR;IACF;IACAF,UAAUI,MAAM,CAAC;QACf;YACEC,WAAWC,gCAAyB;YACpCC,SAAS;gBACPC,aAAa;gBACbC,iBAAiB;YACnB;QACF;KACD;IACD,MAAMC,oBAAoBC,IAAAA,gBAAa,EACrC;IAGF,IAAI;QACF,MAAMC,YAAYC,QAAQC,MAAM,CAACC,MAAM;QACvC,MAAMhB,UACHiB,UAAU,CAAC,4BACXC,YAAY,CAAC;YACZ,MAAMf,IAAID;QACZ;QACF,MAAMiB,WAAWL,QAAQC,MAAM,CAACC,MAAM,KAAKH;QAC3C,MAAMO,oBAAoBC,IAAAA,8CAA4B,EAACF;QACvDG,KAAIC,KAAK,CAAC,CAAC,uCAAuC,EAAEH,mBAAmB;IACzE,EAAE,OAAOI,KAAK;QACZ,qDAAqD;QACrD,IAAIC,IAAAA,gBAAO,EAACD,MAAM;YAChBF,KAAII,KAAK,CAAC,CAAC,yCAAyC,EAAEF,IAAIG,OAAO,EAAE;QACrE;QAEA,MAAMH;IACR,SAAU;QACRb,qCAAAA,kBAAmBiB,IAAI;IACzB;AACF","ignoreList":[0]}
+23
View File
@@ -0,0 +1,23 @@
import type { Module } from '@swc/core';
export type ExtractValueResult = {
value: any;
} | {
unsupported: string;
path?: string;
};
/**
* Extracts the value of an exported const variable named `exportedName`
* (e.g. "export const config = { runtime: 'edge' }") from swc's AST.
* The value must be one of (or returns unsupported):
* - string
* - boolean
* - number
* - null
* - undefined
* - array containing values listed in this list
* - object containing values listed in this list
*
* Returns null if the declaration is not found.
* Returns { unsupported, path? } if the value contains unsupported nodes.
*/
export declare function extractExportedConstValue(module: Module | null, exportedName: string): ExtractValueResult | null;
+220
View File
@@ -0,0 +1,220 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "extractExportedConstValue", {
enumerable: true,
get: function() {
return extractExportedConstValue;
}
});
function isExportDeclaration(node) {
return node.type === 'ExportDeclaration';
}
function isVariableDeclaration(node) {
return node.type === 'VariableDeclaration';
}
function isIdentifier(node) {
return node.type === 'Identifier';
}
function isBooleanLiteral(node) {
return node.type === 'BooleanLiteral';
}
function isNullLiteral(node) {
return node.type === 'NullLiteral';
}
function isStringLiteral(node) {
return node.type === 'StringLiteral';
}
function isNumericLiteral(node) {
return node.type === 'NumericLiteral';
}
function isArrayExpression(node) {
return node.type === 'ArrayExpression';
}
function isObjectExpression(node) {
return node.type === 'ObjectExpression';
}
function isKeyValueProperty(node) {
return node.type === 'KeyValueProperty';
}
function isRegExpLiteral(node) {
return node.type === 'RegExpLiteral';
}
function isTemplateLiteral(node) {
return node.type === 'TemplateLiteral';
}
function isTsSatisfiesExpression(node) {
return node.type === 'TsSatisfiesExpression';
}
/** Formats a path array like `["config", "runtime", "[0]", "value"]` → `"config.runtime[0].value"` */ function formatCodePath(paths) {
if (!paths) return undefined;
let codePath = '';
for (const path of paths){
if (path[0] === '[') {
// "array" + "[0]"
codePath += path;
} else if (codePath === '') {
codePath = path;
} else {
// "object" + ".key"
codePath += `.${path}`;
}
}
return codePath;
}
function extractValue(node, path) {
if (isNullLiteral(node)) {
return {
value: null
};
} else if (isBooleanLiteral(node)) {
// e.g. true / false
return {
value: node.value
};
} else if (isStringLiteral(node)) {
// e.g. "abc"
return {
value: node.value
};
} else if (isNumericLiteral(node)) {
// e.g. 123
return {
value: node.value
};
} else if (isRegExpLiteral(node)) {
// e.g. /abc/i
return {
value: new RegExp(node.pattern, node.flags)
};
} else if (isIdentifier(node)) {
switch(node.value){
case 'undefined':
return {
value: undefined
};
default:
return {
unsupported: `Unknown identifier "${node.value}"`,
path: formatCodePath(path)
};
}
} else if (isArrayExpression(node)) {
// e.g. [1, 2, 3]
const arr = [];
for(let i = 0, len = node.elements.length; i < len; i++){
const elem = node.elements[i];
if (elem) {
if (elem.spread) {
// e.g. [ ...a ]
return {
unsupported: 'Unsupported spread operator in the Array Expression',
path: formatCodePath(path)
};
}
const result = extractValue(elem.expression, path && [
...path,
`[${i}]`
]);
if ('unsupported' in result) return result;
arr.push(result.value);
} else {
// e.g. [1, , 2]
// ^^
arr.push(undefined);
}
}
return {
value: arr
};
} else if (isObjectExpression(node)) {
// e.g. { a: 1, b: 2 }
const obj = {};
for (const prop of node.properties){
if (!isKeyValueProperty(prop)) {
// e.g. { ...a }
return {
unsupported: 'Unsupported spread operator in the Object Expression',
path: formatCodePath(path)
};
}
let key;
if (isIdentifier(prop.key)) {
// e.g. { a: 1, b: 2 }
key = prop.key.value;
} else if (isStringLiteral(prop.key)) {
// e.g. { "a": 1, "b": 2 }
key = prop.key.value;
} else {
return {
unsupported: `Unsupported key type "${prop.key.type}" in the Object Expression`,
path: formatCodePath(path)
};
}
const result = extractValue(prop.value, path && [
...path,
key
]);
if ('unsupported' in result) return result;
obj[key] = result.value;
}
return {
value: obj
};
} else if (isTemplateLiteral(node)) {
// e.g. `abc`
if (node.expressions.length !== 0) {
// TODO: should we add support for `${'e'}d${'g'}'e'`?
return {
unsupported: 'Unsupported template literal with expressions',
path: formatCodePath(path)
};
}
// When TemplateLiteral has 0 expressions, the length of quasis is always 1.
// Because when parsing TemplateLiteral, the parser yields the first quasi,
// then the first expression, then the next quasi, then the next expression, etc.,
// until the last quasi.
// Thus if there is no expression, the parser ends at the frst and also last quasis
//
// A "cooked" interpretation where backslashes have special meaning, while a
// "raw" interpretation where backslashes do not have special meaning
// https://exploringjs.com/impatient-js/ch_template-literals.html#template-strings-cooked-vs-raw
const [{ cooked, raw }] = node.quasis;
return {
value: cooked ?? raw
};
} else if (isTsSatisfiesExpression(node)) {
return extractValue(node.expression);
} else {
return {
unsupported: `Unsupported node type "${node.type}"`,
path: formatCodePath(path)
};
}
}
function extractExportedConstValue(module, exportedName) {
if (!module) return null;
for (const moduleItem of module.body){
if (!isExportDeclaration(moduleItem)) {
continue;
}
const declaration = moduleItem.declaration;
if (!isVariableDeclaration(declaration)) {
continue;
}
if (declaration.kind !== 'const') {
continue;
}
for (const decl of declaration.declarations){
if (isIdentifier(decl.id) && decl.id.value === exportedName && decl.init) {
return extractValue(decl.init, [
exportedName
]);
}
}
}
return null;
}
//# sourceMappingURL=extract-const-value.js.map
File diff suppressed because one or more lines are too long
+82
View File
@@ -0,0 +1,82 @@
import type { NextConfig } from '../../server/config-shared';
import type { RouteHas } from '../../lib/load-custom-routes';
import type { RSCMeta } from '../webpack/loaders/get-module-build-info';
import { PAGE_TYPES } from '../../lib/page-types';
import { type AppSegmentConfig } from '../segment-config/app/app-segment-config';
import { type PagesSegmentConfig, type PagesSegmentConfigConfig } from '../segment-config/pages/pages-segment-config';
export type ProxyMatcher = {
regexp: string;
locale?: false;
has?: RouteHas[];
missing?: RouteHas[];
originalSource: string;
};
export type ProxyConfig = {
/**
* The matcher for the proxy. Read more: [Next.js Docs: Proxy `matcher`](https://nextjs.org/docs/app/api-reference/file-conventions/proxy#matcher),
* [Next.js Docs: Proxy matching paths](https://nextjs.org/docs/app/building-your-application/routing/proxy#matching-paths)
*/
matchers?: ProxyMatcher[];
/**
* The regions that the proxy should run in.
*/
regions?: string | string[];
/**
* A glob, or an array of globs, ignoring dynamic code evaluation for specific
* files. The globs are relative to your application root folder.
*/
unstable_allowDynamic?: string[];
};
export interface AppPageStaticInfo {
type: PAGE_TYPES.APP;
ssg?: boolean;
ssr?: boolean;
rsc?: RSCModuleType;
generateStaticParams?: boolean;
generateSitemaps?: boolean;
generateImageMetadata?: boolean;
middleware?: ProxyConfig;
config: Omit<AppSegmentConfig, 'runtime' | 'maxDuration'> | undefined;
runtime: AppSegmentConfig['runtime'] | undefined;
preferredRegion: AppSegmentConfig['preferredRegion'] | undefined;
maxDuration: number | undefined;
hadUnsupportedValue: boolean;
}
export interface PagesPageStaticInfo {
type: PAGE_TYPES.PAGES;
getStaticProps?: boolean;
getServerSideProps?: boolean;
rsc?: RSCModuleType;
generateStaticParams?: boolean;
generateSitemaps?: boolean;
generateImageMetadata?: boolean;
middleware?: ProxyConfig;
config: (Omit<PagesSegmentConfig, 'runtime' | 'config' | 'maxDuration'> & {
config?: Omit<PagesSegmentConfigConfig, 'runtime' | 'maxDuration'>;
}) | undefined;
runtime: PagesSegmentConfig['runtime'] | undefined;
preferredRegion: PagesSegmentConfigConfig['regions'] | undefined;
maxDuration: number | undefined;
hadUnsupportedValue: boolean;
}
export type PageStaticInfo = AppPageStaticInfo | PagesPageStaticInfo;
export type RSCModuleType = 'server' | 'client';
export declare function getRSCModuleInformation(source: string, isReactServerLayer: boolean): RSCMeta;
type GetPageStaticInfoParams = {
pageFilePath: string;
nextConfig: Partial<NextConfig>;
isDev: boolean;
page: string;
pageType: PAGE_TYPES;
};
export declare function getAppPageStaticInfo({ pageFilePath, nextConfig, isDev, page, }: GetPageStaticInfoParams): Promise<AppPageStaticInfo>;
export declare function getPagesPageStaticInfo({ pageFilePath, nextConfig, isDev, page, }: GetPageStaticInfoParams): Promise<PagesPageStaticInfo>;
/**
* For a given pageFilePath and nextConfig, if the config supports it, this
* function will read the file and return the runtime that should be used.
* It will look into the file content only if the page *requires* a runtime
* to be specified, that is, when gSSP or gSP is used.
* Related discussion: https://github.com/vercel/next.js/discussions/34179
*/
export declare function getPageStaticInfo(params: GetPageStaticInfoParams): Promise<PageStaticInfo>;
export {};
+625
View File
@@ -0,0 +1,625 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
0 && (module.exports = {
getAppPageStaticInfo: null,
getMiddlewareMatchers: null,
getPageStaticInfo: null,
getPagesPageStaticInfo: null,
getRSCModuleInformation: null
});
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
getAppPageStaticInfo: function() {
return getAppPageStaticInfo;
},
getMiddlewareMatchers: function() {
return getMiddlewareMatchers;
},
getPageStaticInfo: function() {
return getPageStaticInfo;
},
getPagesPageStaticInfo: function() {
return getPagesPageStaticInfo;
},
getRSCModuleInformation: function() {
return getRSCModuleInformation;
}
});
const _fs = require("fs");
const _path = require("path");
const _lrucache = require("../../server/lib/lru-cache");
const _extractconstvalue = require("./extract-const-value");
const _parsemodule = require("./parse-module");
const _log = /*#__PURE__*/ _interop_require_wildcard(require("../output/log"));
const _constants = require("../../lib/constants");
const _trytoparsepath = require("../../lib/try-to-parse-path");
const _isapiroute = require("../../lib/is-api-route");
const _isedgeruntime = require("../../lib/is-edge-runtime");
const _constants1 = require("../../shared/lib/constants");
const _pagetypes = require("../../lib/page-types");
const _appsegmentconfig = require("../segment-config/app/app-segment-config");
const _zod = require("../../shared/lib/zod");
const _pagessegmentconfig = require("../segment-config/pages/pages-segment-config");
const _middlewareconfig = require("../segment-config/middleware/middleware-config");
const _apppaths = require("../../shared/lib/router/utils/app-paths");
const _normalizepagepath = require("../../shared/lib/page-path/normalize-page-path");
const _utils = require("../utils");
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
const PARSE_PATTERN = /(?<!(_jsx|jsx-))runtime|preferredRegion|getStaticProps|getServerSideProps|generateStaticParams|export const|generateImageMetadata|generateSitemaps|middleware|proxy/;
const CLIENT_MODULE_LABEL = /\/\* __next_internal_client_entry_do_not_use__ ([^ ]*) (cjs|auto) \*\//;
// Match JSON object that may contain nested objects (for loc info)
// The JSON ends right before the closing " */"
const ACTION_MODULE_LABEL = /\/\* __next_internal_action_entry_do_not_use__ (\{.*\}) \*\//;
const CLIENT_DIRECTIVE = 'use client';
const SERVER_ACTION_DIRECTIVE = 'use server';
function getRSCModuleInformation(source, isReactServerLayer) {
const actionsJson = source.match(ACTION_MODULE_LABEL);
// Parse action metadata - supports both old format (string) and new format (object with loc)
const parsedActionsMeta = actionsJson ? JSON.parse(actionsJson[1]) : undefined;
const clientInfoMatch = source.match(CLIENT_MODULE_LABEL);
const isClientRef = !!clientInfoMatch;
if (!isReactServerLayer) {
return {
type: _constants1.RSC_MODULE_TYPES.client,
actionIds: parsedActionsMeta,
isClientRef
};
}
const clientRefsString = clientInfoMatch == null ? void 0 : clientInfoMatch[1];
const clientRefs = clientRefsString ? clientRefsString.split(',') : [];
const clientEntryType = clientInfoMatch == null ? void 0 : clientInfoMatch[2];
const type = clientInfoMatch ? _constants1.RSC_MODULE_TYPES.client : _constants1.RSC_MODULE_TYPES.server;
return {
type,
actionIds: parsedActionsMeta,
clientRefs,
clientEntryType,
isClientRef
};
}
/**
* Receives a parsed AST from SWC and checks if it belongs to a module that
* requires a runtime to be specified. Those are:
* - Modules with `export function getStaticProps | getServerSideProps`
* - Modules with `export { getStaticProps | getServerSideProps } <from ...>`
* - Modules with `export const runtime = ...`
*/ function checkExports(ast, expectedExports, page) {
const exportsSet = new Set([
'getStaticProps',
'getServerSideProps',
'generateImageMetadata',
'generateSitemaps',
'generateStaticParams'
]);
if (!Array.isArray(ast == null ? void 0 : ast.body)) {
return {};
}
try {
let getStaticProps = false;
let getServerSideProps = false;
let generateImageMetadata = false;
let generateSitemaps = false;
let generateStaticParams = false;
let exports1 = new Set();
let directives = new Set();
let hasLeadingNonDirectiveNode = false;
for (const node of ast.body){
var _node_declaration, _node_declaration1, _node_declaration_identifier, _node_declaration2;
// There should be no non-string literals nodes before directives
if (node.type === 'ExpressionStatement' && node.expression.type === 'StringLiteral') {
if (!hasLeadingNonDirectiveNode) {
const directive = node.expression.value;
if (CLIENT_DIRECTIVE === directive) {
directives.add('client');
}
if (SERVER_ACTION_DIRECTIVE === directive) {
directives.add('server');
}
}
} else {
hasLeadingNonDirectiveNode = true;
}
if (node.type === 'ExportDeclaration' && ((_node_declaration = node.declaration) == null ? void 0 : _node_declaration.type) === 'VariableDeclaration') {
var _node_declaration3;
for (const declaration of (_node_declaration3 = node.declaration) == null ? void 0 : _node_declaration3.declarations){
if (expectedExports.includes(declaration.id.value)) {
exports1.add(declaration.id.value);
}
}
}
if (node.type === 'ExportDeclaration' && ((_node_declaration1 = node.declaration) == null ? void 0 : _node_declaration1.type) === 'FunctionDeclaration' && exportsSet.has((_node_declaration_identifier = node.declaration.identifier) == null ? void 0 : _node_declaration_identifier.value)) {
const id = node.declaration.identifier.value;
getServerSideProps = id === 'getServerSideProps';
getStaticProps = id === 'getStaticProps';
generateImageMetadata = id === 'generateImageMetadata';
generateSitemaps = id === 'generateSitemaps';
generateStaticParams = id === 'generateStaticParams';
}
if (node.type === 'ExportDeclaration' && ((_node_declaration2 = node.declaration) == null ? void 0 : _node_declaration2.type) === 'VariableDeclaration') {
var _node_declaration_declarations_, _node_declaration4;
const id = (_node_declaration4 = node.declaration) == null ? void 0 : (_node_declaration_declarations_ = _node_declaration4.declarations[0]) == null ? void 0 : _node_declaration_declarations_.id.value;
if (exportsSet.has(id)) {
getServerSideProps = id === 'getServerSideProps';
getStaticProps = id === 'getStaticProps';
generateImageMetadata = id === 'generateImageMetadata';
generateSitemaps = id === 'generateSitemaps';
generateStaticParams = id === 'generateStaticParams';
}
}
if (node.type === 'ExportNamedDeclaration') {
for (const specifier of node.specifiers){
var _specifier_orig;
if (specifier.type === 'ExportSpecifier' && ((_specifier_orig = specifier.orig) == null ? void 0 : _specifier_orig.type) === 'Identifier') {
const value = specifier.orig.value;
if (!getServerSideProps && value === 'getServerSideProps') {
getServerSideProps = true;
}
if (!getStaticProps && value === 'getStaticProps') {
getStaticProps = true;
}
if (!generateImageMetadata && value === 'generateImageMetadata') {
generateImageMetadata = true;
}
if (!generateSitemaps && value === 'generateSitemaps') {
generateSitemaps = true;
}
if (!generateStaticParams && value === 'generateStaticParams') {
generateStaticParams = true;
}
if (expectedExports.includes(value) && !exports1.has(value)) {
// An export was found that was actually a re-export, and not a
// literal value. We should warn here.
_log.warn(`Next.js can't recognize the exported \`${value}\` field in "${page}", it may be re-exported from another file. The default config will be used instead.`);
}
}
}
}
}
return {
getStaticProps,
getServerSideProps,
generateImageMetadata,
generateSitemaps,
generateStaticParams,
directives,
exports: exports1
};
} catch {}
return {};
}
function validateMiddlewareProxyExports({ ast, page, pageFilePath, isDev }) {
// Check if this is middleware/proxy
const isMiddleware = page === `/${_constants.MIDDLEWARE_FILENAME}` || page === `/src/${_constants.MIDDLEWARE_FILENAME}`;
const isProxy = page === `/${_constants.PROXY_FILENAME}` || page === `/src/${_constants.PROXY_FILENAME}`;
if (!isMiddleware && !isProxy) {
return;
}
if (!ast || !Array.isArray(ast.body)) {
return;
}
const fileName = isProxy ? _constants.PROXY_FILENAME : _constants.MIDDLEWARE_FILENAME;
// Parse AST to get export info (since checkExports doesn't return middleware/proxy info)
let hasDefaultExport = false;
let hasMiddlewareExport = false;
let hasProxyExport = false;
for (const node of ast.body){
var _node_declaration, _node_declaration1;
if (node.type === 'ExportDefaultDeclaration' || node.type === 'ExportDefaultExpression') {
hasDefaultExport = true;
}
if (node.type === 'ExportDeclaration' && ((_node_declaration = node.declaration) == null ? void 0 : _node_declaration.type) === 'FunctionDeclaration') {
var _node_declaration_identifier;
const id = (_node_declaration_identifier = node.declaration.identifier) == null ? void 0 : _node_declaration_identifier.value;
if (id === 'middleware') {
hasMiddlewareExport = true;
}
if (id === 'proxy') {
hasProxyExport = true;
}
}
if (node.type === 'ExportDeclaration' && ((_node_declaration1 = node.declaration) == null ? void 0 : _node_declaration1.type) === 'VariableDeclaration') {
var _node_declaration_declarations_, _node_declaration2;
const id = (_node_declaration2 = node.declaration) == null ? void 0 : (_node_declaration_declarations_ = _node_declaration2.declarations[0]) == null ? void 0 : _node_declaration_declarations_.id.value;
if (id === 'middleware') {
hasMiddlewareExport = true;
}
if (id === 'proxy') {
hasProxyExport = true;
}
}
if (node.type === 'ExportNamedDeclaration') {
for (const specifier of node.specifiers){
var _specifier_orig;
if (specifier.type === 'ExportSpecifier' && ((_specifier_orig = specifier.orig) == null ? void 0 : _specifier_orig.type) === 'Identifier') {
// Use the exported name if it exists (for aliased exports like `export { foo as proxy }`),
// otherwise fall back to the original name (for simple re-exports like `export { proxy }`)
const exportedIdentifier = specifier.exported || specifier.orig;
const value = exportedIdentifier.value;
if (value === 'middleware') {
hasMiddlewareExport = true;
}
if (value === 'proxy') {
hasProxyExport = true;
}
}
}
}
}
const hasValidExport = hasDefaultExport || isMiddleware && hasMiddlewareExport || isProxy && hasProxyExport;
const relativePath = (0, _path.relative)(process.cwd(), pageFilePath);
const resolvedPath = relativePath.startsWith('.') ? relativePath : `./${relativePath}`;
if (!hasValidExport) {
const message = `The file "${resolvedPath}" must export a function, either as a default export or as a named "${fileName}" export.\n` + `This function is what Next.js runs for every request handled by this ${fileName === 'proxy' ? 'proxy (previously called middleware)' : 'middleware'}.\n\n` + `Why this happens:\n` + (isProxy ? "- You are migrating from `middleware` to `proxy`, but haven't updated the exported function.\n" : '') + `- The file exists but doesn't export a function.\n` + `- The export is not a function (e.g., an object or constant).\n` + `- There's a syntax error preventing the export from being recognized.\n\n` + `To fix it:\n` + `- Ensure this file has either a default or "${fileName}" function export.\n\n` + `Learn more: https://nextjs.org/docs/messages/middleware-to-proxy`;
if (isDev) {
// errorOnce as proxy/middleware runs per request including multiple
// internal _next/ routes and spams logs.
_log.errorOnce(message);
} else {
throw Object.defineProperty(new Error(message), "__NEXT_ERROR_CODE", {
value: "E903",
enumerable: false,
configurable: true
});
}
}
}
function tryToReadFile(filePath, shouldThrow) {
try {
return (0, _fs.readFileSync)(filePath, {
encoding: 'utf8'
});
} catch (error) {
if (shouldThrow) {
error.message = `Next.js ERROR: Failed to read file ${filePath}:\n${error.message}`;
throw error;
}
}
}
function getMiddlewareMatchers(matcherOrMatchers, nextConfig) {
const matchers = Array.isArray(matcherOrMatchers) ? matcherOrMatchers : [
matcherOrMatchers
];
const { i18n } = nextConfig;
return matchers.map((matcher)=>{
matcher = typeof matcher === 'string' ? {
source: matcher
} : matcher;
const originalSource = matcher.source;
let { source, ...rest } = matcher;
const isRoot = source === '/';
if ((i18n == null ? void 0 : i18n.locales) && matcher.locale !== false) {
source = `/:nextInternalLocale((?!_next/)[^/.]{1,})${isRoot ? '' : source}`;
}
source = `/:nextData(_next/data/[^/]{1,})?${source}${isRoot ? `(${nextConfig.i18n ? '|\\.json|' : ''}/?index|/?index\\.json)?` : '{(\\.json)}?'}`;
if (nextConfig.basePath) {
source = `${nextConfig.basePath}${source}`;
}
// Validate that the source is still.
const result = _middlewareconfig.SourceSchema.safeParse(source);
if (!result.success) {
(0, _zod.reportZodError)('Failed to parse middleware source', result.error);
// We need to exit here because middleware being built occurs before we
// finish setting up the server. Exiting here is the only way to ensure
// that we don't hang.
process.exit(1);
}
return {
...rest,
// We know that parsed.regexStr is not undefined because we already
// checked that the source is valid.
regexp: (0, _trytoparsepath.tryToParsePath)(result.data).regexStr,
originalSource: originalSource || source
};
});
}
function parseMiddlewareConfig(page, rawConfig, nextConfig) {
// If there's no config to parse, then return nothing.
if (typeof rawConfig !== 'object' || !rawConfig) return {};
const input = _middlewareconfig.MiddlewareConfigInputSchema.safeParse(rawConfig);
if (!input.success) {
(0, _zod.reportZodError)(`${page} contains invalid middleware config`, input.error);
// We need to exit here because middleware being built occurs before we
// finish setting up the server. Exiting here is the only way to ensure
// that we don't hang.
process.exit(1);
}
const config = {};
if (input.data.matcher) {
config.matchers = getMiddlewareMatchers(input.data.matcher, nextConfig);
}
if (input.data.unstable_allowDynamic) {
config.unstable_allowDynamic = Array.isArray(input.data.unstable_allowDynamic) ? input.data.unstable_allowDynamic : [
input.data.unstable_allowDynamic
];
}
if (input.data.regions) {
config.regions = input.data.regions;
}
return config;
}
const apiRouteWarnings = new _lrucache.LRUCache(250);
function warnAboutExperimentalEdge(apiRoute) {
if (process.env.NODE_ENV === 'production' && process.env.NEXT_PRIVATE_BUILD_WORKER === '1') {
return;
}
if (apiRoute && apiRouteWarnings.has(apiRoute)) {
return;
}
_log.warn(apiRoute ? `${apiRoute} provided runtime 'experimental-edge'. It can be updated to 'edge' instead.` : `You are using an experimental edge runtime, the API might change.`);
if (apiRoute) {
apiRouteWarnings.set(apiRoute, 1);
}
}
let hadUnsupportedValue = false;
const warnedUnsupportedValueMap = new _lrucache.LRUCache(250, ()=>1);
function warnAboutUnsupportedValue(pageFilePath, page, result) {
hadUnsupportedValue = true;
const isProductionBuild = process.env.NODE_ENV === 'production';
if (// we only log for the server compilation so it's not
// duplicated due to webpack build worker having fresh
// module scope for each compiler
process.env.NEXT_COMPILER_NAME !== 'server' || isProductionBuild && warnedUnsupportedValueMap.has(pageFilePath)) {
return;
}
warnedUnsupportedValueMap.set(pageFilePath, true);
const message = `Next.js can't recognize the exported \`config\` field in ` + (page ? `route "${page}"` : `"${pageFilePath}"`) + ':\n' + result.unsupported + (result.path ? ` at "${result.path}"` : '') + '.\n' + 'Read More - https://nextjs.org/docs/messages/invalid-page-config';
// for a build we use `Log.error` instead of throwing
// so that all errors can be logged before exiting the process
if (isProductionBuild) {
_log.error(message);
} else {
throw Object.defineProperty(new Error(message), "__NEXT_ERROR_CODE", {
value: "E1013",
enumerable: false,
configurable: true
});
}
}
async function getAppPageStaticInfo({ pageFilePath, nextConfig, isDev, page }) {
const content = tryToReadFile(pageFilePath, !isDev);
if (!content || !PARSE_PATTERN.test(content)) {
return {
type: _pagetypes.PAGE_TYPES.APP,
config: undefined,
runtime: undefined,
preferredRegion: undefined,
maxDuration: undefined,
hadUnsupportedValue: false
};
}
const ast = await (0, _parsemodule.parseModule)(pageFilePath, content);
validateMiddlewareProxyExports({
ast,
page,
pageFilePath,
isDev
});
const { generateStaticParams, generateImageMetadata, generateSitemaps, exports: exports1, directives } = checkExports(ast, _appsegmentconfig.AppSegmentConfigSchemaKeys, page);
const { type: rsc } = getRSCModuleInformation(content, true);
const exportedConfig = {};
if (exports1) {
for (const property of exports1){
const result = (0, _extractconstvalue.extractExportedConstValue)(ast, property);
if (result !== null && 'unsupported' in result) {
warnAboutUnsupportedValue(pageFilePath, page, result);
} else if (result !== null) {
exportedConfig[property] = result.value;
}
}
}
const configResult = (0, _extractconstvalue.extractExportedConstValue)(ast, 'config');
if (configResult !== null && 'unsupported' in configResult) {
warnAboutUnsupportedValue(pageFilePath, page, configResult);
} else if (configResult !== null) {
exportedConfig.config = configResult.value;
}
const route = (0, _apppaths.normalizeAppPath)(page);
const config = (0, _appsegmentconfig.parseAppSegmentConfig)(exportedConfig, route);
// Prevent edge runtime and generateStaticParams in the same file.
if ((0, _isedgeruntime.isEdgeRuntime)(config.runtime) && generateStaticParams) {
throw Object.defineProperty(new Error(`Page "${page}" cannot use both \`export const runtime = 'edge'\` and export \`generateStaticParams\`.`), "__NEXT_ERROR_CODE", {
value: "E42",
enumerable: false,
configurable: true
});
}
// Prevent use client and generateStaticParams in the same file.
if ((directives == null ? void 0 : directives.has('client')) && generateStaticParams) {
throw Object.defineProperty(new Error(`Page "${page}" cannot use both "use client" and export function "generateStaticParams()".`), "__NEXT_ERROR_CODE", {
value: "E475",
enumerable: false,
configurable: true
});
}
// Prevent use client and unstable_instant in the same file.
if ((directives == null ? void 0 : directives.has('client')) && 'unstable_instant' in config) {
throw Object.defineProperty(new Error(`Page "${page}" cannot export "unstable_instant" from a Client Component module. To use this API, convert this module to a Server Component by removing the "use client" directive.`), "__NEXT_ERROR_CODE", {
value: "E1075",
enumerable: false,
configurable: true
});
}
if ('unstable_instant' in config && !nextConfig.cacheComponents) {
throw Object.defineProperty(new Error(`Page "${page}" cannot use \`export const unstable_instant = ...\` without enabling \`cacheComponents\`.`), "__NEXT_ERROR_CODE", {
value: "E990",
enumerable: false,
configurable: true
});
}
// Prevent unstable_dynamicStaleTime in layouts.
if ('unstable_dynamicStaleTime' in config) {
const isLayout = /\/layout\.[^/]+$/.test(pageFilePath);
if (isLayout) {
throw Object.defineProperty(new Error(`"${page}" cannot use \`export const unstable_dynamicStaleTime\`. This config is only supported in page files, not layouts.`), "__NEXT_ERROR_CODE", {
value: "E1137",
enumerable: false,
configurable: true
});
}
}
// Prevent combining unstable_dynamicStaleTime and unstable_instant.
if ('unstable_dynamicStaleTime' in config && 'unstable_instant' in config) {
throw Object.defineProperty(new Error(`Page "${page}" cannot use both \`export const unstable_dynamicStaleTime\` and \`export const unstable_instant\`.`), "__NEXT_ERROR_CODE", {
value: "E1136",
enumerable: false,
configurable: true
});
}
return {
type: _pagetypes.PAGE_TYPES.APP,
rsc,
generateImageMetadata,
generateSitemaps,
generateStaticParams,
config,
middleware: parseMiddlewareConfig(page, exportedConfig.config, nextConfig),
runtime: config.runtime,
preferredRegion: config.preferredRegion,
maxDuration: config.maxDuration,
hadUnsupportedValue
};
}
async function getPagesPageStaticInfo({ pageFilePath, nextConfig, isDev, page }) {
var _config_config, _config_config1, _config_config2;
const content = tryToReadFile(pageFilePath, !isDev);
if (!content || !PARSE_PATTERN.test(content)) {
return {
type: _pagetypes.PAGE_TYPES.PAGES,
config: undefined,
runtime: undefined,
preferredRegion: undefined,
maxDuration: undefined,
hadUnsupportedValue: false
};
}
const ast = await (0, _parsemodule.parseModule)(pageFilePath, content);
validateMiddlewareProxyExports({
ast,
page,
pageFilePath,
isDev
});
const { getServerSideProps, getStaticProps, exports: exports1 } = checkExports(ast, _pagessegmentconfig.PagesSegmentConfigSchemaKeys, page);
const { type: rsc } = getRSCModuleInformation(content, true);
const exportedConfig = {};
if (exports1) {
for (const property of exports1){
const result = (0, _extractconstvalue.extractExportedConstValue)(ast, property);
if (result !== null && 'unsupported' in result) {
warnAboutUnsupportedValue(pageFilePath, page, result);
} else if (result !== null) {
exportedConfig[property] = result.value;
}
}
}
const configResult = (0, _extractconstvalue.extractExportedConstValue)(ast, 'config');
if (configResult !== null && 'unsupported' in configResult) {
warnAboutUnsupportedValue(pageFilePath, page, configResult);
} else if (configResult !== null) {
exportedConfig.config = configResult.value;
}
// Validate the config.
const route = (0, _normalizepagepath.normalizePagePath)(page);
const config = (0, _pagessegmentconfig.parsePagesSegmentConfig)(exportedConfig, route);
const isAnAPIRoute = (0, _isapiroute.isAPIRoute)(route);
let resolvedRuntime = config.runtime ?? ((_config_config = config.config) == null ? void 0 : _config_config.runtime);
if ((0, _utils.isProxyFile)(page) && resolvedRuntime) {
const relativePath = (0, _path.relative)(process.cwd(), pageFilePath);
const resolvedPath = relativePath.startsWith('.') ? relativePath : `./${relativePath}`;
const message = `Route segment config is not allowed in Proxy file at "${resolvedPath}". Proxy always runs on Node.js runtime. Learn more: https://nextjs.org/docs/messages/middleware-to-proxy`;
if (isDev) {
// errorOnce as proxy/middleware runs per request including multiple
// internal _next/ routes and spams logs.
_log.errorOnce(message);
resolvedRuntime = _constants.SERVER_RUNTIME.nodejs;
} else {
throw Object.defineProperty(new Error(message), "__NEXT_ERROR_CODE", {
value: "E1031",
enumerable: false,
configurable: true
});
}
}
if (resolvedRuntime === _constants.SERVER_RUNTIME.experimentalEdge) {
warnAboutExperimentalEdge(isAnAPIRoute ? page : null);
}
if (!(0, _utils.isProxyFile)(page) && resolvedRuntime === _constants.SERVER_RUNTIME.edge && page && !isAnAPIRoute) {
const message = `Page ${page} provided runtime 'edge', the edge runtime for rendering is currently experimental. Use runtime 'experimental-edge' instead.`;
if (isDev) {
_log.error(message);
} else {
throw Object.defineProperty(new Error(message), "__NEXT_ERROR_CODE", {
value: "E1015",
enumerable: false,
configurable: true
});
}
}
return {
type: _pagetypes.PAGE_TYPES.PAGES,
getStaticProps,
getServerSideProps,
rsc,
config,
middleware: parseMiddlewareConfig(page, exportedConfig.config, nextConfig),
runtime: resolvedRuntime,
preferredRegion: (_config_config1 = config.config) == null ? void 0 : _config_config1.regions,
maxDuration: config.maxDuration ?? ((_config_config2 = config.config) == null ? void 0 : _config_config2.maxDuration),
hadUnsupportedValue
};
}
async function getPageStaticInfo(params) {
if (params.pageType === _pagetypes.PAGE_TYPES.APP) {
return getAppPageStaticInfo(params);
}
return getPagesPageStaticInfo(params);
}
//# sourceMappingURL=get-page-static-info.js.map
File diff suppressed because one or more lines are too long
+5
View File
@@ -0,0 +1,5 @@
/**
* Parses a module with SWC using an LRU cache where the parsed module will
* be indexed by a sha of its content holding up to 500 entries.
*/
export declare const parseModule: (_: string, content: string) => Promise<any>;
+20
View File
@@ -0,0 +1,20 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "parseModule", {
enumerable: true,
get: function() {
return parseModule;
}
});
const _lrucache = require("../../server/lib/lru-cache");
const _withpromisecache = require("../../lib/with-promise-cache");
const _crypto = require("crypto");
const _swc = require("../swc");
const parseModule = (0, _withpromisecache.withPromiseCache)(new _lrucache.LRUCache(500), async (filename, content)=>(0, _swc.parse)(content, {
isModule: 'unknown',
filename
}).catch(()=>null), (_, content)=>(0, _crypto.createHash)('sha1').update(content).digest('hex'));
//# sourceMappingURL=parse-module.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../src/build/analysis/parse-module.ts"],"sourcesContent":["import { LRUCache } from '../../server/lib/lru-cache'\nimport { withPromiseCache } from '../../lib/with-promise-cache'\nimport { createHash } from 'crypto'\nimport { parse } from '../swc'\n\n/**\n * Parses a module with SWC using an LRU cache where the parsed module will\n * be indexed by a sha of its content holding up to 500 entries.\n */\nexport const parseModule = withPromiseCache(\n new LRUCache<any>(500),\n async (filename: string, content: string) =>\n parse(content, { isModule: 'unknown', filename }).catch(() => null),\n (_, content) => createHash('sha1').update(content).digest('hex')\n)\n"],"names":["parseModule","withPromiseCache","LRUCache","filename","content","parse","isModule","catch","_","createHash","update","digest"],"mappings":";;;;+BASaA;;;eAAAA;;;0BATY;kCACQ;wBACN;qBACL;AAMf,MAAMA,cAAcC,IAAAA,kCAAgB,EACzC,IAAIC,kBAAQ,CAAM,MAClB,OAAOC,UAAkBC,UACvBC,IAAAA,UAAK,EAACD,SAAS;QAAEE,UAAU;QAAWH;IAAS,GAAGI,KAAK,CAAC,IAAM,OAChE,CAACC,GAAGJ,UAAYK,IAAAA,kBAAU,EAAC,QAAQC,MAAM,CAACN,SAASO,MAAM,CAAC","ignoreList":[0]}
+9
View File
@@ -0,0 +1,9 @@
export type AnalyzeOptions = {
dir: string;
reactProductionProfiling?: boolean;
noMangling?: boolean;
appDirOnly?: boolean;
output?: boolean;
port?: number;
};
export default function analyze({ dir, reactProductionProfiling, noMangling, appDirOnly, output, port, }: AnalyzeOptions): Promise<void>;
+229
View File
@@ -0,0 +1,229 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return analyze;
}
});
const _trace = require("../../trace");
const _log = /*#__PURE__*/ _interop_require_wildcard(require("../output/log"));
const _nodepath = /*#__PURE__*/ _interop_require_wildcard(require("node:path"));
const _config = /*#__PURE__*/ _interop_require_default(require("../../server/config"));
const _constants = require("../../shared/lib/constants");
const _turbopackanalyze = require("../turbopack-analyze");
const _durationtostring = require("../duration-to-string");
const _promises = require("node:fs/promises");
const _routediscovery = require("../route-discovery");
const _findpagesdir = require("../../lib/find-pages-dir");
const _loadcustomroutes = /*#__PURE__*/ _interop_require_default(require("../../lib/load-custom-routes"));
const _generateroutesmanifest = require("../generate-routes-manifest");
const _ppr = require("../../server/lib/experimental/ppr");
const _apppaths = require("../../shared/lib/router/utils/app-paths");
const _nodehttp = /*#__PURE__*/ _interop_require_default(require("node:http"));
const _servehandler = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/serve-handler"));
const _storage = require("../../telemetry/storage");
const _events = require("../../telemetry/events");
const _shared = require("../../trace/shared");
const _bundler = require("../../lib/bundler");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
async function analyze({ dir, reactProductionProfiling = false, noMangling = false, appDirOnly = false, output = false, port = 4000 }) {
try {
const config = await (0, _config.default)(_constants.PHASE_ANALYZE, dir, {
silent: false,
reactProductionProfiling,
bundler: _bundler.Bundler.Turbopack
});
process.env.NEXT_DEPLOYMENT_ID = config.deploymentId || '';
const distDir = _nodepath.join(dir, '.next');
const telemetry = new _storage.Telemetry({
distDir
});
(0, _trace.setGlobal)('phase', _constants.PHASE_ANALYZE);
(0, _trace.setGlobal)('distDir', distDir);
(0, _trace.setGlobal)('telemetry', telemetry);
_log.info('Analyzing a production build...');
const analyzeContext = {
config,
dir,
distDir,
noMangling,
appDirOnly
};
const { duration: analyzeDuration, shutdownPromise } = await (0, _turbopackanalyze.turbopackAnalyze)(analyzeContext);
const durationString = (0, _durationtostring.durationToString)(analyzeDuration);
const analyzeDir = _nodepath.join(distDir, 'diagnostics/analyze');
await shutdownPromise;
const routes = await collectRoutesForAnalyze(dir, config, appDirOnly);
await (0, _promises.cp)(_nodepath.join(__dirname, '../../bundle-analyzer'), analyzeDir, {
recursive: true
});
await (0, _promises.mkdir)(_nodepath.join(analyzeDir, 'data'), {
recursive: true
});
await (0, _promises.writeFile)(_nodepath.join(analyzeDir, 'data', 'routes.json'), JSON.stringify(routes, null, 2));
let logMessage = `Analyze completed in ${durationString}.`;
if (output) {
logMessage += ` Results written to ${analyzeDir}.\nTo explore the analyze results interactively, run \`next experimental-analyze\` without \`--output\`.`;
}
_log.event(logMessage);
telemetry.record((0, _events.eventAnalyzeCompleted)({
success: true,
durationInSeconds: Math.round(analyzeDuration),
totalPageCount: routes.length
}));
if (!output) {
await startServer(analyzeDir, port);
}
} catch (e) {
const telemetry = _shared.traceGlobals.get('telemetry');
if (telemetry) {
telemetry.record((0, _events.eventAnalyzeCompleted)({
success: false
}));
}
throw e;
}
}
/**
* Collects all routes from the project for the bundle analyzer.
* Returns a list of route paths (both static and dynamic).
*/ async function collectRoutesForAnalyze(dir, config, appDirOnly) {
const { pagesDir, appDir } = (0, _findpagesdir.findPagesDir)(dir);
let appType;
if (pagesDir && appDir) {
appType = 'hybrid';
} else if (pagesDir) {
appType = 'pages';
} else if (appDir) {
appType = 'app';
} else {
throw Object.defineProperty(new Error('No pages or app directory found.'), "__NEXT_ERROR_CODE", {
value: "E929",
enumerable: false,
configurable: true
});
}
const discovery = await (0, _routediscovery.discoverRoutes)({
appDir,
pagesDir,
pageExtensions: config.pageExtensions,
isDev: false,
baseDir: dir,
isSrcDir: _nodepath.relative(dir, pagesDir || appDir || '').startsWith('src'),
appDirOnly
});
const pageKeys = {
pages: Object.keys(discovery.mappedPages || {}),
app: discovery.mappedAppPages ? Object.keys(discovery.mappedAppPages).map((key)=>(0, _apppaths.normalizeAppPath)(key)) : []
};
// Load custom routes
const { redirects, headers, onMatchHeaders, rewrites } = await (0, _loadcustomroutes.default)(config);
// Compute restricted redirect paths
const restrictedRedirectPaths = [
'/_next'
].map((pathPrefix)=>config.basePath ? `${config.basePath}${pathPrefix}` : pathPrefix);
const isAppPPREnabled = (0, _ppr.checkIsAppPPREnabled)(config.experimental.ppr);
// Generate routes manifest
const { routesManifest } = (0, _generateroutesmanifest.generateRoutesManifest)({
appType,
pageKeys,
config,
redirects,
headers,
onMatchHeaders,
rewrites,
restrictedRedirectPaths,
isAppPPREnabled
});
return routesManifest.dynamicRoutes.map((r)=>r.page).concat(routesManifest.staticRoutes.map((r)=>r.page));
}
function startServer(dir, port) {
const server = _nodehttp.default.createServer((req, res)=>{
return (0, _servehandler.default)(req, res, {
public: dir
});
});
return new Promise((resolve, reject)=>{
function onError(err) {
server.close(()=>{
reject(err);
});
}
server.on('error', onError);
server.listen(port, 'localhost', ()=>{
const address = server.address();
if (address == null) {
reject(Object.defineProperty(new Error('Unable to get server address'), "__NEXT_ERROR_CODE", {
value: "E928",
enumerable: false,
configurable: true
}));
return;
}
// No longer needed after startup
server.removeListener('error', onError);
let addressString;
if (typeof address === 'string') {
addressString = address;
} else if (address.family === 'IPv6' && (address.address === '::' || address.address === '::1')) {
addressString = `localhost:${address.port}`;
} else if (address.family === 'IPv6') {
addressString = `[${address.address}]:${address.port}`;
} else {
addressString = `${address.address}:${address.port}`;
}
_log.info(`Bundle analyzer available at http://${addressString}`);
resolve();
});
});
}
//# sourceMappingURL=index.js.map
File diff suppressed because one or more lines are too long
+20
View File
@@ -0,0 +1,20 @@
import type { NextBabelLoaderOptions, NextJsLoaderContext } from './types';
import { type SourceMap, type BabelLoaderTransformOptions } from './util';
/**
* An internal (non-exported) type used by babel.
*/
export type ResolvedBabelConfig = {
options: BabelLoaderTransformOptions;
passes: BabelPluginPasses;
externalDependencies: ReadonlyArray<string>;
};
export type BabelPlugin = unknown;
export type BabelPluginPassList = ReadonlyArray<BabelPlugin>;
export type BabelPluginPasses = ReadonlyArray<BabelPluginPassList>;
export default function getConfig(ctx: NextJsLoaderContext, { source, target, loaderOptions, filename, inputSourceMap, }: {
source: string;
loaderOptions: NextBabelLoaderOptions;
target: string;
filename: string;
inputSourceMap?: SourceMap | undefined;
}): Promise<ResolvedBabelConfig | null>;
+429
View File
@@ -0,0 +1,429 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return getConfig;
}
});
const _nodefs = require("node:fs");
const _nodeutil = require("node:util");
const _json5 = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/json5"));
const _core = require("next/dist/compiled/babel/core");
const _corelibconfig = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/core-lib-config"));
const _util = require("./util");
const _log = /*#__PURE__*/ _interop_require_wildcard(require("../../output/log"));
const _swc = require("../../swc");
const _installbindings = require("../../swc/install-bindings");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
const nextDistPath = /(next[\\/]dist[\\/]shared[\\/]lib)|(next[\\/]dist[\\/]client)|(next[\\/]dist[\\/]pages)/;
function shouldSkipBabel(transformMode, configFilePath, hasReactCompiler) {
return transformMode === 'standalone' && configFilePath == null && !hasReactCompiler;
}
const fileExtensionRegex = /\.([a-z]+)$/;
async function getCacheCharacteristics(loaderOptions, source, filename) {
var _fileExtensionRegex_exec;
let isStandalone, isServer, pagesDir;
switch(loaderOptions.transformMode){
case 'default':
isStandalone = false;
isServer = loaderOptions.isServer;
pagesDir = loaderOptions.pagesDir;
break;
case 'standalone':
isStandalone = true;
break;
default:
throw Object.defineProperty(new Error(`unsupported transformMode in loader options: ${(0, _nodeutil.inspect)(loaderOptions)}`), "__NEXT_ERROR_CODE", {
value: "E811",
enumerable: false,
configurable: true
});
}
const isPageFile = pagesDir != null && filename.startsWith(pagesDir);
const isNextDist = nextDistPath.test(filename);
const hasModuleExports = source.indexOf('module.exports') !== -1;
const fileExt = ((_fileExtensionRegex_exec = fileExtensionRegex.exec(filename)) == null ? void 0 : _fileExtensionRegex_exec[1]) || 'unknown';
let { reactCompilerPlugins, reactCompilerExclude, configFile: configFilePath, transformMode } = loaderOptions;
// Compute `hasReactCompiler` as part of the cache characteristics / key,
// rather than inside of `getFreshConfig`:
// - `isReactCompilerRequired` depends on the file contents
// - `node_modules` and `reactCompilerExclude` depend on the file path, which
// isn't part of the cache characteristics
let hasReactCompiler = reactCompilerPlugins != null && reactCompilerPlugins.length !== 0 && !loaderOptions.isServer && !/[/\\]node_modules[/\\]/.test(filename) && // Assumption: `reactCompilerExclude` is cheap because it should only
// operate on the file path and *not* the file contents (it's sync)
!(reactCompilerExclude == null ? void 0 : reactCompilerExclude(filename));
// `isReactCompilerRequired` is expensive to run (parses/visits with SWC), so
// only run it if there's a good chance we might be able to skip calling Babel
// entirely (speculatively call `shouldSkipBabel`).
//
// Otherwise, we can let react compiler handle this logic for us. It should
// behave equivalently.
if (hasReactCompiler && shouldSkipBabel(transformMode, configFilePath, /*hasReactCompiler*/ false)) {
hasReactCompiler &&= await (0, _swc.isReactCompilerRequired)(filename);
}
return {
isStandalone,
isServer,
isPageFile,
isNextDist,
hasModuleExports,
hasReactCompiler,
fileExt,
configFilePath
};
}
/**
* Return an array of Babel plugins, conditioned upon loader options and
* source file characteristics.
*/ function getPlugins(loaderOptions, cacheCharacteristics) {
const { isServer, isPageFile, isNextDist, hasModuleExports } = cacheCharacteristics;
const { development, hasReactRefresh } = loaderOptions;
const applyCommonJsItem = hasModuleExports ? (0, _core.createConfigItem)(require('../plugins/commonjs'), {
type: 'plugin'
}) : null;
const reactRefreshItem = hasReactRefresh ? (0, _core.createConfigItem)([
require('next/dist/compiled/react-refresh/babel'),
{
skipEnvCheck: true
}
], {
type: 'plugin'
}) : null;
const pageConfigItem = !isServer && isPageFile ? (0, _core.createConfigItem)([
require('../plugins/next-page-config')
], {
type: 'plugin'
}) : null;
const disallowExportAllItem = !isServer && isPageFile ? (0, _core.createConfigItem)([
require('../plugins/next-page-disallow-re-export-all-exports')
], {
type: 'plugin'
}) : null;
const transformDefineItem = (0, _core.createConfigItem)([
require.resolve('next/dist/compiled/babel/plugin-transform-define'),
{
'process.env.NODE_ENV': development ? 'development' : 'production',
'typeof window': isServer ? 'undefined' : 'object',
'process.browser': isServer ? false : true
},
'next-js-transform-define-instance'
], {
type: 'plugin'
});
const nextSsgItem = !isServer && isPageFile ? (0, _core.createConfigItem)([
require.resolve('../plugins/next-ssg-transform')
], {
type: 'plugin'
}) : null;
const commonJsItem = isNextDist ? (0, _core.createConfigItem)(require('next/dist/compiled/babel/plugin-transform-modules-commonjs'), {
type: 'plugin'
}) : null;
const nextFontUnsupported = (0, _core.createConfigItem)([
require('../plugins/next-font-unsupported')
], {
type: 'plugin'
});
return [
reactRefreshItem,
pageConfigItem,
disallowExportAllItem,
applyCommonJsItem,
transformDefineItem,
nextSsgItem,
commonJsItem,
nextFontUnsupported
].filter(Boolean);
}
const isJsonFile = /\.(json|babelrc)$/;
const isJsFile = /\.js$/;
/**
* While this function does block execution while reading from disk, it
* should not introduce any issues. The function is only invoked when
* generating a fresh config, and only a small handful of configs should
* be generated during compilation.
*/ function getCustomBabelConfig(configFilePath) {
if (isJsonFile.exec(configFilePath)) {
const babelConfigRaw = (0, _nodefs.readFileSync)(configFilePath, 'utf8');
return _json5.default.parse(babelConfigRaw);
} else if (isJsFile.exec(configFilePath)) {
return require(configFilePath);
}
throw Object.defineProperty(new Error('The Next.js Babel loader does not support .mjs or .cjs config files.'), "__NEXT_ERROR_CODE", {
value: "E477",
enumerable: false,
configurable: true
});
}
let babelConfigWarned = false;
/**
* Check if custom babel configuration from user only contains options that
* can be migrated into latest Next.js features supported by SWC.
*
* This raises soft warning messages only, not making any errors yet.
*/ function checkCustomBabelConfigDeprecation(config) {
if (!config || Object.keys(config).length === 0) {
return;
}
const { plugins, presets, ...otherOptions } = config;
if (Object.keys(otherOptions ?? {}).length > 0) {
return;
}
if (babelConfigWarned) {
return;
}
babelConfigWarned = true;
const isPresetReadyToDeprecate = !presets || presets.length === 0 || presets.length === 1 && presets[0] === 'next/babel';
const pluginReasons = [];
const unsupportedPlugins = [];
if (Array.isArray(plugins)) {
for (const plugin of plugins){
const pluginName = Array.isArray(plugin) ? plugin[0] : plugin;
// [NOTE]: We cannot detect if the user uses babel-plugin-macro based transform plugins,
// such as `styled-components/macro` in here.
switch(pluginName){
case 'styled-components':
case 'babel-plugin-styled-components':
pluginReasons.push(`\t- 'styled-components' can be enabled via 'compiler.styledComponents' in 'next.config.js'`);
break;
case '@emotion/babel-plugin':
pluginReasons.push(`\t- '@emotion/babel-plugin' can be enabled via 'compiler.emotion' in 'next.config.js'`);
break;
case 'babel-plugin-relay':
pluginReasons.push(`\t- 'babel-plugin-relay' can be enabled via 'compiler.relay' in 'next.config.js'`);
break;
case 'react-remove-properties':
pluginReasons.push(`\t- 'react-remove-properties' can be enabled via 'compiler.reactRemoveProperties' in 'next.config.js'`);
break;
case 'transform-remove-console':
pluginReasons.push(`\t- 'transform-remove-console' can be enabled via 'compiler.removeConsole' in 'next.config.js'`);
break;
default:
unsupportedPlugins.push(pluginName);
break;
}
}
}
if (isPresetReadyToDeprecate && unsupportedPlugins.length === 0) {
_log.warn(`It looks like there is a custom Babel configuration that can be removed${pluginReasons.length > 0 ? ':' : '.'}`);
if (pluginReasons.length > 0) {
_log.warn(`Next.js supports the following features natively: `);
_log.warn(pluginReasons.join(''));
_log.warn(`For more details configuration options, please refer https://nextjs.org/docs/architecture/nextjs-compiler#supported-features`);
}
}
}
/**
* Generate a new, flat Babel config, ready to be handed to Babel-traverse.
* This config should have no unresolved overrides, presets, etc.
*
* The config returned by this function is cached, so the function should not
* depend on file-specific configuration or configuration that could change
* across invocations without a process restart.
*/ async function getFreshConfig(ctx, cacheCharacteristics, loaderOptions, target) {
const { transformMode } = loaderOptions;
const { hasReactCompiler, configFilePath, fileExt } = cacheCharacteristics;
let customConfig = configFilePath && getCustomBabelConfig(configFilePath);
if (shouldSkipBabel(transformMode, configFilePath, hasReactCompiler)) {
// Optimization: There's nothing useful to do, bail out and skip babel on
// this file
return null;
}
checkCustomBabelConfigDeprecation(customConfig);
// We can assume that `reactCompilerPlugins` does not change without a process
// restart (it's safe to cache), as it's specified in the `next.config.js`,
// which always causes a full restart of `next dev` if changed.
const reactCompilerPluginsIfEnabled = hasReactCompiler ? loaderOptions.reactCompilerPlugins ?? [] : [];
let isServer, pagesDir, srcDir, development;
if (transformMode === 'default') {
isServer = loaderOptions.isServer;
pagesDir = loaderOptions.pagesDir;
srcDir = loaderOptions.srcDir;
development = loaderOptions.development;
}
let options = {
babelrc: false,
cloneInputAst: false,
// Use placeholder file info. `updateBabelConfigWithFileDetails` will
// replace this after caching.
filename: `basename.${fileExt}`,
inputSourceMap: undefined,
sourceFileName: `basename.${fileExt}`,
// Set the default sourcemap behavior based on Webpack's mapping flag,
// but allow users to override if they want.
sourceMaps: loaderOptions.sourceMaps === undefined ? ctx.sourceMap : loaderOptions.sourceMaps
};
const baseCaller = {
name: 'next-babel-turbo-loader',
supportsStaticESM: true,
supportsDynamicImport: true,
// Provide plugins with insight into webpack target.
// https://github.com/babel/babel-loader/issues/787
target,
// Webpack 5 supports TLA behind a flag. We enable it by default
// for Babel, and then webpack will throw an error if the experimental
// flag isn't enabled.
supportsTopLevelAwait: true,
isServer,
srcDir,
pagesDir,
isDev: development,
transformMode,
...loaderOptions.caller
};
options.plugins = [
...transformMode === 'default' ? getPlugins(loaderOptions, cacheCharacteristics) : [],
...reactCompilerPluginsIfEnabled,
...(customConfig == null ? void 0 : customConfig.plugins) || []
];
// target can be provided in babelrc
options.target = isServer ? undefined : customConfig == null ? void 0 : customConfig.target;
// env can be provided in babelrc
options.env = customConfig == null ? void 0 : customConfig.env;
options.presets = (()=>{
// If presets is defined the user will have next/babel in their babelrc
if (customConfig == null ? void 0 : customConfig.presets) {
return customConfig.presets;
}
// If presets is not defined the user will likely have "env" in their babelrc
if (customConfig) {
return undefined;
}
// If no custom config is provided the default is to use next/babel
return [
'next/babel'
];
})();
options.overrides = loaderOptions.overrides;
options.caller = {
...baseCaller,
hasJsxRuntime: transformMode === 'default' ? loaderOptions.hasJsxRuntime : undefined
};
// Babel does strict checks on the config so undefined is not allowed
if (typeof options.target === 'undefined') {
delete options.target;
}
Object.defineProperty(options.caller, 'onWarning', {
enumerable: false,
writable: false,
value: (reason)=>{
if (!(reason instanceof Error)) {
reason = Object.defineProperty(new Error(reason), "__NEXT_ERROR_CODE", {
value: "E394",
enumerable: false,
configurable: true
});
}
ctx.emitWarning(reason);
}
});
const loadedOptions = (0, _core.loadOptions)(options);
const config = (0, _util.consumeIterator)((0, _corelibconfig.default)(loadedOptions));
return config;
}
/**
* Each key returned here corresponds with a Babel config that can be shared.
* The conditions of permissible sharing between files is dependent on specific
* file attributes and Next.js compiler states: `CharacteristicsGermaneToCaching`.
*/ function getCacheKey(cacheCharacteristics) {
const { isStandalone, isServer, isPageFile, isNextDist, hasModuleExports, hasReactCompiler, fileExt, configFilePath } = cacheCharacteristics;
const flags = 0 | (isStandalone ? 1 : 0) | (isServer ? 2 : 0) | (isPageFile ? 4 : 0) | (isNextDist ? 8 : 0) | (hasModuleExports ? 16 : 0) | (hasReactCompiler ? 32 : 0);
// separate strings with null bytes, assuming null bytes are not valid in file
// paths
return `${configFilePath || ''}\x00${fileExt}\x00${flags}`;
}
const configCache = new Map();
const configFiles = new Set();
/**
* Applies file-specific values to a potentially-cached configuration object.
*/ function updateBabelConfigWithFileDetails(cachedConfig, loaderOptions, filename, inputSourceMap) {
if (cachedConfig == null) {
return null;
}
return {
...cachedConfig,
options: {
...cachedConfig.options,
cwd: loaderOptions.cwd,
root: loaderOptions.cwd,
filename,
inputSourceMap,
// Ensure that Webpack will get a full absolute path in the sourcemap
// so that it can properly map the module back to its internal cached
// modules.
sourceFileName: filename
}
};
}
async function getConfig(ctx, { source, target, loaderOptions, filename, inputSourceMap }) {
// Install bindings early so they are definitely available to the loader.
// When run by webpack in next this is already done with correct configuration so this is a no-op.
// In turbopack loaders are run in a subprocess so it may or may not be done.
await (0, _installbindings.installBindings)();
const cacheCharacteristics = await getCacheCharacteristics(loaderOptions, source, filename);
if (loaderOptions.configFile) {
// Ensures webpack invalidates the cache for this loader when the config file changes
ctx.addDependency(loaderOptions.configFile);
}
const cacheKey = getCacheKey(cacheCharacteristics);
const cachedConfig = configCache.get(cacheKey);
if (cachedConfig !== undefined) {
return updateBabelConfigWithFileDetails(cachedConfig, loaderOptions, filename, inputSourceMap);
}
if (loaderOptions.configFile && !configFiles.has(loaderOptions.configFile)) {
configFiles.add(loaderOptions.configFile);
_log.info(`Using external babel configuration from ${loaderOptions.configFile}`);
}
const freshConfig = await getFreshConfig(ctx, cacheCharacteristics, loaderOptions, target);
configCache.set(cacheKey, freshConfig);
return updateBabelConfigWithFileDetails(freshConfig, loaderOptions, filename, inputSourceMap);
}
//# sourceMappingURL=get-config.js.map
File diff suppressed because one or more lines are too long
+3
View File
@@ -0,0 +1,3 @@
import type { NextJsLoaderContext } from './types';
declare function nextBabelLoaderOuter(this: NextJsLoaderContext, inputSource: string, inputSourceMap?: any): void;
export default nextBabelLoaderOuter;
+56
View File
@@ -0,0 +1,56 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return _default;
}
});
const _transform = /*#__PURE__*/ _interop_require_default(require("./transform"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
async function nextBabelLoader(ctx, parentTrace, inputSource, inputSourceMap) {
const filename = ctx.resourcePath;
// Ensure `.d.ts` are not processed.
if (filename.endsWith('.d.ts')) {
return [
inputSource,
inputSourceMap
];
}
const target = ctx.target;
const loaderOptions = parentTrace.traceChild('get-options')// @ts-ignore TODO: remove ignore once webpack 5 types are used
.traceFn(()=>ctx.getOptions());
if (loaderOptions.exclude && loaderOptions.exclude(filename)) {
return [
inputSource,
inputSourceMap
];
}
const loaderSpanInner = parentTrace.traceChild('next-babel-turbo-transform');
const { code: transformedSource, map: outputSourceMap } = await loaderSpanInner.traceAsyncFn(async ()=>await (0, _transform.default)(ctx, inputSource, inputSourceMap, loaderOptions, filename, target, loaderSpanInner));
return [
transformedSource,
outputSourceMap
];
}
function nextBabelLoaderOuter(inputSource, // webpack's source map format is compatible with babel, but the type signature doesn't match
inputSourceMap) {
const callback = this.async();
const loaderSpan = this.currentTraceSpan.traceChild('next-babel-turbo-loader');
loaderSpan.traceAsyncFn(()=>nextBabelLoader(this, loaderSpan, inputSource, inputSourceMap)).then(([transformedSource, outputSourceMap])=>callback == null ? void 0 : callback(/* err */ null, transformedSource, outputSourceMap ?? inputSourceMap), (err)=>{
callback == null ? void 0 : callback(err);
});
}
// check this type matches `webpack.LoaderDefinitionFunction`, but be careful
// not to publicly rely on the webpack type since the generated typescript
// declarations will be wrong.
const _nextBabelLoaderOuter = nextBabelLoaderOuter;
const _default = nextBabelLoaderOuter;
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"sources":["../../../../src/build/babel/loader/index.ts"],"sourcesContent":["import type { Span } from '../../../trace'\nimport transform from './transform'\nimport type { NextJsLoaderContext } from './types'\nimport type { SourceMap } from './util'\nimport type { webpack } from 'next/dist/compiled/webpack/webpack'\n\nasync function nextBabelLoader(\n ctx: NextJsLoaderContext,\n parentTrace: Span,\n inputSource: string,\n inputSourceMap: SourceMap | null | undefined\n): Promise<[string, SourceMap | null | undefined]> {\n const filename = ctx.resourcePath\n\n // Ensure `.d.ts` are not processed.\n if (filename.endsWith('.d.ts')) {\n return [inputSource, inputSourceMap]\n }\n\n const target = ctx.target\n const loaderOptions: any = parentTrace\n .traceChild('get-options')\n // @ts-ignore TODO: remove ignore once webpack 5 types are used\n .traceFn(() => ctx.getOptions())\n\n if (loaderOptions.exclude && loaderOptions.exclude(filename)) {\n return [inputSource, inputSourceMap]\n }\n\n const loaderSpanInner = parentTrace.traceChild('next-babel-turbo-transform')\n const { code: transformedSource, map: outputSourceMap } =\n await loaderSpanInner.traceAsyncFn(\n async () =>\n await transform(\n ctx,\n inputSource,\n inputSourceMap,\n loaderOptions,\n filename,\n target,\n loaderSpanInner\n )\n )\n\n return [transformedSource, outputSourceMap]\n}\n\nfunction nextBabelLoaderOuter(\n this: NextJsLoaderContext,\n inputSource: string,\n // webpack's source map format is compatible with babel, but the type signature doesn't match\n inputSourceMap?: any\n) {\n const callback = this.async()\n\n const loaderSpan = this.currentTraceSpan.traceChild('next-babel-turbo-loader')\n loaderSpan\n .traceAsyncFn(() =>\n nextBabelLoader(this, loaderSpan, inputSource, inputSourceMap)\n )\n .then(\n ([transformedSource, outputSourceMap]) =>\n callback?.(\n /* err */ null,\n transformedSource,\n outputSourceMap ?? inputSourceMap\n ),\n (err) => {\n callback?.(err)\n }\n )\n}\n\n// check this type matches `webpack.LoaderDefinitionFunction`, but be careful\n// not to publicly rely on the webpack type since the generated typescript\n// declarations will be wrong.\nconst _nextBabelLoaderOuter: webpack.LoaderDefinitionFunction<\n {},\n NextJsLoaderContext\n> = nextBabelLoaderOuter\n\nexport default nextBabelLoaderOuter\n"],"names":["nextBabelLoader","ctx","parentTrace","inputSource","inputSourceMap","filename","resourcePath","endsWith","target","loaderOptions","traceChild","traceFn","getOptions","exclude","loaderSpanInner","code","transformedSource","map","outputSourceMap","traceAsyncFn","transform","nextBabelLoaderOuter","callback","async","loaderSpan","currentTraceSpan","then","err","_nextBabelLoaderOuter"],"mappings":";;;;+BAiFA;;;eAAA;;;kEAhFsB;;;;;;AAKtB,eAAeA,gBACbC,GAAwB,EACxBC,WAAiB,EACjBC,WAAmB,EACnBC,cAA4C;IAE5C,MAAMC,WAAWJ,IAAIK,YAAY;IAEjC,oCAAoC;IACpC,IAAID,SAASE,QAAQ,CAAC,UAAU;QAC9B,OAAO;YAACJ;YAAaC;SAAe;IACtC;IAEA,MAAMI,SAASP,IAAIO,MAAM;IACzB,MAAMC,gBAAqBP,YACxBQ,UAAU,CAAC,cACZ,+DAA+D;KAC9DC,OAAO,CAAC,IAAMV,IAAIW,UAAU;IAE/B,IAAIH,cAAcI,OAAO,IAAIJ,cAAcI,OAAO,CAACR,WAAW;QAC5D,OAAO;YAACF;YAAaC;SAAe;IACtC;IAEA,MAAMU,kBAAkBZ,YAAYQ,UAAU,CAAC;IAC/C,MAAM,EAAEK,MAAMC,iBAAiB,EAAEC,KAAKC,eAAe,EAAE,GACrD,MAAMJ,gBAAgBK,YAAY,CAChC,UACE,MAAMC,IAAAA,kBAAS,EACbnB,KACAE,aACAC,gBACAK,eACAJ,UACAG,QACAM;IAIR,OAAO;QAACE;QAAmBE;KAAgB;AAC7C;AAEA,SAASG,qBAEPlB,WAAmB,EACnB,6FAA6F;AAC7FC,cAAoB;IAEpB,MAAMkB,WAAW,IAAI,CAACC,KAAK;IAE3B,MAAMC,aAAa,IAAI,CAACC,gBAAgB,CAACf,UAAU,CAAC;IACpDc,WACGL,YAAY,CAAC,IACZnB,gBAAgB,IAAI,EAAEwB,YAAYrB,aAAaC,iBAEhDsB,IAAI,CACH,CAAC,CAACV,mBAAmBE,gBAAgB,GACnCI,4BAAAA,SACE,OAAO,GAAG,MACVN,mBACAE,mBAAmBd,iBAEvB,CAACuB;QACCL,4BAAAA,SAAWK;IACb;AAEN;AAEA,6EAA6E;AAC7E,0EAA0E;AAC1E,8BAA8B;AAC9B,MAAMC,wBAGFP;MAEJ,WAAeA","ignoreList":[0]}
+5
View File
@@ -0,0 +1,5 @@
import { type GeneratorResult } from 'next/dist/compiled/babel/generator';
import type { Span } from '../../../trace';
import type { NextJsLoaderContext } from './types';
import type { SourceMap } from './util';
export default function transform(ctx: NextJsLoaderContext, source: string, inputSourceMap: SourceMap | null | undefined, loaderOptions: any, filename: string, target: string, parentSpan: Span): Promise<GeneratorResult>;
+103
View File
@@ -0,0 +1,103 @@
/*
* Partially adapted from @babel/core (MIT license).
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return transform;
}
});
const _traverse = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/traverse"));
const _generator = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/generator"));
const _corelibnormalizefile = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/core-lib-normalize-file"));
const _corelibnormalizeopts = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/core-lib-normalize-opts"));
const _corelibblockhoistplugin = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/core-lib-block-hoist-plugin"));
const _corelibpluginpass = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/babel/core-lib-plugin-pass"));
const _getconfig = /*#__PURE__*/ _interop_require_default(require("./get-config"));
const _util = require("./util");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function getTraversalParams(file, pluginPairs) {
const passPairs = [];
const passes = [];
const visitors = [];
for (const plugin of pluginPairs.concat((0, _corelibblockhoistplugin.default)())){
const pass = new _corelibpluginpass.default(file, plugin.key, plugin.options);
passPairs.push([
plugin,
pass
]);
passes.push(pass);
visitors.push(plugin.visitor);
}
return {
passPairs,
passes,
visitors
};
}
function invokePluginPre(file, passPairs) {
for (const [{ pre }, pass] of passPairs){
if (pre) {
pre.call(pass, file);
}
}
}
function invokePluginPost(file, passPairs) {
for (const [{ post }, pass] of passPairs){
if (post) {
post.call(pass, file);
}
}
}
function transformAstPass(file, pluginPairs, parentSpan) {
const { passPairs, passes, visitors } = getTraversalParams(file, pluginPairs);
invokePluginPre(file, passPairs);
const visitor = _traverse.default.visitors.merge(visitors, passes, // @ts-ignore - the exported types are incorrect here
file.opts.wrapPluginVisitorMethod);
parentSpan.traceChild('babel-turbo-traverse').traceFn(()=>(0, _traverse.default)(file.ast, visitor, file.scope));
invokePluginPost(file, passPairs);
}
function transformAst(file, babelConfig, parentSpan) {
for (const pluginPairs of babelConfig.passes){
transformAstPass(file, pluginPairs, parentSpan);
}
}
async function transform(ctx, source, inputSourceMap, loaderOptions, filename, target, parentSpan) {
const getConfigSpan = parentSpan.traceChild('babel-turbo-get-config');
const babelConfig = await (0, _getconfig.default)(ctx, {
source,
loaderOptions,
inputSourceMap: inputSourceMap ?? undefined,
target,
filename
});
if (!babelConfig) {
return {
code: source,
map: inputSourceMap ?? null
};
}
getConfigSpan.stop();
const normalizeSpan = parentSpan.traceChild('babel-turbo-normalize-file');
const file = (0, _util.consumeIterator)((0, _corelibnormalizefile.default)(babelConfig.passes, (0, _corelibnormalizeopts.default)(babelConfig), source));
normalizeSpan.stop();
const transformSpan = parentSpan.traceChild('babel-turbo-transform');
transformAst(file, babelConfig, transformSpan);
transformSpan.stop();
const generateSpan = parentSpan.traceChild('babel-turbo-generate');
const { code, map } = (0, _generator.default)(file.ast, file.opts.generatorOpts, file.code);
generateSpan.stop();
return {
code,
map
};
}
//# sourceMappingURL=transform.js.map

Some files were not shown because too many files have changed in this diff Show More