## What
Using methods from `next/headers` in middleware would throw a `requestAsyncStorage` invariant. Additionally, using `draftMode()` in middleware/an edge runtime is not possible
## Why
We do not expose `requestAsyncStorage` to the middleware adapter. Also, the prerender manifest wasn't available to the `EdgeRouteModuleWrapper` & middleware adapter, so it wasn't possible to enable/disable it.
## How
This makes `requestAsyncStorage` available for middleware, and makes the preview mode data available from build to the edge runtime/middleware.
Fixes#52557
### What?
* fixes problems in Next.rs API introduced by #52846
* adds test infrastructure for experimental turbo testing
* adds two test cases to verify the infrastructure
* add grouping of output logs in run-tests
* simplify template loading
### Why?
### How?
## What?
Follow-up to #51830. That PR disables prefetching in `<Link>` but not in the router, so `router.prefetch` would still cause a prefetch and additional compile.
This removes the route handler abstraction and old match validation code in favor of the existing `load-components` flow that exports the `routeModule` directly.
As explained in the comments, for local development, we still want to compress the cache files individually to avoid I/O bottlenecks as we are seeing 1~10 seconds of FS I/O time from user reports.
## What?
Since the recent changes to the server the CPU profile for the router process was no longer written on `ctrl + c`. Turns out the reason is that we now call kill with `SIGKILL` which can't be observed in Node.js.
I've changed it to `SIGINT` instead so that the SIGINT handlers are called during cleanup. The CPU profile writing happens in SIGINT.
Hi!
In previous versions (13.4.2 and earlier) in the custom server I could
do the following:
```
const parsedUrl = parse(req.url, true);
const { pathname } = parsedUrl;
if (pathname === '/c') {
await handle(req, res, parse('/b', true));
} else {
await handle(req, res, parsedUrl);
}
```
Of course, you can replace `handle` with `app.render` in the attached
example, but in practice it is convenient to put the definition of
`parsedUrl` into middleware and substitute the necessary `parsedUrl` in
exceptional situations.
This was broken in #49805.
I'm not sure if this use of request handler is expected, but it has
always worked and people have used it (probably due to lack of
documentation about the difference between `app.render` and
`app.getRequestHandler()`). So the change looks breaking, and I don't
think it should appear in minor versions.
---------
Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
### What?
Disables webpacks cache compression
### Why?
CI already compresses the cache. No need for next.js to do that. In fact this actually causes worse experience in multiple ways:
* CI compresses the cache after the build has finished. So compressing inline slows down the build.
* gzip compression runs with BEST_SPEED optimization, which creates larger cache files. This leads to running into potential cache size limits easier.
* Two layers for compression are not efficient in size and speed.
Trade-off:
* The whole cache will be decompressed on every build, which is less efficient.
In a few tests the benefits are greater than the trade offs.
Spinning out from #37151 and my draft PR #52845, this enables the two
basic recommended rulesets from
[typescript-eslint](https://typescript-eslint.io) for the Next.js
monorepo source code:
*
[`plugin:@typescript-eslint/recommended`](https://typescript-eslint.io/linting/configs#recommended):
Our base recommended rules that detect common bugs or _(non-stylistic)_
TypeScript bad practices
*
[`plugin:@typescript-eslint/stylistic`](https://typescript-eslint.io/linting/configs#stylistic):
Our base starting stylistic recommended for keeping codebases visually
consistent and avoiding out-of-practice visual constructs
The process I used is pretty standard (see
https://github.com/typescript-eslint/typescript-eslint/issues/6760 for
other repos it was done on):
1. Enable those base recommended presets
2. Remove any rule settings that are now redundant
3. Reconfigure any rule whose default settings didn't seem to make sense
for this codebase
4. Add a `// Todo: ...` comment, and under it, add a disable for any
rule that immediately reported a lot of complaints
Note that this only enables the presets internally. It doesn't impact
what end-users of published packages such as Next.js or
`create-next-app` experience. That's a separate task in #52845.
I also didn't fix any existing warning from the `canary` branch. Would
you like me to do that? My preference would be a separate PR to get it
in more quickly.
Any code changes are commented inline.
---------
Co-authored-by: Steven <steven@ceriously.com>
Safari caches scripts during the same browsing session no matter what cache headers are set. This makes it impossible to update our runtime bundles (e.g. Webpack's runtime) during development as the legacy bundle might be cached and still served. If an updated client bundle uses a feature (e.g. `__webpack_require__.n`) that causes a change of the runtime, it triggers an error.
The most straightforward solution would be adding a query to prevent caching.
Fixes#53281.
## What?
I was investigating reports of server actions with `revalidatePath` /
`revalidateTag` not invalidating the client-side router cache. Managed
to reproduce the issue here:
https://github.com/timneutkens/server-actions-test (requires Vercel KV
to run).
While looking at the reducer I noticed a few things that seemed off:
- setTimeout to trigger another `dispatch` on the same reducer with the
fetched data. This means that it would not be part of the same React
Transition.
- redirects weren't applying the data that comes back from the server
(that allows for single hop navigation)
- prefetchCache was invalidated, but the router cache which is used for
back/forward navigation was not invalidated, causing back/forward to not
get the new data.
- all changes in the action-reducer mutate. The part that shouldn't
mutate was part of that setTimeout dispatch.
This PR aims to solve all of these by reworking the actions reducer to
be handled similarly to `router.refresh()`. Since `router.refresh()` was
already modeled to be similar to `revalidatePath('/')`.
The flow is now more like the other reducers:
- Fetch data
- Wait for the data to come back
- Apply the data to the cache and keep it in a mutable variable
- Return the new cache and otherwise values like the url
In particular the actions reducer handles a few extra specifics:
- Resolving the server action promise, so that the value is passed to
the application code waiting for the result.
- Applying redirects from `redirect()` calls.
- Invalidating the router cache
## Followup changes
- Currently when calling `revalidatePath('/dashboard')` the entire
router cache is invalidated instead of only `/dashboard` and further
down, this is not in scope for this PR but still has to be added.
- `notFound()`, I'm not sure how this is supposed to work exactly, it
doesn't really make sense to me to allow it in server actions.
Kudos @feedthejim for helping investigate for this PR 😌
<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:
## For Contributors
### Improving Documentation
- Run `pnpm prettier-fix` to fix formatting issues before opening the
PR.
- Read the Docs Contribution Guide to ensure your contribution follows
the docs guidelines:
https://nextjs.org/docs/community/contribution-guide
### Adding or Updating Examples
- The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- Make sure the linting passes by running `pnpm build && pnpm lint`. See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md
### Fixing a bug
- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md
### Adding a feature
- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md
## For Maintainers
- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change
### What?
### Why?
### How?
Closes NEXT-
Fixes #
-->
This updates the Turbopack build code to provide the same `routeModule` export for App Pages as the Webpack loader does. This also adapts the Turbopack and Webpack loaders to use a shared loader file that is templated.
Fixes NEXT-1469
The template supports the following styles:
# Injections
```ts
declare const tree: LoaderCode
```
Allows you to define the variable in scope in TS, this lets you reference it with correct types within the rest of the file.
```ts
// INJECT:tree
```
Is replaced by the variable that's injected. This lets you ensure the correct invocation/initilization order.
# Variables
Variables will be substituted in the TS code when found. It's only really useful for strings, as the definition looks for the following in the outputted JS code:
```ts
"VAR_REPLACE_ME"
```
So you can have something like:
```ts
const thing = new AmazingThing({ page: "VAR_PAGE" })
```
And it'll be replaced by:
```ts
const thing = new AmazingThing({ page: "/thing" })
```
Where `VAR_PAGE` is `JSON.stringify("/thing")`.
We don't need this peerDependency as it's no longer recommended and only
added for specific cases. This avoids us having to run `node-gyp` just
for this peer dep.
> NOTE OF OBSOLESCENCE -- The author of this project recommends you
avoid its use if possible.
x-ref:
https://github.com/vercel/next.js/actions/runs/5716924037/job/15489725344?pr=53391
### What?
Change the `favicon.ico` metadata `sizes` property from always `"any"`
to using the actual size possible
### Why?
When chrome/firefox browsers search for icon it needs the proper
metadata to determine which one to use, giving `favicon.ico` sizes with
`"any"` will prevent it loading the `icon.svg` as default icon when
available.
Changing to set proper size of `favicon.ico` (as the `favicon.ico` sizes
could be 16x16, 32x32, etc.) fixes the issue.
It works (loading svg icon) for chrome and firefox:
Firefox
<img width="505" alt="image"
src="https://github.com/vercel/next.js/assets/4800338/6873e595-479d-4d9e-ae5c-39e5f938fcf5">
Chrome
<img width="460" alt="image"
src="https://github.com/vercel/next.js/assets/4800338/03bbe4c7-ef76-4f34-a611-337b0d4b97a3">
It loads favicon.ico for Safari:
Using the `test/e2e/app-dir/metadata` app it shows the favicon.ico for
Safari
<img width="1000" alt="image"
src="https://github.com/vercel/next.js/assets/4800338/92cc8714-ea5e-432d-8144-2a4a42ee4ce2">
Can't have it as an e2e test as I tested it always loads the
`favicon.ico` in headless mode which can't determine the behaviors
Fixes#52002
Co-authored-by: JJ Kasper <jj@jjsweb.site>
This PR reverts a change that removed the `content-length` header filtering from the req made by the actions when redirecting. This change made some tests flaky and presumably also broke server actions in subtle ways.
There's still one other bug when redirecting after revalidating that will happen in you revalidate a page that was already rendered before where we will still show stale content. @timneutkens is fixing that one.
NEXT-1483
When verbose logging is enabled and a cache MISS is logged due to either `revalidate: 0`,`cache: no-store` or `cache-control: no-store`, this logs a slightly different message, ie:
```
- GET / 200 in 804ms
├─── GET <url> in 205ms (cache: SKIP, reason: cache: no-cache)
├────── GET <url> 200 in 0ms (cache: HIT)
├────── GET <url> 200 in 373ms (cache: SKIP, reason: revalidate: 0)
└────── GET <url> 200 in 111ms (cache: SKIP, reason: cache-control: no-cache (hard refresh))
```
Closes NEXT-1412
The PR follows #53146 and #53115.
The PR does 3 things:
- Replaces a [very heavy dependency `cpy`](https://github.com/vercel/next.js/pull/53146#issuecomment-1649193789) with a more lightweight copy helper.
- The `fs.cp(src, dest, {recursive: true})` API is not used, as it is still experimental:
<img width="1630" alt="image" src="https://github.com/vercel/next.js/assets/40715044/c61a454a-3a96-4658-a389-fbb68c241f18">
- Update `cross-spawn` to the latest version `7.0.3`
- The only breaking change introduced in `cross-spawn@7.x` is dropping Node.js 8 supports, which allows `cross-spawn` to drop a dependency. Since `create-next-app` requires Node.js 16.8.0, I assume bumping `cross-spawn` would be safe.
- Update `fast-glob` to the latest version `3.3.1` to remove more KiBs (pointed out by @imranbarbhuiya)
- The breaking change introduced in `fast-glob@3.x` is dropping Node.js 8 supports and some options changes.
Together the PR removes another 202 KiB from the `create-next-app/dist/index.js`. The size of `create-next-app/dist/index.js` is now 616 KiB.
<img width="583" alt="image" src="https://github.com/vercel/next.js/assets/40715044/4deb5e36-a63b-4501-b67c-29ea06e30578">
Colocated unit tests (such as ones in `packages/next` and `packages/font`) weren't running in CI since `run-tests` marks the glob cwd as `<root>/tests`. This modifies the working directory to be the root so the new expanded test pattern will pick up files outside of `test/`.
Several of these tests were failing so there are updates in here to fix them. Specifically:
- Source Sans Pro font was renamed to Source Sans 3
- `fillCacheWithDataProperty` test was hitting the `bailOptimistic` code path
- `resolve-metadata` had an invalid assertion (`rel: icon` gets added as part of `IconsMetadata`)
- `resolve-opengraph` wasn't handling undefined images
- `server-patch-reducer` now use inline snapshots as one was failing since it now has a prefetchCache
### What?
Exposing the original error message.
### Why?
While looking at #53279, I noticed that we don't show the original error message, which makes it hard to guess why the error was thrown in the first place.
### How?
Related #53279
This implements the handling for the new `--experimental-turbo` flag
that keeps the Next.js routing handling in front of turbopack and
leverages the new Next.rs API.
---------
Co-authored-by: Tobias Koppers <tobias.koppers@googlemail.com>
Co-authored-by: Alex Kirszenberg <alex.kirszenberg@vercel.com>
This refactors the changes from my previous PR to allow smooth scrolling for the appDir case -- `componentDidUpdate` isn't a reliable way to check if only the hash has changed. This adds a property to `focusAndScrollRef` and compares canonicalUrls (sans hash fragment)
- Original https://github.com/vercel/next.js/pull/52915
Co-authored-by: Tim Neutkens <6324199+timneutkens@users.noreply.github.com>
Mark `react-dev-overlay` as an external for the client layer. This
reduces the server bundle by 1 MB (2.5 MB → 1.5 MB) during dev with
fewer resolve calls. Note that it applies to all pages, so this will
have a non-trivial memory improvement potentially.
This PR adds some improved `modularizeImports` rules to ensure that some
of the popular UI libraries (mostly icons) can be correctly optimized
instead of creating thousands of modules. Here's an example of applying
this to `lucide-react`:
![CleanShot 2023-07-22 at 19 34
15@2x](https://github.com/vercel/next.js/assets/3676859/cf9ef13f-1d5d-4df6-9097-364983ea7b8b)
With https://github.com/swc-project/plugins/pull/196 being landed, we
can add different transform rules for specific names in the import. For
example, for `lucide-react` there're now 3 transforms:
- `'Lucide(.*)': ...`
- `'(.*)Icon': ...`
- `'*': ...`
On top of that, another critical change made in this PR is the
introducing of `modularize-import-loader`. With this new loader, we can
delegate the task of re-exporting the value to Webpack, where we can
adjust the type of the export and the target path. This is very
necessary and can't be done in SWC alone because libs like
`lucide-react` is using `.mjs` and don't have `exports` values for the
individual icons in the package.json files.
Because of that, if we simply transform the expression to `import Icon
from 'lucide-react/esm/icons/foo` it will fail because:
1. It's missing a `.mjs` extension
2. It doesn't have `/esm/icons/foo.mjs` in package.json `exports`
For 1), in fact that they moved to `.mjs` only in a recent upgrade so we
can't even hard code it to be `.mjs` in the transform (breaks old
versions).
Because of all the above, I decided to go with Webpack's own resolution
logic with the loader as a _temporary_ solution. It's temporary because
it's still assuming that the file structure of these libs doesn't
change.
This uses an IPC server (if available) for incremental cache methods to help prevent race conditions when reading/writing from cache and also to dedupe requests in cases where multiple cache reads are in flight. This cuts down on data fetching across the different build-time workers.
Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com>