Skip to content

Commit

Permalink
Merge branch 'canary' into bugfix/middleware-only
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Nov 15, 2021
2 parents 5174e88 + 66d9b4e commit 4342fa2
Show file tree
Hide file tree
Showing 36 changed files with 183 additions and 180 deletions.
5 changes: 3 additions & 2 deletions .eslintrc.json
Expand Up @@ -30,14 +30,15 @@
},
"overrides": [
{
"files": ["test/**/*.test.js"],
"files": ["test/**/*.js", "test/**/*.ts", "**/*.test.ts"],
"extends": ["plugin:jest/recommended"],
"rules": {
"jest/expect-expect": "off",
"jest/no-disabled-tests": "off",
"jest/no-conditional-expect": "off",
"jest/valid-title": "off",
"jest/no-interpolation-in-snapshots": "off"
"jest/no-interpolation-in-snapshots": "off",
"jest/no-export": "off"
}
},
{ "files": ["**/__tests__/**"], "env": { "jest": true } },
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Expand Up @@ -17,5 +17,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "12.0.4-canary.13"
"version": "12.0.4-canary.14"
}
2 changes: 1 addition & 1 deletion packages/create-next-app/package.json
@@ -1,6 +1,6 @@
{
"name": "create-next-app",
"version": "12.0.4-canary.13",
"version": "12.0.4-canary.14",
"keywords": [
"react",
"next",
Expand Down
4 changes: 2 additions & 2 deletions packages/eslint-config-next/package.json
@@ -1,6 +1,6 @@
{
"name": "eslint-config-next",
"version": "12.0.4-canary.13",
"version": "12.0.4-canary.14",
"description": "ESLint configuration used by NextJS.",
"main": "index.js",
"license": "MIT",
Expand All @@ -9,7 +9,7 @@
"directory": "packages/eslint-config-next"
},
"dependencies": {
"@next/eslint-plugin-next": "12.0.4-canary.13",
"@next/eslint-plugin-next": "12.0.4-canary.14",
"@rushstack/eslint-patch": "^1.0.6",
"@typescript-eslint/parser": "^4.20.0",
"eslint-import-resolver-node": "^0.3.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-next/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/eslint-plugin-next",
"version": "12.0.4-canary.13",
"version": "12.0.4-canary.14",
"description": "ESLint plugin for NextJS.",
"main": "lib/index.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-bundle-analyzer/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/bundle-analyzer",
"version": "12.0.4-canary.13",
"version": "12.0.4-canary.14",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-codemod/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/codemod",
"version": "12.0.4-canary.13",
"version": "12.0.4-canary.14",
"license": "MIT",
"dependencies": {
"chalk": "4.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-env/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/env",
"version": "12.0.4-canary.13",
"version": "12.0.4-canary.14",
"keywords": [
"react",
"next",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-mdx/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/mdx",
"version": "12.0.4-canary.13",
"version": "12.0.4-canary.14",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-storybook/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-storybook",
"version": "12.0.4-canary.13",
"version": "12.0.4-canary.14",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-storybook"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-module/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-module",
"version": "12.0.4-canary.13",
"version": "12.0.4-canary.14",
"description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)",
"main": "dist/polyfill-module.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-nomodule/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-nomodule",
"version": "12.0.4-canary.13",
"version": "12.0.4-canary.14",
"description": "A polyfill for non-dead, nomodule browsers.",
"main": "dist/polyfill-nomodule.js",
"license": "MIT",
Expand Down
1 change: 1 addition & 0 deletions packages/next/build/entries.ts
Expand Up @@ -162,6 +162,7 @@ export function createEntrypoints(
page,
absoluteAppPath: pages['/_app'],
absoluteDocumentPath: pages['/_document'],
absoluteErrorPath: pages['/_error'],
absolutePagePath,
isServerComponent: isFlight,
buildId,
Expand Down
Expand Up @@ -5,6 +5,7 @@ export default async function middlewareRSCLoader(this: any) {
absolutePagePath,
absoluteAppPath,
absoluteDocumentPath,
absoluteErrorPath,
basePath,
isServerComponent: isServerComponentQuery,
assetPrefix,
Expand All @@ -14,23 +15,28 @@ export default async function middlewareRSCLoader(this: any) {
const isServerComponent = isServerComponentQuery === 'true'
const stringifiedAbsolutePagePath = stringifyRequest(this, absolutePagePath)
const stringifiedAbsoluteAppPath = stringifyRequest(this, absoluteAppPath)
const stringifiedAbsoluteErrorPath = stringifyRequest(this, absoluteErrorPath)
const stringified500PagePath = stringifyRequest(this, './pages/500')
const stringifiedAbsoluteDocumentPath = stringifyRequest(
this,
absoluteDocumentPath
)

let appDefinition = `const App = require(${stringifiedAbsoluteAppPath}).default`
let documentDefinition = `const Document = require(${stringifiedAbsoluteDocumentPath}).default`

const transformed = `
import { adapter } from 'next/dist/server/web/adapter'
import { RouterContext } from 'next/dist/shared/lib/router-context'
import { renderToHTML } from 'next/dist/server/web/render'
${appDefinition}
${documentDefinition}
import App from ${stringifiedAbsoluteAppPath}
import Document from ${stringifiedAbsoluteDocumentPath}
let ErrorPage
try {
ErrorPage = require(${stringified500PagePath}).default
} catch (_) {
ErrorPage = require(${stringifiedAbsoluteErrorPath}).default
}
const {
default: Page,
config,
Expand Down Expand Up @@ -66,6 +72,7 @@ export default async function middlewareRSCLoader(this: any) {
}
delete query.__flight__
const req = { url: pathname }
const renderOpts = {
Component,
pageConfig: config || {},
Expand Down Expand Up @@ -97,32 +104,51 @@ export default async function middlewareRSCLoader(this: any) {
const transformStream = new TransformStream()
const writer = transformStream.writable.getWriter()
const encoder = new TextEncoder()
let result
let renderError
let statusCode = 200
try {
const result = await renderToHTML(
{ url: pathname },
result = await renderToHTML(
req,
{},
pathname,
query,
renderOpts
)
result.pipe({
write: str => writer.write(encoder.encode(str)),
end: () => writer.close(),
// Not implemented: cork/uncork/on/removeListener
})
} catch (err) {
return new Response(
(err || 'An error occurred while rendering ' + pathname + '.').toString(),
{
status: 500,
headers: { 'x-middleware-ssr': '1' }
}
)
renderError = err
statusCode = 500
}
if (renderError) {
try {
const errorRes = { statusCode, err: renderError }
result = await renderToHTML(
req,
errorRes,
pathname,
query,
{ ...renderOpts, Component: ErrorPage }
)
} catch (err) {
return new Response(
(err || 'An error occurred while rendering ' + pathname + '.').toString(),
{
status: 500,
headers: { 'x-middleware-ssr': '1' }
}
)
}
}
result.pipe({
write: str => writer.write(encoder.encode(str)),
end: () => writer.close(),
// Not implemented: cork/uncork/on/removeListener
})
return new Response(transformStream.readable, {
headers: { 'x-middleware-ssr': '1' }
headers: { 'x-middleware-ssr': '1' },
status: statusCode
})
}
Expand Down
12 changes: 6 additions & 6 deletions packages/next/package.json
@@ -1,6 +1,6 @@
{
"name": "next",
"version": "12.0.4-canary.13",
"version": "12.0.4-canary.14",
"description": "The React Framework",
"main": "./dist/server/next.js",
"license": "MIT",
Expand Down Expand Up @@ -70,10 +70,10 @@
"@babel/runtime": "7.15.4",
"@hapi/accept": "5.0.2",
"@napi-rs/triples": "1.0.3",
"@next/env": "12.0.4-canary.13",
"@next/polyfill-module": "12.0.4-canary.13",
"@next/react-dev-overlay": "12.0.4-canary.13",
"@next/react-refresh-utils": "12.0.4-canary.13",
"@next/env": "12.0.4-canary.14",
"@next/polyfill-module": "12.0.4-canary.14",
"@next/react-dev-overlay": "12.0.4-canary.14",
"@next/react-refresh-utils": "12.0.4-canary.14",
"acorn": "8.5.0",
"assert": "2.0.0",
"browserify-zlib": "0.2.0",
Expand Down Expand Up @@ -156,7 +156,7 @@
"@babel/traverse": "7.15.0",
"@babel/types": "7.15.0",
"@napi-rs/cli": "1.2.1",
"@next/polyfill-nomodule": "12.0.4-canary.13",
"@next/polyfill-nomodule": "12.0.4-canary.14",
"@peculiar/webcrypto": "1.1.7",
"@taskr/clear": "1.1.0",
"@taskr/esnext": "1.1.0",
Expand Down
1 change: 1 addition & 0 deletions packages/next/server/dev/hot-reloader.ts
Expand Up @@ -528,6 +528,7 @@ export default class HotReloader {
page,
absoluteAppPath: this.pagesMapping['/_app'],
absoluteDocumentPath: this.pagesMapping['/_document'],
absoluteErrorPath: this.pagesMapping['/_error'],
absolutePagePath,
isServerComponent,
buildId: this.buildId,
Expand Down
6 changes: 3 additions & 3 deletions packages/next/server/dev/next-dev-server.ts
Expand Up @@ -34,7 +34,7 @@ import Server, {
FindComponentsResult,
} from '../next-server'
import { normalizePagePath } from '../normalize-page-path'
import Router, { Params, route } from '../router'
import Router, { hasBasePath, Params, replaceBasePath, route } from '../router'
import { eventCliSession } from '../../telemetry/events'
import { Telemetry } from '../../telemetry/storage'
import { setGlobal } from '../../trace'
Expand Down Expand Up @@ -543,11 +543,11 @@ export default class DevServer extends Server {
const { basePath } = this.nextConfig
let originalPathname: string | null = null

if (basePath && parsedUrl.pathname?.startsWith(basePath)) {
if (basePath && hasBasePath(parsedUrl.pathname || '/', basePath)) {
// strip basePath before handling dev bundles
// If replace ends up replacing the full url it'll be `undefined`, meaning we have to default it to `/`
originalPathname = parsedUrl.pathname
parsedUrl.pathname = parsedUrl.pathname!.slice(basePath.length) || '/'
parsedUrl.pathname = replaceBasePath(parsedUrl.pathname || '/', basePath)
}

const { pathname } = parsedUrl
Expand Down
3 changes: 2 additions & 1 deletion packages/next/server/next-server.ts
Expand Up @@ -67,6 +67,7 @@ import Router, {
DynamicRoutes,
PageChecker,
Params,
replaceBasePath,
route,
Route,
} from './router'
Expand Down Expand Up @@ -369,7 +370,7 @@ export default class Server {
})

if (url.basePath) {
req.url = req.url!.replace(this.nextConfig.basePath, '') || '/'
req.url = replaceBasePath(req.url!, this.nextConfig.basePath)
addRequestMeta(req, '_nextHadBasePath', true)
}

Expand Down
25 changes: 19 additions & 6 deletions packages/next/server/router.ts
Expand Up @@ -44,9 +44,22 @@ export type PageChecker = (pathname: string) => Promise<boolean>

const customRouteTypes = new Set(['rewrite', 'redirect', 'header'])

function replaceBasePath(basePath: string, pathname: string) {
// If replace ends up replacing the full url it'll be `undefined`, meaning we have to default it to `/`
return pathname!.replace(basePath, '') || '/'
export function hasBasePath(pathname: string, basePath: string): boolean {
return (
typeof pathname === 'string' &&
(pathname === basePath || pathname.startsWith(basePath + '/'))
)
}

export function replaceBasePath(pathname: string, basePath: string): string {
// ensure basePath is only stripped if it matches exactly
// and doesn't contain extra chars e.g. basePath /docs
// should replace for /docs, /docs/, /docs/a but not /docsss
if (hasBasePath(pathname, basePath)) {
pathname = pathname.substr(basePath.length)
if (!pathname.startsWith('/')) pathname = `/${pathname}`
}
return pathname
}

export default class Router {
Expand Down Expand Up @@ -142,7 +155,7 @@ export default class Router {

const applyCheckTrue = async (checkParsedUrl: NextUrlWithParsedQuery) => {
const originalFsPathname = checkParsedUrl.pathname
const fsPathname = replaceBasePath(this.basePath, originalFsPathname!)
const fsPathname = replaceBasePath(originalFsPathname!, this.basePath)

for (const fsRoute of this.fsRoutes) {
const fsParams = fsRoute.match(fsPathname)
Expand Down Expand Up @@ -283,8 +296,8 @@ export default class Router {
const keepLocale = isCustomRoute

const currentPathnameNoBasePath = replaceBasePath(
this.basePath,
currentPathname
currentPathname,
this.basePath
)

if (!keepBasePath) {
Expand Down
3 changes: 2 additions & 1 deletion packages/next/server/web/next-url.ts
Expand Up @@ -2,6 +2,7 @@ import type { PathLocale } from '../../shared/lib/i18n/normalize-locale-path'
import type { DomainLocale, I18NConfig } from '../config-shared'
import { getLocaleMetadata } from '../../shared/lib/i18n/get-locale-metadata'
import cookie from 'next/dist/compiled/cookie'
import { replaceBasePath } from '../router'

/**
* TODO
Expand Down Expand Up @@ -48,7 +49,7 @@ export class NextURL extends URL {
const { headers = {}, basePath, i18n } = this._options

if (basePath && this._url.pathname.startsWith(basePath)) {
this._url.pathname = this._url.pathname.replace(basePath, '') || '/'
this._url.pathname = replaceBasePath(this._url.pathname, basePath)
this._basePath = basePath
} else {
this._basePath = ''
Expand Down
5 changes: 4 additions & 1 deletion packages/next/shared/lib/i18n/normalize-locale-path.ts
Expand Up @@ -21,7 +21,10 @@ export function normalizeLocalePath(
const pathnameParts = pathname.split('/')

;(locales || []).some((locale) => {
if (pathnameParts[1].toLowerCase() === locale.toLowerCase()) {
if (
pathnameParts[1] &&
pathnameParts[1].toLowerCase() === locale.toLowerCase()
) {
detectedLocale = locale
pathnameParts.splice(1, 1)
pathname = pathnameParts.join('/') || '/'
Expand Down

0 comments on commit 4342fa2

Please sign in to comment.