refactor: move HtmlContext
(#34482)
The shared utils file included an import from `react` (because it was using `createContext`) which seems to be unnecessary in the Middleware bundle. With this PR and steps #34425 laid out, the bundle size did decrease without breaking functionality. ![image](https://user-images.githubusercontent.com/18369201/154508389-0a813e3e-1e07-4c45-8b71-444cc54a7f9e.png) Fixes #34425 ## 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 `yarn lint`
This commit is contained in:
parent
d4eea7593a
commit
eddabd98f8
6 changed files with 85 additions and 81 deletions
|
@ -1,11 +1,9 @@
|
|||
import React, { Component, ReactElement, ReactNode, useContext } from 'react'
|
||||
import { OPTIMIZED_FONT_PROVIDERS } from '../shared/lib/constants'
|
||||
import {
|
||||
import type {
|
||||
DocumentContext,
|
||||
DocumentInitialProps,
|
||||
DocumentProps,
|
||||
HtmlContext,
|
||||
HtmlProps,
|
||||
} from '../shared/lib/utils'
|
||||
import { BuildManifest, getPageFiles } from '../server/get-page-files'
|
||||
import { cleanAmpPath } from '../server/utils'
|
||||
|
@ -13,6 +11,9 @@ import { htmlEscapeJsonString } from '../server/htmlescape'
|
|||
import Script, { ScriptProps } from '../client/script'
|
||||
import isError from '../lib/is-error'
|
||||
|
||||
import { HtmlContext } from '../shared/lib/html-context'
|
||||
import type { HtmlProps } from '../shared/lib/html-context'
|
||||
|
||||
export { DocumentContext, DocumentInitialProps, DocumentProps }
|
||||
|
||||
export type OriginProps = {
|
||||
|
|
|
@ -37,8 +37,6 @@ import {
|
|||
DocumentInitialProps,
|
||||
DocumentProps,
|
||||
DocumentContext,
|
||||
HtmlContext,
|
||||
HtmlProps,
|
||||
getDisplayName,
|
||||
isResSent,
|
||||
loadGetInitialProps,
|
||||
|
@ -46,6 +44,10 @@ import {
|
|||
RenderPage,
|
||||
RenderPageResult,
|
||||
} from '../shared/lib/utils'
|
||||
|
||||
import { HtmlContext } from '../shared/lib/html-context'
|
||||
import type { HtmlProps } from '../shared/lib/html-context'
|
||||
|
||||
import type { NextApiRequestCookies, __ApiPreviewProps } from './api-utils'
|
||||
import { denormalizePagePath } from './denormalize-page-path'
|
||||
import type { FontManifest } from './font-utils'
|
||||
|
|
42
packages/next/shared/lib/html-context.ts
Normal file
42
packages/next/shared/lib/html-context.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import type { BuildManifest } from '../../server/get-page-files'
|
||||
import type { NEXT_DATA, MaybeDeferContentHook } from './utils'
|
||||
|
||||
import { createContext } from 'react'
|
||||
|
||||
export type HtmlProps = {
|
||||
__NEXT_DATA__: NEXT_DATA
|
||||
dangerousAsPath: string
|
||||
docComponentsRendered: {
|
||||
Html?: boolean
|
||||
Main?: boolean
|
||||
Head?: boolean
|
||||
NextScript?: boolean
|
||||
}
|
||||
buildManifest: BuildManifest
|
||||
ampPath: string
|
||||
inAmpMode: boolean
|
||||
hybridAmp: boolean
|
||||
isDevelopment: boolean
|
||||
dynamicImports: string[]
|
||||
assetPrefix?: string
|
||||
canonicalBase: string
|
||||
headTags: any[]
|
||||
unstable_runtimeJS?: false
|
||||
unstable_JsPreload?: false
|
||||
devOnlyCacheBusterQueryString: string
|
||||
scriptLoader: { afterInteractive?: string[]; beforeInteractive?: any[] }
|
||||
locale?: string
|
||||
disableOptimizedLoading?: boolean
|
||||
styles?: React.ReactElement[] | React.ReactFragment
|
||||
head?: Array<JSX.Element | null>
|
||||
useMaybeDeferContent: MaybeDeferContentHook
|
||||
crossOrigin?: string
|
||||
optimizeCss?: boolean
|
||||
optimizeFonts?: boolean
|
||||
runtime?: 'edge' | 'nodejs'
|
||||
}
|
||||
|
||||
export const HtmlContext = createContext<HtmlProps>(null as any)
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
HtmlContext.displayName = 'HtmlContext'
|
||||
}
|
|
@ -22,7 +22,6 @@ import { normalizeLocalePath } from '../i18n/normalize-locale-path'
|
|||
import mitt from '../mitt'
|
||||
import {
|
||||
AppContextType,
|
||||
formatWithValidation,
|
||||
getLocationOrigin,
|
||||
getURL,
|
||||
loadGetInitialProps,
|
||||
|
@ -38,6 +37,7 @@ import resolveRewrites from './utils/resolve-rewrites'
|
|||
import { getRouteMatcher } from './utils/route-matcher'
|
||||
import { getRouteRegex } from './utils/route-regex'
|
||||
import { getMiddlewareRegex } from './utils/get-middleware-regex'
|
||||
import { formatWithValidation } from './utils/format-url'
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import { UrlObject } from 'url'
|
||||
import { ParsedUrlQuery } from 'querystring'
|
||||
import type { UrlObject } from 'url'
|
||||
import type { ParsedUrlQuery } from 'querystring'
|
||||
import * as querystring from './querystring'
|
||||
|
||||
const slashedProtocols = /https?|ftp|gopher|file/
|
||||
|
@ -71,3 +71,34 @@ export function formatUrl(urlObj: UrlObject) {
|
|||
|
||||
return `${protocol}${host}${pathname}${search}${hash}`
|
||||
}
|
||||
|
||||
export const urlObjectKeys = [
|
||||
'auth',
|
||||
'hash',
|
||||
'host',
|
||||
'hostname',
|
||||
'href',
|
||||
'path',
|
||||
'pathname',
|
||||
'port',
|
||||
'protocol',
|
||||
'query',
|
||||
'search',
|
||||
'slashes',
|
||||
]
|
||||
|
||||
export function formatWithValidation(url: UrlObject): string {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
if (url !== null && typeof url === 'object') {
|
||||
Object.keys(url).forEach((key) => {
|
||||
if (urlObjectKeys.indexOf(key) === -1) {
|
||||
console.warn(
|
||||
`Unknown key passed via urlObject into url.format: ${key}`
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return formatUrl(url)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { BuildManifest } from '../../server/get-page-files'
|
||||
import type { HtmlProps } from './html-context'
|
||||
import type { ComponentType } from 'react'
|
||||
import type { DomainLocale } from '../../server/config'
|
||||
import type { Env } from '@next/env'
|
||||
|
@ -6,9 +6,6 @@ import type { IncomingMessage, ServerResponse } from 'http'
|
|||
import type { NextRouter } from './router/router'
|
||||
import type { ParsedUrlQuery } from 'querystring'
|
||||
import type { PreviewData } from 'next/types'
|
||||
import type { UrlObject } from 'url'
|
||||
import { createContext } from 'react'
|
||||
import { formatUrl } from './router/utils/format-url'
|
||||
|
||||
export type NextComponentType<
|
||||
C extends BaseContext = NextPageContext,
|
||||
|
@ -195,39 +192,6 @@ export type MaybeDeferContentHook = (
|
|||
contentFn: () => JSX.Element
|
||||
) => [boolean, JSX.Element]
|
||||
|
||||
export type HtmlProps = {
|
||||
__NEXT_DATA__: NEXT_DATA
|
||||
dangerousAsPath: string
|
||||
docComponentsRendered: {
|
||||
Html?: boolean
|
||||
Main?: boolean
|
||||
Head?: boolean
|
||||
NextScript?: boolean
|
||||
}
|
||||
buildManifest: BuildManifest
|
||||
ampPath: string
|
||||
inAmpMode: boolean
|
||||
hybridAmp: boolean
|
||||
isDevelopment: boolean
|
||||
dynamicImports: string[]
|
||||
assetPrefix?: string
|
||||
canonicalBase: string
|
||||
headTags: any[]
|
||||
unstable_runtimeJS?: false
|
||||
unstable_JsPreload?: false
|
||||
devOnlyCacheBusterQueryString: string
|
||||
scriptLoader: { afterInteractive?: string[]; beforeInteractive?: any[] }
|
||||
locale?: string
|
||||
disableOptimizedLoading?: boolean
|
||||
styles?: React.ReactElement[] | React.ReactFragment
|
||||
head?: Array<JSX.Element | null>
|
||||
useMaybeDeferContent: MaybeDeferContentHook
|
||||
crossOrigin?: string
|
||||
optimizeCss?: boolean
|
||||
optimizeFonts?: boolean
|
||||
runtime?: 'edge' | 'nodejs'
|
||||
}
|
||||
|
||||
/**
|
||||
* Next `API` route request
|
||||
*/
|
||||
|
@ -410,37 +374,6 @@ export async function loadGetInitialProps<
|
|||
return props
|
||||
}
|
||||
|
||||
export const urlObjectKeys = [
|
||||
'auth',
|
||||
'hash',
|
||||
'host',
|
||||
'hostname',
|
||||
'href',
|
||||
'path',
|
||||
'pathname',
|
||||
'port',
|
||||
'protocol',
|
||||
'query',
|
||||
'search',
|
||||
'slashes',
|
||||
]
|
||||
|
||||
export function formatWithValidation(url: UrlObject): string {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
if (url !== null && typeof url === 'object') {
|
||||
Object.keys(url).forEach((key) => {
|
||||
if (urlObjectKeys.indexOf(key) === -1) {
|
||||
console.warn(
|
||||
`Unknown key passed via urlObject into url.format: ${key}`
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return formatUrl(url)
|
||||
}
|
||||
|
||||
export const SP = typeof performance !== 'undefined'
|
||||
export const ST =
|
||||
SP &&
|
||||
|
@ -449,11 +382,6 @@ export const ST =
|
|||
|
||||
export class DecodeError extends Error {}
|
||||
|
||||
export const HtmlContext = createContext<HtmlProps>(null as any)
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
HtmlContext.displayName = 'HtmlContext'
|
||||
}
|
||||
|
||||
export interface CacheFs {
|
||||
readFile(f: string): Promise<string>
|
||||
readFileSync(f: string): string
|
||||
|
|
Loading…
Reference in a new issue