未验证 提交 494889ac 编写于 作者: J Joe Haddad 提交者: GitHub

Format a few documents (#6505)

上级 a9c39885
/* eslint-disable import/first */
import {IncomingMessage, ServerResponse} from 'http'
import { IncomingMessage, ServerResponse } from 'http'
import { resolve, join, sep } from 'path'
import { parse as parseUrl, UrlWithParsedQuery } from 'url'
import { parse as parseQs, ParsedUrlQuery } from 'querystring'
import fs from 'fs'
import {renderToHTML} from './render'
import {sendHTML} from './send-html'
import {serveStatic} from './serve-static'
import Router, {route, Route} from './router'
import { renderToHTML } from './render'
import { sendHTML } from './send-html'
import { serveStatic } from './serve-static'
import Router, { route, Route } from './router'
import { isInternalUrl, isBlockedPage } from './utils'
import loadConfig from 'next-server/next-config'
import {PHASE_PRODUCTION_SERVER, BUILD_ID_FILE, CLIENT_STATIC_FILES_PATH, CLIENT_STATIC_FILES_RUNTIME} from 'next-server/constants'
import {
PHASE_PRODUCTION_SERVER,
BUILD_ID_FILE,
CLIENT_STATIC_FILES_PATH,
CLIENT_STATIC_FILES_RUNTIME,
} from 'next-server/constants'
import * as envConfig from '../lib/runtime-config'
import {loadComponents} from './load-components'
import { loadComponents } from './load-components'
type NextConfig = any
type ServerConstructor = {
dir?: string,
staticMarkup?: boolean,
quiet?: boolean,
dir?: string
staticMarkup?: boolean
quiet?: boolean
conf?: NextConfig,
}
......@@ -30,16 +35,21 @@ export default class Server {
distDir: string
buildId: string
renderOpts: {
ampEnabled: boolean,
staticMarkup: boolean,
buildId: string,
generateEtags: boolean,
runtimeConfig?: {[key: string]: any},
ampEnabled: boolean
staticMarkup: boolean
buildId: string
generateEtags: boolean
runtimeConfig?: { [key: string]: any }
assetPrefix?: string,
}
router: Router
public constructor({ dir = '.', staticMarkup = false, quiet = false, conf = null }: ServerConstructor = {}) {
public constructor({
dir = '.',
staticMarkup = false,
quiet = false,
conf = null,
}: ServerConstructor = {}) {
this.dir = resolve(dir)
this.quiet = quiet
const phase = this.currentPhase()
......@@ -48,9 +58,18 @@ export default class Server {
// Only serverRuntimeConfig needs the default
// publicRuntimeConfig gets it's default in client/index.js
const {serverRuntimeConfig = {}, publicRuntimeConfig, assetPrefix, generateEtags, target} = this.nextConfig
const {
serverRuntimeConfig = {},
publicRuntimeConfig,
assetPrefix,
generateEtags,
target,
} = this.nextConfig
if (process.env.NODE_ENV === 'production' && target !== 'server') throw new Error('Cannot start server when target is not server. https://err.sh/zeit/next.js/next-start-serverless')
if (process.env.NODE_ENV === 'production' && target !== 'server')
throw new Error(
'Cannot start server when target is not server. https://err.sh/zeit/next.js/next-start-serverless',
)
this.buildId = this.readBuildId()
this.renderOpts = {
......@@ -87,7 +106,11 @@ export default class Server {
console.error(...args)
}
private handleRequest(req: IncomingMessage, res: ServerResponse, parsedUrl?: UrlWithParsedQuery): Promise<void> {
private handleRequest(
req: IncomingMessage,
res: ServerResponse,
parsedUrl?: UrlWithParsedQuery,
): Promise<void> {
// Parse url if parsedUrl not provided
if (!parsedUrl || typeof parsedUrl !== 'object') {
const url: any = req.url
......@@ -100,12 +123,11 @@ export default class Server {
}
res.statusCode = 200
return this.run(req, res, parsedUrl)
.catch((err) => {
this.logError(err)
res.statusCode = 500
res.end('Internal Server Error')
})
return this.run(req, res, parsedUrl).catch((err) => {
this.logError(err)
res.statusCode = 500
res.end('Internal Server Error')
})
}
public getRequestHandler() {
......@@ -134,10 +156,18 @@ export default class Server {
// The commons folder holds commonschunk files
// The chunks folder holds dynamic entries
// The buildId folder holds pages and potentially other assets. As buildId changes per build it can be long-term cached.
if (params.path[0] === CLIENT_STATIC_FILES_RUNTIME || params.path[0] === 'chunks' || params.path[0] === this.buildId) {
if (
params.path[0] === CLIENT_STATIC_FILES_RUNTIME ||
params.path[0] === 'chunks' ||
params.path[0] === this.buildId
) {
this.setImmutableAssetCacheControl(res)
}
const p = join(this.distDir, CLIENT_STATIC_FILES_PATH, ...(params.path || []))
const p = join(
this.distDir,
CLIENT_STATIC_FILES_PATH,
...(params.path || []),
)
await this.serveStatic(req, res, p, parsedUrl)
},
},
......@@ -187,7 +217,11 @@ export default class Server {
return routes
}
private async run(req: IncomingMessage, res: ServerResponse, parsedUrl: UrlWithParsedQuery) {
private async run(
req: IncomingMessage,
res: ServerResponse,
parsedUrl: UrlWithParsedQuery,
) {
try {
const fn = this.router.match(req, res, parsedUrl)
if (fn) {
......@@ -210,12 +244,22 @@ export default class Server {
}
}
private async sendHTML(req: IncomingMessage, res: ServerResponse, html: string) {
const {generateEtags} = this.renderOpts
return sendHTML(req, res, html, {generateEtags})
private async sendHTML(
req: IncomingMessage,
res: ServerResponse,
html: string,
) {
const { generateEtags } = this.renderOpts
return sendHTML(req, res, html, { generateEtags })
}
public async render(req: IncomingMessage, res: ServerResponse, pathname: string, query: ParsedUrlQuery = {}, parsedUrl?: UrlWithParsedQuery): Promise<void> {
public async render(
req: IncomingMessage,
res: ServerResponse,
pathname: string,
query: ParsedUrlQuery = {},
parsedUrl?: UrlWithParsedQuery,
): Promise<void> {
const url: any = req.url
if (isInternalUrl(url)) {
return this.handleRequest(req, res, parsedUrl)
......@@ -237,7 +281,13 @@ export default class Server {
return this.sendHTML(req, res, html)
}
public async renderToAMP(req: IncomingMessage, res: ServerResponse, pathname: string, query: ParsedUrlQuery = {}, parsedUrl?: UrlWithParsedQuery): Promise<void> {
public async renderToAMP(
req: IncomingMessage,
res: ServerResponse,
pathname: string,
query: ParsedUrlQuery = {},
parsedUrl?: UrlWithParsedQuery,
): Promise<void> {
if (!this.nextConfig.experimental.amp) {
throw new Error('"experimental.amp" is not enabled in "next.config.js"')
}
......@@ -262,22 +312,45 @@ export default class Server {
return this.sendHTML(req, res, html)
}
private async renderToHTMLWithComponents(req: IncomingMessage, res: ServerResponse, pathname: string, query: ParsedUrlQuery = {}, opts: any) {
private async renderToHTMLWithComponents(
req: IncomingMessage,
res: ServerResponse,
pathname: string,
query: ParsedUrlQuery = {},
opts: any,
) {
const result = await loadComponents(this.distDir, this.buildId, pathname)
return renderToHTML(req, res, pathname, query, {...result, ...opts})
return renderToHTML(req, res, pathname, query, { ...result, ...opts })
}
public async renderToAMPHTML(req: IncomingMessage, res: ServerResponse, pathname: string, query: ParsedUrlQuery = {}): Promise<string|null> {
public async renderToAMPHTML(
req: IncomingMessage,
res: ServerResponse,
pathname: string,
query: ParsedUrlQuery = {},
): Promise<string | null> {
if (!this.nextConfig.experimental.amp) {
throw new Error('"experimental.amp" is not enabled in "next.config.js"')
}
return this.renderToHTML(req, res, pathname, query, {amphtml: true})
return this.renderToHTML(req, res, pathname, query, { amphtml: true })
}
public async renderToHTML(req: IncomingMessage, res: ServerResponse, pathname: string, query: ParsedUrlQuery = {}, {amphtml}: {amphtml?: boolean} = {}): Promise<string|null> {
public async renderToHTML(
req: IncomingMessage,
res: ServerResponse,
pathname: string,
query: ParsedUrlQuery = {},
{ amphtml }: { amphtml?: boolean } = {},
): Promise<string | null> {
try {
// To make sure the try/catch is executed
const html = await this.renderToHTMLWithComponents(req, res, pathname, query, {...this.renderOpts, amphtml})
const html = await this.renderToHTMLWithComponents(
req,
res,
pathname,
query,
{ ...this.renderOpts, amphtml },
)
return html
} catch (err) {
if (err.code === 'ENOENT') {
......@@ -291,8 +364,17 @@ export default class Server {
}
}
public async renderError(err: Error|null, req: IncomingMessage, res: ServerResponse, pathname: string, query: ParsedUrlQuery = {}): Promise<void> {
res.setHeader('Cache-Control', 'no-cache, no-store, max-age=0, must-revalidate')
public async renderError(
err: Error | null,
req: IncomingMessage,
res: ServerResponse,
pathname: string,
query: ParsedUrlQuery = {},
): Promise<void> {
res.setHeader(
'Cache-Control',
'no-cache, no-store, max-age=0, must-revalidate',
)
const html = await this.renderErrorToHTML(err, req, res, pathname, query)
if (html === null) {
return
......@@ -300,11 +382,24 @@ export default class Server {
return this.sendHTML(req, res, html)
}
public async renderErrorToHTML(err: Error|null, req: IncomingMessage, res: ServerResponse, _pathname: string, query: ParsedUrlQuery = {}) {
return this.renderToHTMLWithComponents(req, res, '/_error', query, {...this.renderOpts, err})
public async renderErrorToHTML(
err: Error | null,
req: IncomingMessage,
res: ServerResponse,
_pathname: string,
query: ParsedUrlQuery = {},
) {
return this.renderToHTMLWithComponents(req, res, '/_error', query, {
...this.renderOpts,
err,
})
}
public async render404(req: IncomingMessage, res: ServerResponse, parsedUrl?: UrlWithParsedQuery): Promise<void> {
public async render404(
req: IncomingMessage,
res: ServerResponse,
parsedUrl?: UrlWithParsedQuery,
): Promise<void> {
const url: any = req.url
const { pathname, query } = parsedUrl ? parsedUrl : parseUrl(url, true)
if (!pathname) {
......@@ -314,7 +409,12 @@ export default class Server {
return this.renderError(null, req, res, pathname, query)
}
public async serveStatic(req: IncomingMessage, res: ServerResponse, path: string, parsedUrl?: UrlWithParsedQuery): Promise<void> {
public async serveStatic(
req: IncomingMessage,
res: ServerResponse,
path: string,
parsedUrl?: UrlWithParsedQuery,
): Promise<void> {
if (!this.isServeableUrl(path)) {
return this.render404(req, res, parsedUrl)
}
......@@ -349,7 +449,11 @@ export default class Server {
return fs.readFileSync(buildIdFile, 'utf8').trim()
} catch (err) {
if (!fs.existsSync(buildIdFile)) {
throw new Error(`Could not find a valid build in the '${this.distDir}' directory! Try building your app with 'next build' before starting the server.`)
throw new Error(
`Could not find a valid build in the '${
this.distDir
}' directory! Try building your app with 'next build' before starting the server.`,
)
}
throw err
......
......@@ -213,7 +213,9 @@ export async function renderToHTML(
}
if (dev && (props.router || props.Component)) {
throw new Error(`'router' and 'Component' can not be returned in getInitialProps from _app.js https://err.sh/zeit/next.js/cant-override-next-props.md`)
throw new Error(
`'router' and 'Component' can not be returned in getInitialProps from _app.js https://err.sh/zeit/next.js/cant-override-next-props.md`,
)
}
const {
......
......@@ -14,19 +14,20 @@ export default class Document extends Component {
_devOnlyInvalidateCacheQueryString: PropTypes.string,
}
static getInitialProps ({ renderPage }) {
static getInitialProps({ renderPage }) {
const { html, head } = renderPage()
const styles = flush()
return { html, head, styles }
}
getChildContext () {
getChildContext() {
return {
_documentProps: this.props,
// In dev we invalidate the cache by appending a timestamp to the resource URL.
// This is a workaround to fix https://github.com/zeit/next.js/issues/5860
// TODO: remove this workaround when https://bugs.webkit.org/show_bug.cgi?id=187726 is fixed.
_devOnlyInvalidateCacheQueryString: process.env.NODE_ENV !== 'production' ? '?ts=' + Date.now() : ''
_devOnlyInvalidateCacheQueryString:
process.env.NODE_ENV !== 'production' ? '?ts=' + Date.now() : '',
}
}
......@@ -71,111 +72,181 @@ export class Head extends Component {
static propTypes = {
nonce: PropTypes.string,
crossOrigin: PropTypes.string
crossOrigin: PropTypes.string,
}
getCssLinks () {
getCssLinks() {
const { assetPrefix, files } = this.context._documentProps
if(!files || files.length === 0) {
if (!files || files.length === 0) {
return null
}
return files.map((file) => {
return files.map(file => {
// Only render .css files here
if(!/\.css$/.exec(file)) {
if (!/\.css$/.exec(file)) {
return null
}
return <link
key={file}
nonce={this.props.nonce}
rel='stylesheet'
href={`${assetPrefix}/_next/${file}`}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
return (
<link
key={file}
nonce={this.props.nonce}
rel="stylesheet"
href={`${assetPrefix}/_next/${file}`}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
)
})
}
getPreloadDynamicChunks () {
getPreloadDynamicChunks() {
const { dynamicImports, assetPrefix } = this.context._documentProps
const { _devOnlyInvalidateCacheQueryString } = this.context
return dynamicImports.map((bundle) => {
return <link
rel='preload'
key={bundle.file}
href={`${assetPrefix}/_next/${bundle.file}${_devOnlyInvalidateCacheQueryString}`}
as='script'
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
return dynamicImports.map(bundle => {
return (
<link
rel="preload"
key={bundle.file}
href={`${assetPrefix}/_next/${
bundle.file
}${_devOnlyInvalidateCacheQueryString}`}
as="script"
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
)
})
}
getPreloadMainLinks () {
getPreloadMainLinks() {
const { assetPrefix, files } = this.context._documentProps
if (!files || files.length === 0) {
return null
}
const { _devOnlyInvalidateCacheQueryString } = this.context
return files.map((file) => {
return files.map(file => {
// Only render .js files here
if(!/\.js$/.exec(file)) {
if (!/\.js$/.exec(file)) {
return null
}
return <link
key={file}
nonce={this.props.nonce}
rel='preload'
href={`${assetPrefix}/_next/${file}${_devOnlyInvalidateCacheQueryString}`}
as='script'
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
return (
<link
key={file}
nonce={this.props.nonce}
rel="preload"
href={`${assetPrefix}/_next/${file}${_devOnlyInvalidateCacheQueryString}`}
as="script"
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
)
})
}
render () {
const { ampEnabled, head, styles, amphtml, assetPrefix, __NEXT_DATA__ } = this.context._documentProps
render() {
const {
ampEnabled,
head,
styles,
amphtml,
assetPrefix,
__NEXT_DATA__,
} = this.context._documentProps
const { _devOnlyInvalidateCacheQueryString } = this.context
const { page, buildId } = __NEXT_DATA__
let children = this.props.children
// show a warning if Head contains <title> (only in development)
if (process.env.NODE_ENV !== 'production') {
children = React.Children.map(children, (child) => {
children = React.Children.map(children, child => {
if (child && child.type === 'title') {
console.warn("Warning: <title> should not be used in _document.js's <Head>. https://err.sh/next.js/no-document-title")
console.warn(
"Warning: <title> should not be used in _document.js's <Head>. https://err.sh/next.js/no-document-title"
)
}
return child
})
if (this.props.crossOrigin) console.warn('Warning: `Head` attribute `crossOrigin` is deprecated. https://err.sh/next.js/doc-crossorigin-deprecated')
if (this.props.crossOrigin)
console.warn(
'Warning: `Head` attribute `crossOrigin` is deprecated. https://err.sh/next.js/doc-crossorigin-deprecated'
)
}
return <head {...this.props}>
{children}
{head}
{amphtml && <>
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1"/>
<link rel="canonical" href={page} />
{/* https://www.ampproject.org/docs/fundamentals/optimize_amp#optimize-the-amp-runtime-loading */}
<link rel="preload" as="script" href="https://cdn.ampproject.org/v0.js" />
{/* Add custom styles before AMP styles to prevent accidental overrides */}
{styles && <style amp-custom="" dangerouslySetInnerHTML={{__html: styles.map((style) => style.props.dangerouslySetInnerHTML.__html).join('')}} />}
<style amp-boilerplate="" dangerouslySetInnerHTML={{__html: `body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}`}}></style>
<noscript><style amp-boilerplate="" dangerouslySetInnerHTML={{__html: `body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}`}}></style></noscript>
<script async src="https://cdn.ampproject.org/v0.js"></script>
</>}
{!amphtml && <>
{ampEnabled && <link rel="amphtml" href={`${page}?amp=1`} />}
{page !== '/_error' && <link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages${getPagePathname(page)}${_devOnlyInvalidateCacheQueryString}`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />}
<link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages/_app.js${_devOnlyInvalidateCacheQueryString}`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
{this.getPreloadDynamicChunks()}
{this.getPreloadMainLinks()}
{this.getCssLinks()}
{styles || null}
</>}
</head>
return (
<head {...this.props}>
{children}
{head}
{amphtml && (
<>
<meta
name="viewport"
content="width=device-width,minimum-scale=1,initial-scale=1"
/>
<link rel="canonical" href={page} />
{/* https://www.ampproject.org/docs/fundamentals/optimize_amp#optimize-the-amp-runtime-loading */}
<link
rel="preload"
as="script"
href="https://cdn.ampproject.org/v0.js"
/>
{/* Add custom styles before AMP styles to prevent accidental overrides */}
{styles && (
<style
amp-custom=""
dangerouslySetInnerHTML={{
__html: styles
.map(style => style.props.dangerouslySetInnerHTML.__html)
.join(''),
}}
/>
)}
<style
amp-boilerplate=""
dangerouslySetInnerHTML={{
__html: `body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}`,
}}
/>
<noscript>
<style
amp-boilerplate=""
dangerouslySetInnerHTML={{
__html: `body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}`,
}}
/>
</noscript>
<script async src="https://cdn.ampproject.org/v0.js" />
</>
)}
{!amphtml && (
<>
{ampEnabled && <link rel="amphtml" href={`${page}?amp=1`} />}
{page !== '/_error' && (
<link
rel="preload"
href={`${assetPrefix}/_next/static/${buildId}/pages${getPagePathname(
page
)}${_devOnlyInvalidateCacheQueryString}`}
as="script"
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
)}
<link
rel="preload"
href={`${assetPrefix}/_next/static/${buildId}/pages/_app.js${_devOnlyInvalidateCacheQueryString}`}
as="script"
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
{this.getPreloadDynamicChunks()}
{this.getPreloadMainLinks()}
{this.getCssLinks()}
{styles || null}
</>
)}
</head>
)
}
}
......@@ -185,11 +256,9 @@ export class Main extends Component {
_devOnlyInvalidateCacheQueryString: PropTypes.string,
}
render () {
render() {
const { html } = this.context._documentProps
return (
<div id='__next' dangerouslySetInnerHTML={{ __html: html }} />
)
return <div id="__next" dangerouslySetInnerHTML={{ __html: html }} />
}
}
......@@ -201,62 +270,78 @@ export class NextScript extends Component {
static propTypes = {
nonce: PropTypes.string,
crossOrigin: PropTypes.string
crossOrigin: PropTypes.string,
}
getDynamicChunks () {
getDynamicChunks() {
const { dynamicImports, assetPrefix } = this.context._documentProps
const { _devOnlyInvalidateCacheQueryString } = this.context
return dynamicImports.map((bundle) => {
return <script
async
key={bundle.file}
src={`${assetPrefix}/_next/${bundle.file}${_devOnlyInvalidateCacheQueryString}`}
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
return dynamicImports.map(bundle => {
return (
<script
async
key={bundle.file}
src={`${assetPrefix}/_next/${
bundle.file
}${_devOnlyInvalidateCacheQueryString}`}
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
)
})
}
getScripts () {
getScripts() {
const { assetPrefix, files } = this.context._documentProps
if (!files || files.length === 0) {
return null
}
const { _devOnlyInvalidateCacheQueryString } = this.context
return files.map((file) => {
return files.map(file => {
// Only render .js files here
if(!/\.js$/.exec(file)) {
if (!/\.js$/.exec(file)) {
return null
}
return <script
key={file}
src={`${assetPrefix}/_next/${file}${_devOnlyInvalidateCacheQueryString}`}
nonce={this.props.nonce}
async
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
return (
<script
key={file}
src={`${assetPrefix}/_next/${file}${_devOnlyInvalidateCacheQueryString}`}
nonce={this.props.nonce}
async
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
)
})
}
static getInlineScriptSource (documentProps) {
const {__NEXT_DATA__} = documentProps
static getInlineScriptSource(documentProps) {
const { __NEXT_DATA__ } = documentProps
try {
const data = JSON.stringify(__NEXT_DATA__)
return htmlEscapeJsonString(data)
} catch(err) {
if(err.message.indexOf('circular structure')) {
throw new Error(`Circular structure in "getInitialProps" result of page "${__NEXT_DATA__.page}". https://err.sh/zeit/next.js/circular-structure`)
} catch (err) {
if (err.message.indexOf('circular structure')) {
throw new Error(
`Circular structure in "getInitialProps" result of page "${
__NEXT_DATA__.page
}". https://err.sh/zeit/next.js/circular-structure`
)
}
throw err
}
}
render () {
const { staticMarkup, assetPrefix, amphtml, devFiles, __NEXT_DATA__ } = this.context._documentProps
render() {
const {
staticMarkup,
assetPrefix,
amphtml,
devFiles,
__NEXT_DATA__,
} = this.context._documentProps
const { _devOnlyInvalidateCacheQueryString } = this.context
if (amphtml) {
......@@ -301,23 +386,63 @@ export class NextScript extends Component {
const { page, buildId } = __NEXT_DATA__
if (process.env.NODE_ENV !== 'production') {
if (this.props.crossOrigin) console.warn('Warning: `NextScript` attribute `crossOrigin` is deprecated. https://err.sh/next.js/doc-crossorigin-deprecated')
if (this.props.crossOrigin)
console.warn(
'Warning: `NextScript` attribute `crossOrigin` is deprecated. https://err.sh/next.js/doc-crossorigin-deprecated'
)
}
return <>
{devFiles ? devFiles.map((file) => <script key={file} src={`${assetPrefix}/_next/${file}${_devOnlyInvalidateCacheQueryString}`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />) : null}
{staticMarkup ? null : <script id="__NEXT_DATA__" type="application/json" nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} dangerouslySetInnerHTML={{
__html: NextScript.getInlineScriptSource(this.context._documentProps)
}} />}
{page !== '/_error' && <script async id={`__NEXT_PAGE__${page}`} src={`${assetPrefix}/_next/static/${buildId}/pages${getPagePathname(page)}${_devOnlyInvalidateCacheQueryString}`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />}
<script async id={`__NEXT_PAGE__/_app`} src={`${assetPrefix}/_next/static/${buildId}/pages/_app.js${_devOnlyInvalidateCacheQueryString}`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
{staticMarkup ? null : this.getDynamicChunks()}
{staticMarkup ? null : this.getScripts()}
</>
return (
<>
{devFiles
? devFiles.map(file => (
<script
key={file}
src={`${assetPrefix}/_next/${file}${_devOnlyInvalidateCacheQueryString}`}
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
))
: null}
{staticMarkup ? null : (
<script
id="__NEXT_DATA__"
type="application/json"
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
dangerouslySetInnerHTML={{
__html: NextScript.getInlineScriptSource(
this.context._documentProps
),
}}
/>
)}
{page !== '/_error' && (
<script
async
id={`__NEXT_PAGE__${page}`}
src={`${assetPrefix}/_next/static/${buildId}/pages${getPagePathname(
page
)}${_devOnlyInvalidateCacheQueryString}`}
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
)}
<script
async
id={`__NEXT_PAGE__/_app`}
src={`${assetPrefix}/_next/static/${buildId}/pages/_app.js${_devOnlyInvalidateCacheQueryString}`}
nonce={this.props.nonce}
crossOrigin={this.props.crossOrigin || process.crossOrigin}
/>
{staticMarkup ? null : this.getDynamicChunks()}
{staticMarkup ? null : this.getScripts()}
</>
)
}
}
function getPagePathname (page) {
function getPagePathname(page) {
if (page === '/') {
return '/index.js'
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册