Skip to content

Commit

Permalink
Gate alternate bundler behind canary only (#76634)
Browse files Browse the repository at this point in the history
This restricts rspack to only be used with canary builds, and updates
the plugin’s readme to note this, along with its experimental state.

Test Plan: Made a custom build with a `__NEXT_VERSION` of `15.2.0` and
verified builds failed with the canary-only message.

---------

Co-authored-by: Zack Tanner <1939140+ztanner@users.noreply.github.com>
  • Loading branch information
wbinnssmith and ztanner authored Feb 28, 2025
1 parent 93a43ee commit 80fbbc2
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 22 deletions.
5 changes: 4 additions & 1 deletion packages/next-plugin-rspack/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# @next/plugin-rspack
# @next/plugin-rspack (EXPERIMENTAL)

> [!WARNING]
> This package is currently experimental and actively developed and supported in Next.js’ `canary` branch. To use this, you must be using a published canary build of Next.js.
This plugin allows you to use [Rspack](https://rspack.dev) in place of webpack with Next.js.

Expand Down
3 changes: 2 additions & 1 deletion packages/next/errors.json
Original file line number Diff line number Diff line change
Expand Up @@ -657,5 +657,6 @@
"656": "If providing both the revalidate and expire options, the expire option must be greater than the revalidate option. The expire option indicates how many seconds from the start until it can no longer be used.",
"657": "revalidate must be a number for image-cache",
"658": "Pass `Infinity` instead of `false` if you want to cache on the server forever without checking with the origin.",
"659": "SSG should not return an image cache value"
"659": "SSG should not return an image cache value",
"660": "Rspack support is only available in Next.js canary."
}
28 changes: 8 additions & 20 deletions packages/next/src/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { dset } from '../shared/lib/dset'
import { normalizeZodErrors } from '../shared/lib/zod'
import { HTML_LIMITED_BOT_UA_RE_STRING } from '../shared/lib/router/utils/is-bot'
import { findDir } from '../lib/find-pages-dir'
import { CanaryOnlyError, isStableBuild } from '../shared/lib/canary-only'

export { normalizeConfig } from './config-shared'
export type { DomainLocale, NextConfig } from './config-shared'
Expand Down Expand Up @@ -244,20 +245,18 @@ function assignDefaults(
)
}

if (
!process.env.__NEXT_VERSION?.includes('canary') &&
!process.env.__NEXT_TEST_MODE &&
!process.env.NEXT_PRIVATE_LOCAL_DEV
) {
if (isStableBuild()) {
// Prevents usage of certain experimental features outside of canary
if (result.experimental?.ppr) {
throw new CanaryOnlyError('experimental.ppr')
throw new CanaryOnlyError({ feature: 'experimental.ppr' })
} else if (result.experimental?.dynamicIO) {
throw new CanaryOnlyError('experimental.dynamicIO')
throw new CanaryOnlyError({ feature: 'experimental.dynamicIO' })
} else if (result.experimental?.turbo?.unstablePersistentCaching) {
throw new CanaryOnlyError('experimental.turbo.unstablePersistentCaching')
throw new CanaryOnlyError({
feature: 'experimental.turbo.unstablePersistentCaching',
})
} else if (result.experimental?.nodeMiddleware) {
throw new CanaryOnlyError('experimental.nodeMiddleware')
throw new CanaryOnlyError({ feature: 'experimental.nodeMiddleware' })
}
}

Expand Down Expand Up @@ -1370,14 +1369,3 @@ export function getConfiguredExperimentalFeatures(
}
return configuredExperimentalFeatures
}

class CanaryOnlyError extends Error {
constructor(feature: string) {
super(
`The experimental feature "${feature}" can only be enabled when using the latest canary version of Next.js.`
)
// This error is meant to interrupt the server start/build process
// but the stack trace isn't meaningful, as it points to internal code.
this.stack = undefined
}
}
23 changes: 23 additions & 0 deletions packages/next/src/shared/lib/canary-only.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export function isStableBuild() {
return (
!process.env.__NEXT_VERSION?.includes('canary') &&
!process.env.__NEXT_TEST_MODE &&
!process.env.NEXT_PRIVATE_LOCAL_DEV
)
}

export class CanaryOnlyError extends Error {
constructor(arg: { feature: string } | string) {
if (typeof arg === 'object' && 'feature' in arg) {
super(
`The experimental feature "${arg.feature}" can only be enabled when using the latest canary version of Next.js.`
)
} else {
super(arg)
}

// This error is meant to interrupt the server start/build process
// but the stack trace isn't meaningful, as it points to internal code.
this.stack = undefined
}
}
12 changes: 12 additions & 0 deletions packages/next/src/shared/lib/get-rspack.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { CanaryOnlyError, isStableBuild } from './canary-only'

export function getRspackCore() {
gateCanary()
try {
// eslint-disable-next-line import/no-extraneous-dependencies
return require('@rspack/core')
Expand All @@ -14,6 +17,7 @@ export function getRspackCore() {
}

export function getRspackReactRefresh() {
gateCanary()
try {
// eslint-disable-next-line import/no-extraneous-dependencies
return require('@rspack/plugin-react-refresh')
Expand All @@ -27,3 +31,11 @@ export function getRspackReactRefresh() {
throw e
}
}

function gateCanary() {
if (isStableBuild()) {
throw new CanaryOnlyError(
'Rspack support is only available in Next.js canary.'
)
}
}

0 comments on commit 80fbbc2

Please sign in to comment.