This bundles a collection of Typescript updates that correct typings
across the servers:
- Manifest typings have been narrowed
- Some methods have been moved to abstract methods on classes
- Added some type guard functions for route matches
- Utilized early returns in logic to reduce nesting
- Added mutability modifiers to some properties to prevent accidental
mutations
- Removed some useless assigns from unused catch error params:
```ts
try {
await something
} catch (_) {}
// Is the same as
try {
await something
} catch {}
```
This does not introduce any new functionality, simply some QOL
improvements.
I've introduced a bug with memory watching in development in this PR: #53523.
Specifically when calling `cleanup` the process would exit because the `exit` listener on the childprocess would be called which then calls `process.exit(0)`. This caused a condition where calling `worker.end()` would immediately quit the process.
This PR ensures the cleanup listeners for childprocess are disabled (`.off(`) so that when we call `worker.end()` the process is terminated without the main process being terminated.
## Initial Pass
The initial pass applies to all user code. If an import (`foo`) matches one of the packages from our list, say:
```js
// user code
import { a } from 'foo'
import { otherThings } from './code'
```
The initial pass transforms it into:
```js
// user code
import { a } from '__barrel_optimize__?names=a!=!foo'
import { otherThings } from './code'
```
## Barrel Optimizations
This `__barrel_optimize__` loader is used to optimize the imports of "barrel" files that have many
re-exports. Currently, both Node.js and Webpack have to enter all of these
submodules even if we only need a few of them.
For example, say a file `foo.js` with the following contents:
```js
export { a } from './a'
export { b } from './b'
export { c } from './c'
...
```
If the user imports `a` only, this loader will accept the `names` option to
be `['a']`. Then, it request the `__barrel_transform__` SWC loader to load
`foo.js` (via `this.loadModule` Webpack API) and receive the following info:
```js
export const __next_private_export_map__ = '[["./a","a","a"],["./b","b","b"],["./c","c","c"],...]'
```
The export map, generated by SWC, is a JSON that represents the exports of
that module, their original file, and their original name (since you can do
`export { a as b }`).
Then, this loader can safely remove all the exports that are not needed and
re-export the ones from `names`:
```js
export { a } from './a'
```
That's the basic situation and also the happy path.
## Wildcard Exports
For wildcard exports (e.g. `export * from './a'`), it becomes a bit more complicated.
Say `foo.js` with the following contents:
```js
export * from './a'
export * from './b'
export * from './c'
...
```
If the user imports `bar` from it, SWC can never know which files are going to be
exporting `bar`. So, we have to keep all the wildcard exports and do the same
process recursively. This loader will return the following output:
```js
export * from '__barrel_optimize__?names=bar&wildcard!=!./a'
export * from '__barrel_optimize__?names=bar&wildcard!=!./b'
export * from '__barrel_optimize__?names=bar&wildcard!=!./c'
...
```
The "!=!" tells Webpack to use the same loader to process './a', './b', and './c'.
After the recursive process, the "inner loaders" will either return an empty string
or:
```js
export * from './target'
```
Where `target` is the file that exports `bar`.
## Non-Barrel Files
If the file is not a barrel, we can't apply any optimizations. That's because
we can't easily remove things from the file. For example, say `foo.js` with:
```js
const v = 1
export function b () {
return v
}
```
If the user imports `b` only, we can't remove the `const v = 1` even though
the file is side-effect free. In these caes, this loader will simply re-export
`foo.js`:
```js
export * from './foo'
```
Besides these cases, this loader also carefully handles the module cache so
SWC won't analyze the same file twice, and no instance of the same file will
be accidentally created as different instances.
---
- [x] Disable this loader for Jest
- [x] Add tests for SWC loader caching
- [x] Add tests for external modules
- [x] Add tests for pages
- [x] Add tests for recursive `export *`s
---
Closes#54038, closes#54286.
* Share util `isGroupSegment`
* Refactor `normalizePathname` to`normalizeSegments` in `src/client/components/router-reducer/compute-changed-path.ts` to avoid extra call of path join and split
Fix#45301
If you deploy Next.js with in front Cloudflare, empty prefetch responses will be cached because there is no `cache-control` header and the extension is .json, Cloudflare considers these requests cacheable assets
If you want a test for this I would like to know if there is an existing one where I can add the header check
A continuation of #51864 with RedirectType used in an e2e test and some
ts-ignores removed from the codebase. Happy to split it into two PRs but
I left comments in the two consequential files
---------
Previously the code used in both edge and node runtimes used _almost_ the same code. This unifies the two into the base server implementation while also preserving the specific case handled by the split.
This also moves the `/_next/data` route matching to a cached value to prevent it from creating the `RegExp` on every request evaluation.
Adding a default app router not-found error page in production. We introduced a custom global not-found page if you have `not-found.js` file under app directory. Next.js will still routed you to default pages 404 if there's no routes matched when you don't have a custom `not-found.js`.
This PR creates a default layout (only having `html` and `body`) and will use the default not-found component as children to build a default 404 page for app router, and server will route to that page when there's any app router pages existed. This will also fix the hmr issue that when you hit a pathname doesn't exist, nextjs will compile `/_error` for you which is not expected, now we're using `/not-found` instead
Closes NEXT-1359
for internal:
https://vercel.slack.com/archives/C03S8ED1DKM/p1691700057242999
### Problem
- The existing [`redirect()`
function](https://nextjs.org/docs/app/api-reference/functions/redirect)
can't control the status code.
- The existing [`redirect()`
function](https://nextjs.org/docs/app/api-reference/functions/redirect)
returns a 307 HTTP redirect response while it returns a 308-equivalent
meta tag `<meta http-equiv="refresh" content="0;url=/foo"/>` in
streaming response (e.g., suspense boundary), making the behavior
inconsistent.
### Solution
Adding a new `permanentRedirect()` function and changing the meta tag
default accordingly.
| func | HTTP status | meta tag |
|---|:---:|---|
| `redirect()` | 307 | `<meta http-equiv="refresh"
content="1;url=/foo"/>` |
| `permanentRedirect()` | 308 | `<meta http-equiv="refresh"
content="0;url=/foo"/>` |
ref.
https://developers.google.com/search/docs/crawling-indexing/301-redirects
---------
Co-authored-by: JJ Kasper <jj@jjsweb.site>
Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This replaces the existing recursive directory reading beheviour with a more efficient implementation. Rather than previously doing actual recursion with the function calls to go deeper into each directory, this has been rewritten to instead use a while loop and a stack. This should improve memory usage for projects with very deep directory structures.
The updated design that performs directory scanning on all directories found at each layer, allowing more filesystem calls to be sent to the OS instead of waiting like the previous implementation did.
**Currently the new implementation is about 3x faster.**
### What?
fix the paths for app pages with route groups (e. g. `(dashboard)`)
Closes WEB-1463
---------
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Noticed there were two cases in `next-server.ts` that leverage `this as any` to call functions defined only in next-dev-server.
This change ensures the types are correct, which is useful for refactoring, e.g. renaming the function in `next-dev-server` would cause the original code to break unexpectedly.
When I was working on #54199 , if the file path is wrong the next app build error only shows "can't read file from ...", it took me hours to figure out where it actually fails in next build command. Adding an prefix for the error message so that could identify it easier.
Also clean up other unused comments and incorrect named variables
This implements the same cleanup logic used for start-server and render-workers for the workers used during build.
It's more of a contingency as we do call `.end()` on the worker too.
Fixes#45508
Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
## Implementation
Base on #54530, we're implementing a `optimize_barrel` transform to
optimize barrel files to only export the names we need. If the
transformed file isn't a "barrel file", we just re-export the names from
it without any transformation.
Take `lucide-react` as an example, with #54530 we are able to transform
```js
import { IceCream } from 'lucide-react'
```
to
```js
import { IceCream } from '__barrel_optimize__?names=IceCream!=!lucide-react?__barrel_optimize_noop__=IceCream'
```
And then, we apply that new request with a new Webpack module rule to
use the SWC loader with option `optimizeBarrelExports: ['IceCream']`,
which eventually got passed to this new `optimize_barrel` transform and
does the optimization.
## Notes
We'll have to add a new `getModularizeImportAliases` alias list to map
`lucide-react` to the ESM version, as we have the `['main', 'module']`
resolve order for the server compiler. Otherwise this optimization
doesn't work in that compiler.
There's no e2e test added because it's already covered by the
`modularize-imports` test as we removed the default `lucide-react`
transform rules and it still works.
We'll need to test other libs before migrating them to the new
`optimizePackageImports` option.
---
Closes#54571, closes#53605, closes#53789, closes#53894, closes
#54063.
This PR is a larger change to documentation to make the following
updates:
- Deconstructs [Server
Actions](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions)
into "Forms and Mutations" and an API reference
- Removes content in place of future React API documentation pages
- Removes outdated [Building
Forms](https://nextjs.org/docs/pages/building-your-application/data-fetching/building-forms)
docs from the Pages Router and adds conditional content for both routes
in "Forms and Mutations"
- Adds TypeScript code blocks to API Routes page, recommends Route
Handlers for isomorphic signatures.
- Updates `revalidatePath` and `revalidateTag` docs to have a Server
Actions example.
---------
Co-authored-by: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com>
Before:
```
Error: `export const config` in /vercel/path0/src/app/api/route.js is deprecated. Please change `runtime` property to segment export config. See https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config
```
After:
```
Error: `export const config` in /vercel/path0/src/app/api/route.js is deprecated:
- Change `config.runtime…` to `export const runtime = "edge"`
- Change `config.regions…` to `export const preferredRegion = ["us-east-1"]`
Visit https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config for more information.
```
The values proposed in Change.. are the actual ones from the customers, they can just copy paste.
Closes NEXT-1560
This ensures we don't pass through the signal field when revalidating a
fetch as that can be delayed and we don't want to abort the
revalidation.
Closes: https://github.com/vercel/next.js/issues/54045
### What?
* add support for middleware manifest and edge adapter for pages API
routes
* improve the error reporting a tiny bit
### Why?
### How?
Closes WEB-1428
When `fallback: false` is set and you visit a dynamic segment (e.g. `/[slug]`), the router server was getting stuck in a `x-no-fallback` loop and eventually would fail because it was matching the output at `check_fs` before attempting to resolve dynamic routes in the `check: true` block.
Closes NEXT-1557
This is the first step to enable the automatic "modularize imports"
optimization for some libraries. It transforms named imports like
`import { A, B, C as F } from 'foo'` to a special loader string: `import
{ A, B, C as F } from "barrel-optimize-loader?names=A,B,C!foo"`.
In a follow-up PR we'll apply corresponding optimization with another
SWC transformer.