Skip to content

Commit

Permalink
Replace middleware flag with warning (vercel#30160)
Browse files Browse the repository at this point in the history
Follow-up to vercel#30154 this replaces the experimental flag with a warning that is shown once on usage instead.
  • Loading branch information
ijjk authored Oct 22, 2021
1 parent 7e81d13 commit 67681fe
Show file tree
Hide file tree
Showing 15 changed files with 305 additions and 295 deletions.
13 changes: 13 additions & 0 deletions errors/beta-middleware.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Beta Middleware Used

#### Why This Error Occurred

The middleware feature of Next.js is still in beta so this warning is shown to express that the feature is not yet covered by semver and can experience changes at any point.

#### Possible Ways to Fix It

No fix necessary.

### Useful Links

- [semver documentation](https://semver.org/)
4 changes: 4 additions & 0 deletions errors/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"title": "Messages",
"heading": true,
"routes": [
{
"title": "beta-middleware",
"path": "/errors/beta-middleware.md"
},
{
"title": "custom-document-image-import",
"path": "/errors/custom-document-image-import.md"
Expand Down
2 changes: 1 addition & 1 deletion packages/next/build/entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export function createEntrypoints(

const isLikeServerless = isTargetLikeServerless(target)

if (page.match(MIDDLEWARE_ROUTE) && config.experimental.middleware) {
if (page.match(MIDDLEWARE_ROUTE)) {
const loaderOpts: MiddlewareLoaderOptions = {
absolutePagePath: pages[page],
page,
Expand Down
50 changes: 25 additions & 25 deletions packages/next/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,6 @@ export default async function build(
)
const pageKeys = Object.keys(mappedPages)
const hasMiddleware = pageKeys.some((page) => MIDDLEWARE_ROUTE.test(page))

if (hasMiddleware && !config.experimental.middleware) {
console.warn(
`Warning: detected _middleware page but the "experimental.middleware" config was not enabled. Please enable it in ${config.configFileName}`
)
}

const conflictingPublicFiles: string[] = []
const hasCustomErrorPage: boolean =
mappedPages['/_error'].startsWith('private-next-pages')
Expand All @@ -300,6 +293,15 @@ export default async function build(
mappedPages['/404'].startsWith('private-next-pages')
)

if (hasMiddleware) {
console.warn(
chalk.bold.yellow(`Warning: `) +
chalk.yellow(
`using beta Middleware (not covered by semver) - https://nextjs.org/docs/messages/beta-middleware`
)
)
}

if (hasPublicDir) {
const hasPublicUnderScoreNextDir = await fileExists(
path.join(publicDir, '_next')
Expand Down Expand Up @@ -1718,26 +1720,24 @@ export default async function build(
)
}

if (config.experimental.middleware) {
const middlewareManifest: MiddlewareManifest = JSON.parse(
await promises.readFile(
path.join(distDir, SERVER_DIRECTORY, MIDDLEWARE_MANIFEST),
'utf8'
)
const middlewareManifest: MiddlewareManifest = JSON.parse(
await promises.readFile(
path.join(distDir, SERVER_DIRECTORY, MIDDLEWARE_MANIFEST),
'utf8'
)
)

await promises.writeFile(
path.join(
distDir,
CLIENT_STATIC_FILES_PATH,
buildId,
'_middlewareManifest.js'
),
`self.__MIDDLEWARE_MANIFEST=${devalue(
middlewareManifest.sortedMiddleware
)};self.__MIDDLEWARE_MANIFEST_CB&&self.__MIDDLEWARE_MANIFEST_CB()`
)
}
await promises.writeFile(
path.join(
distDir,
CLIENT_STATIC_FILES_PATH,
buildId,
'_middlewareManifest.js'
),
`self.__MIDDLEWARE_MANIFEST=${devalue(
middlewareManifest.sortedMiddleware
)};self.__MIDDLEWARE_MANIFEST_CB&&self.__MIDDLEWARE_MANIFEST_CB()`
)

const images = { ...config.images }
const { deviceSizes, imageSizes } = images
Expand Down
8 changes: 1 addition & 7 deletions packages/next/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,6 @@ export default async function getBaseWebpackConfig(
parallel: config.experimental.cpus,
swcMinify: config.experimental.swcMinify,
terserOptions,
middlewareEnabled: config.experimental.middleware,
}).apply(compiler)
},
// Minify CSS
Expand Down Expand Up @@ -1197,9 +1196,6 @@ export default async function getBaseWebpackConfig(
}),
'process.env.__NEXT_ROUTER_BASEPATH': JSON.stringify(config.basePath),
'process.env.__NEXT_HAS_REWRITES': JSON.stringify(hasRewrites),
'process.env.__NEXT_HAS_MIDDLEWARE': JSON.stringify(
config.experimental.middleware
),
'process.env.__NEXT_I18N_SUPPORT': JSON.stringify(!!config.i18n),
'process.env.__NEXT_I18N_DOMAINS': JSON.stringify(config.i18n?.domains),
'process.env.__NEXT_ANALYTICS_ID': JSON.stringify(config.analyticsId),
Expand Down Expand Up @@ -1278,9 +1274,7 @@ export default async function getBaseWebpackConfig(
new PagesManifestPlugin({ serverless: isLikeServerless, dev }),
// MiddlewarePlugin should be after DefinePlugin so NEXT_PUBLIC_*
// replacement is done before its process.env.* handling
!isServer &&
config.experimental.middleware &&
new MiddlewarePlugin({ dev }),
!isServer && new MiddlewarePlugin({ dev }),
isServer && new NextJsSsrImportPlugin(),
!isServer &&
new BuildManifestPlugin({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,13 @@ function buildError(error, file) {

export class TerserPlugin {
constructor(options = {}) {
const {
cacheDir,
terserOptions = {},
parallel,
swcMinify,
middlewareEnabled,
} = options
const { cacheDir, terserOptions = {}, parallel, swcMinify } = options

this.options = {
swcMinify,
cacheDir,
parallel,
terserOptions,
middlewareEnabled,
}
}

Expand Down Expand Up @@ -106,17 +99,15 @@ export class TerserPlugin {
}

// remove below if we start minifying middleware chunks
if (this.options.middlewareEnabled) {
if (name.startsWith('static/chunks/webpack-')) {
webpackAsset = name
}
if (name.startsWith('static/chunks/webpack-')) {
webpackAsset = name
}

// don't minify _middleware as it can break in some cases
// and doesn't provide too much of a benefit as it's server-side
if (name.match(/(middleware-chunks|_middleware\.js$)/)) {
hasMiddleware = true
return false
}
// don't minify _middleware as it can break in some cases
// and doesn't provide too much of a benefit as it's server-side
if (name.match(/(middleware-chunks|_middleware\.js$)/)) {
hasMiddleware = true
return false
}

const { info } = res
Expand Down
40 changes: 18 additions & 22 deletions packages/next/client/page-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,31 +85,27 @@ export default class PageLoader {
}

getMiddlewareList(): Promise<string[]> {
if (process.env.__NEXT_HAS_MIDDLEWARE) {
if (process.env.NODE_ENV === 'production') {
return getMiddlewareManifest()
if (process.env.NODE_ENV === 'production') {
return getMiddlewareManifest()
} else {
if ((window as any).__DEV_MIDDLEWARE_MANIFEST) {
return (window as any).__DEV_MIDDLEWARE_MANIFEST
} else {
if ((window as any).__DEV_MIDDLEWARE_MANIFEST) {
return (window as any).__DEV_MIDDLEWARE_MANIFEST
} else {
if (!this.promisedMiddlewareManifest) {
this.promisedMiddlewareManifest = fetch(
`${this.assetPrefix}/_next/static/${this.buildId}/_devMiddlewareManifest.json`
)
.then((res) => res.json())
.then((manifest) => {
;(window as any).__DEV_MIDDLEWARE_MANIFEST = manifest
return manifest
})
.catch((err) => {
console.log(`Failed to fetch _devMiddlewareManifest`, err)
})
}
return this.promisedMiddlewareManifest
if (!this.promisedMiddlewareManifest) {
this.promisedMiddlewareManifest = fetch(
`${this.assetPrefix}/_next/static/${this.buildId}/_devMiddlewareManifest.json`
)
.then((res) => res.json())
.then((manifest) => {
;(window as any).__DEV_MIDDLEWARE_MANIFEST = manifest
return manifest
})
.catch((err) => {
console.log(`Failed to fetch _devMiddlewareManifest`, err)
})
}
return this.promisedMiddlewareManifest
}
} else {
return Promise.resolve([])
}
}

Expand Down
37 changes: 16 additions & 21 deletions packages/next/client/route-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,32 +232,27 @@ export function getClientBuildManifest(): Promise<ClientBuildManifest> {
markAssetError(new Error('Failed to load client build manifest'))
)
}
let _getMiddlewareManifest = () => Promise.resolve([])

if (process.env.__NEXT_HAS_MIDDLEWARE) {
_getMiddlewareManifest = async () => {
if (self.__MIDDLEWARE_MANIFEST) {
return Promise.resolve(self.__MIDDLEWARE_MANIFEST)
}
export function getMiddlewareManifest(): Promise<any> {
if (self.__MIDDLEWARE_MANIFEST) {
return Promise.resolve(self.__MIDDLEWARE_MANIFEST)
}

const onMiddlewareManifest: Promise<any> = new Promise<any>((resolve) => {
const cb = self.__MIDDLEWARE_MANIFEST_CB
self.__MIDDLEWARE_MANIFEST_CB = () => {
resolve(self.__MIDDLEWARE_MANIFEST!)
cb && cb()
}
})
const onMiddlewareManifest: Promise<any> = new Promise<any>((resolve) => {
const cb = self.__MIDDLEWARE_MANIFEST_CB
self.__MIDDLEWARE_MANIFEST_CB = () => {
resolve(self.__MIDDLEWARE_MANIFEST!)
cb && cb()
}
})

return resolvePromiseWithTimeout(
onMiddlewareManifest,
MS_MAX_IDLE_DELAY,
markAssetError(new Error('Failed to load client middleware manifest'))
)
}
return resolvePromiseWithTimeout(
onMiddlewareManifest,
MS_MAX_IDLE_DELAY,
markAssetError(new Error('Failed to load client middleware manifest'))
)
}

export const getMiddlewareManifest = _getMiddlewareManifest

interface RouteFiles {
scripts: string[]
css: string[]
Expand Down
2 changes: 0 additions & 2 deletions packages/next/server/config-shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ export type NextConfig = { [key: string]: any } & {
staticPageGenerationTimeout?: number
crossOrigin?: false | 'anonymous' | 'use-credentials'
experimental?: {
middleware?: boolean
swcMinify?: boolean
swcLoader?: boolean
cpus?: number
Expand Down Expand Up @@ -204,7 +203,6 @@ export const defaultConfig: NextConfig = {
},
staticPageGenerationTimeout: 60,
experimental: {
middleware: false,
swcLoader: false,
swcMinify: false,
cpus: Math.max(
Expand Down
48 changes: 22 additions & 26 deletions packages/next/server/dev/next-dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,12 +265,10 @@ export default class DevServer extends Server {
routedPages.push(pageName)
}

if (this.nextConfig.experimental.middleware) {
this.middleware = getSortedRoutes(routedMiddleware).map((page) => ({
match: getRouteMatcher(getMiddlewareRegex(page)),
page,
}))
}
this.middleware = getSortedRoutes(routedMiddleware).map((page) => ({
match: getRouteMatcher(getMiddlewareRegex(page)),
page,
}))

try {
// we serve a separate manifest with all pages for the client in
Expand Down Expand Up @@ -693,27 +691,25 @@ export default class DevServer extends Server {
},
})

if (this.nextConfig.experimental.middleware) {
fsRoutes.unshift({
match: route(
`/_next/${CLIENT_STATIC_FILES_PATH}/${this.buildId}/${DEV_MIDDLEWARE_MANIFEST}`
),
type: 'route',
name: `_next/${CLIENT_STATIC_FILES_PATH}/${this.buildId}/${DEV_MIDDLEWARE_MANIFEST}`,
fn: async (_req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'application/json; charset=utf-8')
res.end(
JSON.stringify(
this.middleware?.map((middleware) => middleware.page) || []
)
fsRoutes.unshift({
match: route(
`/_next/${CLIENT_STATIC_FILES_PATH}/${this.buildId}/${DEV_MIDDLEWARE_MANIFEST}`
),
type: 'route',
name: `_next/${CLIENT_STATIC_FILES_PATH}/${this.buildId}/${DEV_MIDDLEWARE_MANIFEST}`,
fn: async (_req, res) => {
res.statusCode = 200
res.setHeader('Content-Type', 'application/json; charset=utf-8')
res.end(
JSON.stringify(
this.middleware?.map((middleware) => middleware.page) || []
)
return {
finished: true,
}
},
})
}
)
return {
finished: true,
}
},
})

fsRoutes.push({
match: route('/:path*'),
Expand Down
Loading

0 comments on commit 67681fe

Please sign in to comment.