In #80281 we moved the README from
`../../packages/next/src/client/components/react-dev-overlay/README.md`
to `packages/next/src/next-devtools/README.md`, but did not update the
link in the contributing guide.
### What?
Adds a `--deployable-tar` option to `pack-next` that writes generated
tarballs into the target project and patches package references to use
relative `file:` paths.
### Why?
Projects that need to deploy with locally packed Next.js packages should
be able to include those tarballs inside the project directory instead
of referencing tarballs from the Next.js checkout.
### How?
Resolves the target project package.json location, writes tarballs to a
sibling `tarballs/` directory, and maps package override paths to
project-relative references when patching package.json. Existing `--tar`
behavior continues to write to the repository tarballs directory.
### Verification
- `git diff --check`
- `git diff --cached --check`
- `pnpm prettier --with-node-modules --ignore-path .prettierignore
--write scripts/pack-next.ts scripts/pack-utils/patch-package-json.ts
contributing/core/testing.md contributing/core/developing.md`
- `npx eslint --config eslint.config.mjs --fix scripts/pack-next.ts
scripts/pack-utils/patch-package-json.ts contributing/core/testing.md
contributing/core/developing.md` (Markdown files were ignored because no
matching ESLint config was supplied)
- `pnpm pack-next --project ../sandbox/nextjs-duplicated-html-repro/
--deployable-tar`
<!-- NEXT_JS_LLM_PR -->
@wbinnssmith added these scripts a long time ago at my suggestion/urging, but I think they ended up bad for a couple reasons that were hard to foresee at the time:
- afsctool operates in-place and doesn't atomically write the compressed file, so if the process gets interrupted, your `target` directory is corrupted. https://github.com/Dr-Emann/applesauce is better for this reason.
- This doesn't acquire the cargo lock, and modifying files while cargo is running is a good way to get corruption of the `target` directory.
https://github.com/bgw/cargo-apfs-compress is my latest attempt at solving this, though I don't have a `LaunchAgents` config for it.
Regarding `node_modules`: pnpm creates reflinks from a shared global store on apfs. Trying to compress these reflinked files is just going to hurt you because it'll break the data deduplication that would've otherwise happened.
When running `next build --debug-prerender`, React owner stacks are now
captured and displayed in prerender error output. This makes it much
easier to diagnose which component triggered uncached I/O or accessed
request data without Suspense. Previously, `--debug-prerender` only
enabled source maps and disabled minification. Now it also auto-enables
`allowDevelopmentBuild` and sets `NODE_ENV=development`, which loads
React development builds where `captureOwnerStack()` is available.
The main challenge is that with `NODE_ENV=development`, both server and
client bundles include dev-only code paths (HMR, WebSocket connections,
dev overlay, debug channel, etc.) that expect a running dev server. We
don't want these when using `next start`. To solve this, we introduce
`process.env.__NEXT_DEV_SERVER`, an internal env var that is truthy only
during `next dev`. In client bundles, it's inlined at build time (`'1'`
for `next dev`, `''` for `next build`). In production server runtime
bundles, it's inlined as `''` for dead-code elimination. In development
server runtime bundles, it's left as a runtime check because those
bundles are shared between `next dev` (where it's set) and `next build
--debug-prerender` (where it's not). Meanwhile, `NODE_ENV` continues to
control React's dev/prod mode and error formatting, which is exactly
what we want for `--debug-prerender`.
This also replaces the previous `renderOpts.dev` / `workStore.dev`
pattern, which was unreliable because `RouteModule.isDev` was derived
from `NODE_ENV` at compile time. When `allowDevelopmentBuild` set
`NODE_ENV=development`, `isDev` would be compiled as `true` and
incorrectly activate all dev guards during `next start`.
Key changes:
- `config.ts` auto-enables `allowDevelopmentBuild` and sets
`NODE_ENV=development` when `--debug-prerender` is active
- `define-env.ts` inlines `__NEXT_DEV_SERVER` into all bundles (truthy
for dev, falsy for build) so dev-server features are dead-code
eliminated in production and `--debug-prerender` builds
- `next-dev.ts` and `next.ts` set `__NEXT_DEV_SERVER` in the process
environment for externalized server-side code
- `renderOpts.dev` and `workStore.dev` are removed — all consumers now
use `__NEXT_DEV_SERVER` (for dev-server features) or `NODE_ENV` (for
error formatting that should work in both dev and `--debug-prerender`
builds)
- `patch-error-inspect.ts` devirtualizes React server URLs in source map
URLs so they display as readable file paths
Noticed this after rebuilding on top of #71688
Most Linux distributions default to `gcc` for their default `cc`
implementation (e.g. via Debian's `build-essential` meta-package, which
we can probably implicitly assume is installed), which means that they
won't typically have `clang` installed.
`librocksdb-sys` seems to always depend on `clang` on Linux. It looks
like this might be a consequence of using
[rust-bindgen](https://github.com/rust-lang/rust-bindgen) (though I'm
confused why this didn't come up earlier), as it looks like rocksdb can
otherwise build with gcc.
This shouldn't be an issue for macos, since `clang` is the default `cc`
on that platform.
### What?
Ports a few more useful scripts from nextpack, namely:
- `patch-next`
- `sweep`
- `build-native` (to clean up incremental artifacts on compiler panics)
- the macOS compression agent
Copies changes from https://github.com/vercel/turbo/pull/8166, and
updates contributing documentation to include the installation of lld.
> **What's wrong with `ld`?** It's very slow and uses a lot of memory.
>
> **Why `lld`?** It's fast, mature, and well-supported. Meta and Google
use it for all their linking workloads. We're already using it for macos
and x86-64 Windows. There is [ongoing work to make it the default for
rustc](https://github.com/rust-lang/rust/issues/71515), and it already
is default on a few platforms.
>
> **Why not `mold`?** Mold is generally faster, but the margin is slim
enough for our workloads that it doesn't really matter. Mold only
recently got support for LTO, doesn't support v0 rust symbol demanging,
doesn't support BOLT (though we don't use that yet), etc. Mold is
maturing quickly, but `lld` still seems like the "safer" choice.
This brings over the utility scripts `pnpm pack-next` and `pnpm
unpack-next path/to/app` from Nextpack, along with the documentation,
which has been added to `contributing/core/developing.md`.
GitHub recommends blobless clones over shallow clones:
https://github.blog/2020-12-21-get-up-to-speed-with-partial-clone-and-shallow-clone/
> For these reasons we do not recommend shallow clones except for builds
that delete the repository immediately afterwards. Fetching from shallow
clones can cause more harm than good!
I've been using blobless clones for development for the last couple
weeks. The blobless clone has the benefit of including the full
repository history (for the cloned branch). Tools like `git blame` will
be slower as git fetches the related blobs on-demand.
Benchmarks (using all the flags in the docs):
- The blobless clone is faster on my machine, taking 11.1 seconds versus
13.1 seconds for the shallow clone.
- The blobless clone takes up 256M on disk, versus 244M for the shallow
clone. It's worse, but not by much.
Continues #39778Closes#40499
## Bug
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`
## Feature
- [ ] Implements an existing feature request or RFC. Make sure the
feature request has been accepted for implementation before opening a
PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`
## Documentation / Examples
- [ ] Make sure the linting passes by running `pnpm lint`
- [ ] The examples guidelines are followed from [our contributing
doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples)
Co-authored-by: Tim Neutkens <tim@timneutkens.nl>
Co-authored-by: JJ Kasper <jj@jjsweb.site>