未验证 提交 e125d905 编写于 作者: T Tim Neutkens 提交者: GitHub

Clean up render.tsx options (#13759)

Went through and removed a bunch of internal options which are just pass-through values of buildManifest

Closes #13851
上级 a89afc2e
......@@ -17,8 +17,6 @@ export type PluginMetaData = {
// currently supported middleware
export const VALID_MIDDLEWARE = [
'document-head-tags-server',
'document-body-tags-server',
'document-html-props-server',
'on-init-client',
'on-init-server',
'on-error-server',
......
......@@ -803,7 +803,7 @@ export default async function getBaseWebpackConfig(
}
}, {}),
'process.env.NODE_ENV': JSON.stringify(webpackMode),
'process.crossOrigin': JSON.stringify(crossOrigin),
'process.env.__NEXT_CROSS_ORIGIN': JSON.stringify(crossOrigin),
'process.browser': JSON.stringify(!isServer),
'process.env.__NEXT_TEST_MODE': JSON.stringify(
process.env.__NEXT_TEST_MODE
......
......@@ -56,6 +56,7 @@ export default class BuildManifestPlugin {
(compilation, callback) => {
const { chunks } = compilation
const assetMap: BuildManifest = {
polyfillFiles: [],
devFiles: [],
lowPriorityFiles: [],
pages: { '/_app': [] },
......@@ -115,7 +116,7 @@ export default class BuildManifestPlugin {
}
// Create a separate entry for polyfills
assetMap.pages['/_polyfills'] = polyfillFiles
assetMap.polyfillFiles = polyfillFiles
// Add the runtime build manifest file (generated later in this file)
// as a dependency for the app. If the flag is false, the file won't be
......
......@@ -21,8 +21,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWAR
// Implementation of this PR: https://github.com/jamiebuilds/react-loadable/pull/132
// Modified to strip out unneeded results for Next's specific use case
import url from 'url'
import {
Compiler,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
......@@ -30,10 +28,9 @@ import {
} from 'webpack'
function buildManifest(
compiler: Compiler,
_compiler: Compiler,
compilation: CompilationType.Compilation
) {
let context = compiler.options.context
let manifest: { [k: string]: any[] } = {}
compilation.chunkGroups.forEach((chunkGroup) => {
......@@ -50,17 +47,8 @@ function buildManifest(
return
}
let publicPath = url.resolve(
compilation.outputOptions.publicPath || '',
file
)
for (const module of chunk.modulesIterable) {
let id = module.id
let name =
typeof module.libIdent === 'function'
? module.libIdent({ context })
: null
if (!manifest[request]) {
manifest[request] = []
......@@ -77,9 +65,7 @@ function buildManifest(
manifest[request].push({
id,
name,
file,
publicPath,
})
}
})
......
......@@ -44,7 +44,7 @@ export function getAssetPath(route) {
function appendLink(href, rel, as) {
return new Promise((res, rej, link) => {
link = document.createElement('link')
link.crossOrigin = process.crossOrigin
link.crossOrigin = process.env.__NEXT_CROSS_ORIGIN
link.href = href
link.rel = rel
if (as) link.as = as
......@@ -267,7 +267,7 @@ export default class PageLoader {
// dependencies already have it added during build manifest creation
if (isPage) url = url.replace(/\.js$/, '.module.js')
}
script.crossOrigin = process.crossOrigin
script.crossOrigin = process.env.__NEXT_CROSS_ORIGIN
script.src = url
script.onerror = () => {
const error = new Error(`Error loading script ${url}`)
......
......@@ -251,7 +251,6 @@ export default async function exportApp(
assetPrefix: nextConfig.assetPrefix.replace(/\/$/, ''),
distDir,
dev: false,
staticMarkup: false,
hotReloader: null,
basePath: nextConfig.experimental.basePath,
canonicalBase: nextConfig.amp?.canonicalBase || '',
......
......@@ -5,6 +5,7 @@ import { format, URLFormatOptions, UrlObject } from 'url'
import { ManifestItem } from '../server/load-components'
import { NextRouter } from './router/router'
import { Env } from '../../lib/load-env-config'
import { BuildManifest } from '../server/get-page-files'
/**
* Types used by both next and next-server
......@@ -153,20 +154,15 @@ export type DocumentInitialProps = RenderPageResult & {
export type DocumentProps = DocumentInitialProps & {
__NEXT_DATA__: NEXT_DATA
dangerousAsPath: string
buildManifest: BuildManifest
ampPath: string
inAmpMode: boolean
hybridAmp: boolean
staticMarkup: boolean
isDevelopment: boolean
devFiles: string[]
files: string[]
lowPriorityFiles: string[]
polyfillFiles: string[]
dynamicImports: ManifestItem[]
assetPrefix?: string
canonicalBase: string
htmlProps: any
bodyTags: any[]
headTags: any[]
unstable_runtimeJS?: false
}
......
......@@ -2,6 +2,7 @@ import { normalizePagePath, denormalizePagePath } from './normalize-page-path'
export type BuildManifest = {
devFiles: string[]
polyfillFiles: string[]
lowPriorityFiles: string[]
pages: {
'/_app': string[]
......
......@@ -23,7 +23,6 @@ export type ManifestItem = {
id: number | string
name: string
file: string
publicPath: string
}
type ReactLoadableManifest = { [moduleId: string]: ManifestItem[] }
......
......@@ -87,7 +87,6 @@ export type ServerConstructor = {
* Where the Next project is located - @default '.'
*/
dir?: string
staticMarkup?: boolean
/**
* Hide error messages containing server information - @default false
*/
......@@ -113,7 +112,6 @@ export default class Server {
buildId: string
renderOpts: {
poweredByHeader: boolean
staticMarkup: boolean
buildId: string
generateEtags: boolean
runtimeConfig?: { [key: string]: any }
......@@ -140,7 +138,6 @@ export default class Server {
public constructor({
dir = '.',
staticMarkup = false,
quiet = false,
conf = null,
dev = false,
......@@ -171,7 +168,6 @@ export default class Server {
this.renderOpts = {
poweredByHeader: this.nextConfig.poweredByHeader,
canonicalBase: this.nextConfig.amp.canonicalBase,
staticMarkup,
buildId: this.buildId,
generateEtags,
previewProps: this.getPreviewProps(),
......
......@@ -119,7 +119,6 @@ function enhanceComponents(
}
function render(
renderElementToString: (element: React.ReactElement<any>) => string,
element: React.ReactElement<any>,
ampMode: any
): { html: string; head: React.ReactElement[] } {
......@@ -127,7 +126,7 @@ function render(
let head
try {
html = renderElementToString(element)
html = renderToString(element)
} finally {
head = Head.rewind() || defaultHead(isInAmpMode(ampMode))
}
......@@ -136,7 +135,6 @@ function render(
}
export type RenderOptsPartial = {
staticMarkup: boolean
buildId: string
canonicalBase: string
runtimeConfig?: { [key: string]: any }
......@@ -165,6 +163,7 @@ export type RenderOpts = LoadComponentsReturnType & RenderOptsPartial
function renderDocument(
Document: DocumentType,
{
buildManifest,
props,
docProps,
pathname,
......@@ -184,14 +183,8 @@ function renderDocument(
ampState,
inAmpMode,
hybridAmp,
staticMarkup,
devFiles,
files,
lowPriorityFiles,
polyfillFiles,
dynamicImports,
htmlProps,
bodyTags,
headTags,
gsp,
gssp,
......@@ -211,12 +204,7 @@ function renderDocument(
hybridAmp: boolean
dynamicImportsIds: string[]
dynamicImports: ManifestItem[]
devFiles: string[]
files: string[]
lowPriorityFiles: string[]
polyfillFiles: string[]
htmlProps: any
bodyTags: any
headTags: any
isFallback?: boolean
gsp?: boolean
......@@ -250,21 +238,16 @@ function renderDocument(
gip, // whether the page has getInitialProps
appGip, // whether the _app has getInitialProps
},
buildManifest,
dangerousAsPath,
canonicalBase,
ampPath,
inAmpMode,
isDevelopment: !!dev,
hybridAmp,
staticMarkup,
devFiles,
files,
lowPriorityFiles,
polyfillFiles,
dynamicImports,
assetPrefix,
htmlProps,
bodyTags,
headTags,
unstable_runtimeJS,
...docProps,
......@@ -293,7 +276,6 @@ export async function renderToHTML(
const {
err,
dev = false,
staticMarkup = false,
ampPath = '',
App,
Document,
......@@ -334,8 +316,6 @@ export async function renderToHTML(
}
const headTags = (...args: any) => callMiddleware('headTags', args)
const bodyTags = (...args: any) => callMiddleware('bodyTags', args)
const htmlProps = (...args: any) => callMiddleware('htmlProps', args, true)
const didRewrite = (req as any)._nextDidRewrite
const isFallback = !!query.__nextFallback
......@@ -674,27 +654,16 @@ export async function renderToHTML(
// the response might be finished on the getInitialProps call
if (isResSent(res) && !isSSG) return null
const devFiles = buildManifest.devFiles
const files = [
...new Set([
...getPageFiles(buildManifest, '/_app'),
...getPageFiles(buildManifest, pathname),
]),
]
const lowPriorityFiles = buildManifest.lowPriorityFiles
const polyfillFiles = getPageFiles(buildManifest, '/_polyfills')
const renderElementToString = staticMarkup
? renderToStaticMarkup
: renderToString
const renderPageError = (): { html: string; head: any } | void => {
if (ctx.err && ErrorDebug) {
return render(
renderElementToString,
<ErrorDebug error={ctx.err} />,
ampState
)
return render(<ErrorDebug error={ctx.err} />, ampState)
}
if (dev && (props.router || props.Component)) {
......@@ -716,7 +685,6 @@ export async function renderToHTML(
} = enhanceComponents(options, App, Component)
return render(
renderElementToString,
<AppContainer>
<EnhancedApp Component={EnhancedComponent} router={router} {...props} />
</AppContainer>,
......@@ -771,8 +739,6 @@ export async function renderToHTML(
ampState,
props,
headTags: await headTags(documentCtx),
bodyTags: await bodyTags(documentCtx),
htmlProps: await htmlProps(documentCtx),
isFallback,
docProps,
pathname,
......@@ -782,10 +748,7 @@ export async function renderToHTML(
hybridAmp,
dynamicImportsIds,
dynamicImports,
devFiles,
files,
lowPriorityFiles,
polyfillFiles,
gsp: !!getStaticProps ? true : undefined,
gssp: !!getServerSideProps ? true : undefined,
gip: hasPageGetInitialProps ? true : undefined,
......
import PropTypes from 'prop-types'
import React, { Component } from 'react'
import React, { useContext, Component } from 'react'
import flush from 'styled-jsx/server'
import {
AMP_RENDER_TARGET,
......@@ -53,18 +53,6 @@ export default class Document<P = {}> extends Component<DocumentProps & P> {
'next-plugin-loader?middleware=document-head-tags-server!'
)
: () => []
static bodyTagsMiddleware = process.env.__NEXT_PLUGINS
? import(
// @ts-ignore loader syntax
'next-plugin-loader?middleware=document-body-tags-server!'
)
: () => []
static htmlPropsMiddleware = process.env.__NEXT_PLUGINS
? import(
// @ts-ignore loader syntax
'next-plugin-loader?middleware=document-html-props-server!'
)
: () => []
/**
* `getInitialProps` hook returns the context object with the addition of `renderPage`.
......@@ -133,33 +121,22 @@ export default class Document<P = {}> extends Component<DocumentProps & P> {
}
}
export class Html extends Component<
React.DetailedHTMLProps<
export function Html(
props: React.DetailedHTMLProps<
React.HtmlHTMLAttributes<HTMLHtmlElement>,
HTMLHtmlElement
>
> {
static contextType = DocumentComponentContext
static propTypes = {
children: PropTypes.node.isRequired,
}
context!: React.ContextType<typeof DocumentComponentContext>
render() {
const { inAmpMode, htmlProps } = this.context._documentProps
return (
<html
{...htmlProps}
{...this.props}
amp={inAmpMode ? '' : undefined}
data-ampdevmode={
inAmpMode && process.env.NODE_ENV !== 'production' ? '' : undefined
}
/>
)
}
) {
const { inAmpMode } = useContext(DocumentComponentContext)._documentProps
return (
<html
{...props}
amp={inAmpMode ? '' : undefined}
data-ampdevmode={
inAmpMode && process.env.NODE_ENV !== 'production' ? '' : undefined
}
/>
)
}
export class Head extends Component<
......@@ -195,7 +172,9 @@ export class Head extends Component<
file
)}${_devOnlyInvalidateCacheQueryString}`}
as="style"
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
/>,
<link
key={file}
......@@ -204,7 +183,9 @@ export class Head extends Component<
href={`${assetPrefix}/_next/${encodeURI(
file
)}${_devOnlyInvalidateCacheQueryString}`}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
/>
)
})
......@@ -235,7 +216,9 @@ export class Head extends Component<
)}${_devOnlyInvalidateCacheQueryString}`}
as="script"
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
/>
)
})
......@@ -269,7 +252,9 @@ export class Head extends Component<
file
)}${_devOnlyInvalidateCacheQueryString}`}
as="script"
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
/>
))
}
......@@ -480,7 +465,9 @@ export class Head extends Component<
}
as="script"
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
/>
)}
{!disableRuntimeJS && page !== '/_error' && (
......@@ -497,7 +484,9 @@ export class Head extends Component<
}
as="script"
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
/>
)}
{!disableRuntimeJS && this.getPreloadDynamicChunks()}
......@@ -565,7 +554,9 @@ export class NextScript extends Component<OriginProps> {
bundle.file
)}${_devOnlyInvalidateCacheQueryString}`}
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
{...modernProps}
/>
)
......@@ -573,11 +564,11 @@ export class NextScript extends Component<OriginProps> {
}
getScripts() {
const { assetPrefix, files, lowPriorityFiles } = this.context._documentProps
const { assetPrefix, files, buildManifest } = this.context._documentProps
const { _devOnlyInvalidateCacheQueryString } = this.context
const normalScripts = files?.filter((file) => file.endsWith('.js'))
const lowPriorityScripts = lowPriorityFiles?.filter((file) =>
const lowPriorityScripts = buildManifest.lowPriorityFiles?.filter((file) =>
file.endsWith('.js')
)
......@@ -596,7 +587,9 @@ export class NextScript extends Component<OriginProps> {
)}${_devOnlyInvalidateCacheQueryString}`}
nonce={this.props.nonce}
async
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
{...modernProps}
/>
)
......@@ -606,10 +599,10 @@ export class NextScript extends Component<OriginProps> {
getPolyfillScripts() {
// polyfills.js has to be rendered as nomodule without async
// It also has to be the first script to load
const { assetPrefix, polyfillFiles } = this.context._documentProps
const { assetPrefix, buildManifest } = this.context._documentProps
const { _devOnlyInvalidateCacheQueryString } = this.context
return polyfillFiles
return buildManifest.polyfillFiles
.filter(
(polyfill) =>
polyfill.endsWith('.js') && !/\.module\.js$/.test(polyfill)
......@@ -618,7 +611,9 @@ export class NextScript extends Component<OriginProps> {
<script
key={polyfill}
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
noModule={true}
src={`${assetPrefix}/_next/${polyfill}${_devOnlyInvalidateCacheQueryString}`}
/>
......@@ -642,12 +637,10 @@ export class NextScript extends Component<OriginProps> {
render() {
const {
staticMarkup,
assetPrefix,
inAmpMode,
devFiles,
buildManifest,
__NEXT_DATA__,
bodyTags,
unstable_runtimeJS,
} = this.context._documentProps
const disableRuntimeJS = unstable_runtimeJS === false
......@@ -667,12 +660,14 @@ export class NextScript extends Component<OriginProps> {
return (
<>
{staticMarkup || disableRuntimeJS ? null : (
{disableRuntimeJS ? null : (
<script
id="__NEXT_DATA__"
type="application/json"
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
dangerouslySetInnerHTML={{
__html: NextScript.getInlineScriptSource(
this.context._documentProps
......@@ -687,12 +682,13 @@ export class NextScript extends Component<OriginProps> {
key={file}
src={`${assetPrefix}/_next/${file}${_devOnlyInvalidateCacheQueryString}`}
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
data-ampdevmode
/>
))
: null}
{React.createElement(React.Fragment, {}, ...(bodyTags || []))}
</>
)
}
......@@ -717,7 +713,7 @@ export class NextScript extends Component<OriginProps> {
_devOnlyInvalidateCacheQueryString
}
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN}
{...(process.env.__NEXT_MODERN_BUILD ? { noModule: true } : {})}
/>,
process.env.__NEXT_MODERN_BUILD && (
......@@ -733,7 +729,9 @@ export class NextScript extends Component<OriginProps> {
_devOnlyInvalidateCacheQueryString
}
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
type="module"
/>
),
......@@ -750,7 +748,7 @@ export class NextScript extends Component<OriginProps> {
}
key="_app"
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN}
{...(process.env.__NEXT_MODERN_BUILD ? { noModule: true } : {})}
/>,
process.env.__NEXT_MODERN_BUILD && (
......@@ -764,7 +762,9 @@ export class NextScript extends Component<OriginProps> {
}
key="_app-modern"
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
type="module"
/>
),
......@@ -772,8 +772,8 @@ export class NextScript extends Component<OriginProps> {
return (
<>
{!disableRuntimeJS && devFiles
? devFiles.map(
{!disableRuntimeJS && buildManifest.devFiles
? buildManifest.devFiles.map(
(file: string) =>
!file.match(/\.js\.map/) && (
<script
......@@ -782,17 +782,21 @@ export class NextScript extends Component<OriginProps> {
file
)}${_devOnlyInvalidateCacheQueryString}`}
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
/>
)
)
: null}
{staticMarkup || disableRuntimeJS ? null : (
{disableRuntimeJS ? null : (
<script
id="__NEXT_DATA__"
type="application/json"
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
dangerouslySetInnerHTML={{
__html: NextScript.getInlineScriptSource(
this.context._documentProps
......@@ -803,7 +807,9 @@ export class NextScript extends Component<OriginProps> {
{process.env.__NEXT_MODERN_BUILD && !disableRuntimeJS ? (
<script
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
crossOrigin={
this.props.crossOrigin || process.env.__NEXT_CROSS_ORIGIN
}
noModule={true}
dangerouslySetInnerHTML={{
__html: NextScript.safariNomoduleFix,
......@@ -813,9 +819,8 @@ export class NextScript extends Component<OriginProps> {
{!disableRuntimeJS && this.getPolyfillScripts()}
{!disableRuntimeJS && appScript}
{!disableRuntimeJS && page !== '/_error' && pageScript}
{disableRuntimeJS || staticMarkup ? null : this.getDynamicChunks()}
{disableRuntimeJS || staticMarkup ? null : this.getScripts()}
{React.createElement(React.Fragment, {}, ...(bodyTags || []))}
{disableRuntimeJS ? null : this.getDynamicChunks()}
{disableRuntimeJS ? null : this.getScripts()}
</>
)
}
......
......@@ -2,7 +2,7 @@ import Server, { ServerConstructor } from '../next-server/server/next-server'
import { NON_STANDARD_NODE_ENV } from '../lib/constants'
import * as log from '../build/output/log'
type NextServerConstructor = Omit<ServerConstructor, 'staticMarkup'> & {
type NextServerConstructor = ServerConstructor & {
/**
* Whether to launch Next.js in dev mode - @default false
*/
......
......@@ -310,8 +310,7 @@ export default function (render, fetch) {
// test dynamic chunk
resources.push(
'/_next/' +
reactLoadableManifest['../../components/hello1'][0].publicPath
'/_next/' + reactLoadableManifest['../../components/hello1'][0].file
)
// test main.js runtime etc
......
export default async function bodyTags () {
return (
<>
<script dangerouslySetInnerHTML={{ __html: 'console.log("hi") ' }} />
</>
)
}
......@@ -28,12 +28,6 @@ function runTests() {
expect(html).toMatch(/home/)
})
it('should apply htmlProps from plugin correctly', async () => {
const html = await renderViaHTTP(appPort, '/')
const $ = cheerio.load(html)
expect($('html').attr('lang')).toBe('en')
})
it('should apply headTags from plugin correctly', async () => {
const html = await renderViaHTTP(appPort, '/')
const $ = cheerio.load(html)
......@@ -43,18 +37,6 @@ function runTests() {
expect(found).toBeTruthy()
})
it('should apply bodyTags from plugin correctly', async () => {
const html = await renderViaHTTP(appPort, '/')
const $ = cheerio.load(html)
const found = Array.from($('body').children()).find(
(el) =>
el.type === 'script' &&
el.children[0] &&
el.children[0].data.includes('console.log')
)
expect(found).toBeTruthy()
})
it('should call clientInit from plugin correctly', async () => {
const browser = await webdriver(appPort, '/')
expect(await browser.eval('window.didClientInit')).toBe(true)
......
......@@ -198,7 +198,7 @@ describe('Production Usage', () => {
// test dynamic chunk
resources.add(
url + reactLoadableManifest['../../components/hello1'][0].publicPath
url + reactLoadableManifest['../../components/hello1'][0].file
)
// test main.js runtime etc
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册