When creating an NFT file in
https://github.com/vercel/next.js/pull/98003, I store a generic list of
"base" paths and then construct the final path in the JSON file as
relative to the base path. For most files, these paths are relative to
the `*.nft.json` file, but for additional roots, this base path is
always an empty string (relative to the root of the filesystem), so
being able to re-use the original `RcStr` instead of constructing a
brand new string may be beneficial.
This also moves the unit tests to be colocated next to the functions
that are actually being tested.
Thus far, it wasn't possible to use `require()` in a template file with
Webpack.
But I needed to add a `if(NEXT_RUNTIME !== "edge") { const x =
require("../../something"); }`
Turbopack doesn't do any regex rewrite hacks, so this just worked
This gets `cargo doc` clean, and enables it in CI so that we won't regress it (I'm open to removing this if it proves to be annoying).
I also cleaned up some documentation and even found some dead code (deleted `turbopack/crates/turbopack-dev-server/src/source/conditional.rs`).
### What?
This PR wires custom `cacheHandler` / `cacheHandlers` through the
remaining edge entrypoints so edge app pages, edge app routes, edge
pages SSR, middleware, and edge API routes can all see the configured
handlers.
It also adds an e2e regression suite covering:
- pages-router ISR revalidation with a custom incremental cache handler
- app-router cache handlers with cache components enabled
- edge app page + edge app route wiring when cache components are
disabled
### Why?
We already support custom cache handlers in non-edge paths, but several
edge code paths were not forwarding that configuration into the
generated entrypoints/runtime wrappers. That meant custom cache handlers
could be skipped in edge rendering and edge route execution, and we did
not have regression coverage around those cases.
### How?
- pass `cacheHandler` / `cacheHandlers` through the JS build entry
plumbing for edge server entries
- inject cache handler imports/registration into the webpack edge
templates and loaders
- mirror the same wiring in the Turbopack/Rust entry generation for edge
app pages, app routes, pages SSR, and middleware
- update the edge route wrapper to initialize and register cache
handlers before invoking the route module
- extend `next-taskless` template expansion with raw injection support
so the generated edge templates can add imports and registration code
- add `test/e2e/cache-handlers-upstream-wiring` fixtures to cover
pages/app, edge/non-edge, and revalidation behavior
Added a new `rspack` directory as an independent Rust and pnpm
workspace, dedicated to building Next.js Rspack bindings. It shares code
with Turbopack through the `next-taskless` crate.
SSR data is a special module context for development usecases to help with HMR of pages router pages. This allows us to transform pages to strip the Component export, then the dev server can tell the difference between server side and client side changes which informs what kind of refresh we need to do.
Instead, create a new `ReferenceEntrySubType` and configure the `export stripping` transform to trigger using that. This is a better approach since we only need to transform that module instead of putting a lot of dependencies in the new module-context and assert layer.
This should be a development time performance improvement for pages router
Finally delete a number of the `_runtime_entries` functions for server contexts. These were always empty and were a user of the `ServerContextType::PagesData` enum varient that was being deleted.
Closes PACK-4155
## Goal
With three different bundlers, we're often forced to duplicate next.js-specific logic and configuration across two or three different bundlers.
E.g. https://github.com/SyMind/next-rspack-binding/ would cause us to duplicate our current externals logic across all three.
To help, we'd like to have a shared crate that can be used in a few different ways:
- Via turbopack (which is itself called through native napi bindings)
- Via direct native napi bindings to JS for webpack
- Via wasm bindings to JS for webpack [*(note: ideally these would be replaced with napi's recent wasm support, but it doesn't make sense to do that until after the napi v3 migration is done)*](https://napi.rs/blog/announce-v3#webassembly)
- Via Rspack (we'd build a custom binary)
The wasm bindings (in their current state) and Rspack cannot (or should not) depend on `turbo-tasks`. However, all of the current `next-*` crates depend on `turbo-tasks`.
This introduces a `next-taskless` crate for code that can be isolated from performing IO and that does not need to depend on `turbo-tasks`. Code in this crate can be used from wasm or Rspack.
## This PR
As a proof-of-concept, this deduplicates our next.js entrypoint templating logic across webpack and Turbopack. It's a large function that doesn't need to directly depend on file IO.
Some path manipulation had to be moved out of `turbo-tasks-fs` to support this, so that code is in `turbo-unix-path`.
I'm happy to accept different bikeshedded crate names.
## Testing
Tested wasm with:
```
pnpm i
pnpm swc-build-wasm --target nodejs
pnpm build
NODE_TEST_MODE=start NEXT_TEST_WASM=true NEXT_SKIP_NATIVE_POSTINSTALL=1 NEXT_TEST_PREFER_OFFLINE=1 node run-tests.js test/production/pages-dir/production/test/index.test.ts
```
Tested turbopack with:
```
pnpm i
pnpm swc-build-native
pnpm build
pnpm test-start-turbo test/production/pages-dir/production/test/index.test.ts
```
Tested webpack with:
```
pnpm i
pnpm swc-build-native
pnpm build
pnpm test-start test/production/pages-dir/production/test/index.test.ts
```