Unflag Automatic Prerendering (#7666)
* Unflag Dynamic Routing * Unflag Automatic Prerendering * Ensure pages are lambdas for test * Fix file check * Fix tests * oof * Use lambda for document middleware test
This commit is contained in:
parent
291eb83923
commit
3aed76fad8
25 changed files with 89 additions and 146 deletions
|
@ -30,9 +30,8 @@ const defaultConfig: { [key: string]: any } = {
|
|||
(Number(process.env.CIRCLE_NODE_TOTAL) ||
|
||||
(os.cpus() || { length: 1 }).length) - 1
|
||||
),
|
||||
autoExport: false,
|
||||
ampBindInitData: false,
|
||||
exportTrailingSlash: true,
|
||||
exportTrailingSlash: false,
|
||||
terserLoader: false,
|
||||
profiling: false,
|
||||
flyingShuttle: false,
|
||||
|
|
|
@ -84,7 +84,6 @@ export default class Server {
|
|||
runtimeConfig?: { [key: string]: any }
|
||||
assetPrefix?: string
|
||||
canonicalBase: string
|
||||
autoExport: boolean
|
||||
documentMiddlewareEnabled: boolean
|
||||
dev?: boolean
|
||||
}
|
||||
|
@ -121,7 +120,6 @@ export default class Server {
|
|||
ampBindInitData: this.nextConfig.experimental.ampBindInitData,
|
||||
poweredByHeader: this.nextConfig.poweredByHeader,
|
||||
canonicalBase: this.nextConfig.amp.canonicalBase,
|
||||
autoExport: this.nextConfig.experimental.autoExport,
|
||||
documentMiddlewareEnabled: this.nextConfig.experimental
|
||||
.documentMiddleware,
|
||||
staticMarkup,
|
||||
|
|
|
@ -122,7 +122,6 @@ function render(
|
|||
}
|
||||
|
||||
type RenderOpts = {
|
||||
autoExport: boolean
|
||||
documentMiddlewareEnabled: boolean
|
||||
ampBindInitData: boolean
|
||||
staticMarkup: boolean
|
||||
|
@ -241,7 +240,6 @@ export async function renderToHTML(
|
|||
const {
|
||||
err,
|
||||
dev = false,
|
||||
autoExport = false,
|
||||
documentMiddlewareEnabled = false,
|
||||
ampBindInitData = false,
|
||||
staticMarkup = false,
|
||||
|
@ -279,19 +277,17 @@ export async function renderToHTML(
|
|||
)
|
||||
}
|
||||
|
||||
if (autoExport) {
|
||||
isStaticPage = typeof (Component as any).getInitialProps !== 'function'
|
||||
const defaultAppGetInitialProps =
|
||||
App.getInitialProps === (App as any).origGetInitialProps
|
||||
isStaticPage = isStaticPage && defaultAppGetInitialProps
|
||||
isStaticPage = typeof (Component as any).getInitialProps !== 'function'
|
||||
const defaultAppGetInitialProps =
|
||||
App.getInitialProps === (App as any).origGetInitialProps
|
||||
isStaticPage = isStaticPage && defaultAppGetInitialProps
|
||||
|
||||
if (isStaticPage) {
|
||||
// remove query values except ones that will be set during export
|
||||
query = {
|
||||
amp: query.amp,
|
||||
}
|
||||
renderOpts.nextExport = true
|
||||
if (isStaticPage) {
|
||||
// remove query values except ones that will be set during export
|
||||
query = {
|
||||
amp: query.amp,
|
||||
}
|
||||
renderOpts.nextExport = true
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -282,17 +282,12 @@ export default async function build(dir: string, conf = null): Promise<void> {
|
|||
PAGES_MANIFEST
|
||||
)
|
||||
|
||||
const { autoExport } = config.experimental
|
||||
const staticPages = new Set<string>()
|
||||
const invalidPages = new Set<string>()
|
||||
const pageInfos = new Map<string, PageInfo>()
|
||||
let pagesManifest: any = {}
|
||||
const pagesManifest = JSON.parse(await fsReadFile(manifestPath, 'utf8'))
|
||||
let customAppGetInitialProps: boolean | undefined
|
||||
|
||||
if (autoExport) {
|
||||
pagesManifest = JSON.parse(await fsReadFile(manifestPath, 'utf8'))
|
||||
}
|
||||
|
||||
process.env.NEXT_PHASE = PHASE_PRODUCTION_BUILD
|
||||
|
||||
const staticCheckSema = new Sema(config.experimental.cpus, {
|
||||
|
@ -324,57 +319,55 @@ export default async function build(dir: string, conf = null): Promise<void> {
|
|||
|
||||
let isStatic = false
|
||||
|
||||
if (autoExport) {
|
||||
pagesManifest[page] = bundleRelative.replace(/\\/g, '/')
|
||||
pagesManifest[page] = bundleRelative.replace(/\\/g, '/')
|
||||
|
||||
const runtimeEnvConfig = {
|
||||
publicRuntimeConfig: config.publicRuntimeConfig,
|
||||
serverRuntimeConfig: config.serverRuntimeConfig,
|
||||
}
|
||||
const nonReservedPage = !page.match(/^\/(_app|_error|_document|api)/)
|
||||
const runtimeEnvConfig = {
|
||||
publicRuntimeConfig: config.publicRuntimeConfig,
|
||||
serverRuntimeConfig: config.serverRuntimeConfig,
|
||||
}
|
||||
const nonReservedPage = !page.match(/^\/(_app|_error|_document|api)/)
|
||||
|
||||
if (nonReservedPage && customAppGetInitialProps === undefined) {
|
||||
customAppGetInitialProps = hasCustomAppGetInitialProps(
|
||||
target === 'serverless'
|
||||
? serverBundle
|
||||
: path.join(
|
||||
distPath,
|
||||
SERVER_DIRECTORY,
|
||||
`/static/${buildId}/pages/_app.js`
|
||||
),
|
||||
runtimeEnvConfig
|
||||
if (nonReservedPage && customAppGetInitialProps === undefined) {
|
||||
customAppGetInitialProps = hasCustomAppGetInitialProps(
|
||||
target === 'serverless'
|
||||
? serverBundle
|
||||
: path.join(
|
||||
distPath,
|
||||
SERVER_DIRECTORY,
|
||||
`/static/${buildId}/pages/_app.js`
|
||||
),
|
||||
runtimeEnvConfig
|
||||
)
|
||||
|
||||
if (customAppGetInitialProps) {
|
||||
console.warn(
|
||||
'Opting out of automatic exporting due to custom `getInitialProps` in `pages/_app`\n'
|
||||
)
|
||||
|
||||
if (customAppGetInitialProps) {
|
||||
console.warn(
|
||||
'Opting out of automatic exporting due to custom `getInitialProps` in `pages/_app`\n'
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (customAppGetInitialProps === false && nonReservedPage) {
|
||||
try {
|
||||
await staticCheckSema.acquire()
|
||||
const result: any = await new Promise((resolve, reject) => {
|
||||
staticCheckWorkers.default(
|
||||
{ serverBundle, runtimeEnvConfig },
|
||||
(error: Error | null, result: any) => {
|
||||
if (error) return reject(error)
|
||||
resolve(result || {})
|
||||
}
|
||||
)
|
||||
})
|
||||
staticCheckSema.release()
|
||||
if (customAppGetInitialProps === false && nonReservedPage) {
|
||||
try {
|
||||
await staticCheckSema.acquire()
|
||||
const result: any = await new Promise((resolve, reject) => {
|
||||
staticCheckWorkers.default(
|
||||
{ serverBundle, runtimeEnvConfig },
|
||||
(error: Error | null, result: any) => {
|
||||
if (error) return reject(error)
|
||||
resolve(result || {})
|
||||
}
|
||||
)
|
||||
})
|
||||
staticCheckSema.release()
|
||||
|
||||
if (result.isStatic) {
|
||||
staticPages.add(page)
|
||||
isStatic = true
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.message !== 'INVALID_DEFAULT_EXPORT') throw err
|
||||
invalidPages.add(page)
|
||||
staticCheckSema.release()
|
||||
if (result.isStatic) {
|
||||
staticPages.add(page)
|
||||
isStatic = true
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.message !== 'INVALID_DEFAULT_EXPORT') throw err
|
||||
invalidPages.add(page)
|
||||
staticCheckSema.release()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -411,7 +404,7 @@ export default async function build(dir: string, conf = null): Promise<void> {
|
|||
|
||||
await writeBuildId(distDir, buildId, selectivePageBuilding)
|
||||
|
||||
if (autoExport && staticPages.size > 0) {
|
||||
if (staticPages.size > 0) {
|
||||
const exportApp = require('../export').default
|
||||
const exportOptions = {
|
||||
silent: true,
|
||||
|
@ -471,7 +464,7 @@ export default async function build(dir: string, conf = null): Promise<void> {
|
|||
})
|
||||
|
||||
if (flyingShuttle) {
|
||||
if (autoExport) await flyingShuttle.mergePagesManifest()
|
||||
await flyingShuttle.mergePagesManifest()
|
||||
await flyingShuttle.save(allStaticPages, pageInfos)
|
||||
}
|
||||
|
||||
|
|
|
@ -450,8 +450,7 @@ export default async function getBaseWebpackConfig(
|
|||
: {}),
|
||||
'process.env.__NEXT_EXPERIMENTAL_DEBUG': JSON.stringify(debug),
|
||||
'process.env.__NEXT_EXPORT_TRAILING_SLASH': JSON.stringify(
|
||||
!config.experimental.autoExport &&
|
||||
config.experimental.exportTrailingSlash
|
||||
config.experimental.exportTrailingSlash
|
||||
),
|
||||
...(isServer
|
||||
? { 'typeof window': JSON.stringify('undefined') }
|
||||
|
|
|
@ -23,7 +23,7 @@ describe('AMP Validation on Export', () => {
|
|||
const toCheck = ['first', 'second', 'third.amp']
|
||||
await Promise.all(
|
||||
toCheck.map(async page => {
|
||||
const content = await readFile(join(outDir, `${page}/index.html`))
|
||||
const content = await readFile(join(outDir, `${page}.html`))
|
||||
await validateAMP(content.toString())
|
||||
})
|
||||
)
|
||||
|
@ -47,9 +47,7 @@ describe('AMP Validation on Export', () => {
|
|||
expect(stdout).toMatch(
|
||||
/warn.*The tag 'amp-video extension \.js script' is missing/
|
||||
)
|
||||
await expect(access(join(outDir, 'cat/index.html'))).resolves.toBe(
|
||||
undefined
|
||||
)
|
||||
await expect(access(join(outDir, 'cat.html'))).resolves.toBe(undefined)
|
||||
await expect(stderr).not.toMatch(
|
||||
/Found conflicting amp tag "meta" with conflicting prop name="viewport"/
|
||||
)
|
||||
|
@ -76,9 +74,7 @@ describe('AMP Validation on Export', () => {
|
|||
expect(stdout).toMatch(
|
||||
/error.*The tag 'img' may only appear as a descendant of tag 'noscript'. Did you mean 'amp-img'\?/
|
||||
)
|
||||
await expect(access(join(outDir, 'dog/index.html'))).resolves.toBe(
|
||||
undefined
|
||||
)
|
||||
await expect(access(join(outDir, 'dog.html'))).resolves.toBe(undefined)
|
||||
await expect(stderr).not.toMatch(
|
||||
/Found conflicting amp tag "meta" with conflicting prop name="viewport"/
|
||||
)
|
||||
|
@ -108,7 +104,7 @@ describe('AMP Validation on Export', () => {
|
|||
expect(stdout).toMatch(
|
||||
/error.*The tag 'img' may only appear as a descendant of tag 'noscript'. Did you mean 'amp-img'\?/
|
||||
)
|
||||
await expect(access(join(outDir, 'dog-cat/index.html'))).resolves.toBe(
|
||||
await expect(access(join(outDir, 'dog-cat.html'))).resolves.toBe(
|
||||
undefined
|
||||
)
|
||||
await expect(stderr).not.toMatch(
|
||||
|
|
|
@ -5,8 +5,5 @@ module.exports = {
|
|||
},
|
||||
amp: {
|
||||
canonicalBase: 'http://localhost:1234'
|
||||
},
|
||||
experimental: {
|
||||
autoExport: true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
module.exports = {
|
||||
target: 'serverless',
|
||||
experimental: {
|
||||
autoExport: true,
|
||||
flyingShuttle: true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
module.exports = {
|
||||
target: 'serverless',
|
||||
experimental: {
|
||||
autoExport: true
|
||||
}
|
||||
target: 'serverless'
|
||||
}
|
||||
|
|
|
@ -2,8 +2,5 @@ module.exports = {
|
|||
onDemandEntries: {
|
||||
// Make sure entries are not getting disposed.
|
||||
maxInactiveAge: 1000 * 60 * 60
|
||||
},
|
||||
experimental: {
|
||||
autoExport: true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
export default () => <p>Hi again 👋</p>
|
||||
const Another = () => <p>Hi again 👋</p>
|
||||
Another.getInitialProps = () => ({})
|
||||
export default Another
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
export default () => <p>Hi there 👋</p>
|
||||
const Home = () => <p>Hi there 👋</p>
|
||||
Home.getInitialProps = () => ({})
|
||||
export default Home
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
module.exports = {
|
||||
experimental: {
|
||||
autoExport: true
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
module.exports = {
|
||||
experimental: {
|
||||
autoExport: true
|
||||
}
|
||||
}
|
|
@ -20,52 +20,36 @@ describe('Export with default map', () => {
|
|||
|
||||
it('should export with folder that has dot in name', async () => {
|
||||
expect.assertions(1)
|
||||
await expect(access(join(outdir, 'v1.12/index.html'))).resolves.toBe(
|
||||
undefined
|
||||
)
|
||||
await expect(access(join(outdir, 'v1.12.html'))).resolves.toBe(undefined)
|
||||
})
|
||||
|
||||
it('should export an amp only page to clean path', async () => {
|
||||
expect.assertions(1)
|
||||
await expect(access(join(outdir, 'docs/index.html'))).resolves.toBe(
|
||||
undefined
|
||||
)
|
||||
await expect(access(join(outdir, 'docs.html'))).resolves.toBe(undefined)
|
||||
})
|
||||
|
||||
it('should export hybrid amp page correctly', async () => {
|
||||
expect.assertions(2)
|
||||
await expect(access(join(outdir, 'some/index.html'))).resolves.toBe(
|
||||
undefined
|
||||
)
|
||||
await expect(access(join(outdir, 'some.amp/index.html'))).resolves.toBe(
|
||||
undefined
|
||||
)
|
||||
await expect(access(join(outdir, 'some.html'))).resolves.toBe(undefined)
|
||||
await expect(access(join(outdir, 'some.amp.html'))).resolves.toBe(undefined)
|
||||
})
|
||||
|
||||
it('should export nested hybrid amp page correctly', async () => {
|
||||
expect.assertions(3)
|
||||
await expect(access(join(outdir, 'docs/index.html'))).resolves.toBe(
|
||||
undefined
|
||||
)
|
||||
await expect(access(join(outdir, 'docs.amp/index.html'))).resolves.toBe(
|
||||
undefined
|
||||
)
|
||||
await expect(access(join(outdir, 'docs.html'))).resolves.toBe(undefined)
|
||||
await expect(access(join(outdir, 'docs.amp.html'))).resolves.toBe(undefined)
|
||||
|
||||
const html = await readFile(join(outdir, 'docs/index.html'))
|
||||
const html = await readFile(join(outdir, 'docs.html'))
|
||||
const $ = cheerio.load(html)
|
||||
expect($('link[rel=amphtml]').attr('href')).toBe('/docs.amp')
|
||||
})
|
||||
|
||||
it('should export nested hybrid amp page correctly with folder', async () => {
|
||||
expect.assertions(3)
|
||||
await expect(access(join(outdir, 'info/index.html'))).resolves.toBe(
|
||||
undefined
|
||||
)
|
||||
await expect(access(join(outdir, 'info.amp/index.html'))).resolves.toBe(
|
||||
undefined
|
||||
)
|
||||
await expect(access(join(outdir, 'info.html'))).resolves.toBe(undefined)
|
||||
await expect(access(join(outdir, 'info.amp.html'))).resolves.toBe(undefined)
|
||||
|
||||
const html = await readFile(join(outdir, 'info/index.html'))
|
||||
const html = await readFile(join(outdir, 'info.html'))
|
||||
const $ = cheerio.load(html)
|
||||
expect($('link[rel=amphtml]').attr('href')).toBe('/info.amp')
|
||||
})
|
||||
|
@ -73,7 +57,7 @@ describe('Export with default map', () => {
|
|||
it('should export hybrid index amp page correctly', async () => {
|
||||
expect.assertions(3)
|
||||
await expect(access(join(outdir, 'index.html'))).resolves.toBe(undefined)
|
||||
await expect(access(join(outdir, 'index.amp/index.html'))).resolves.toBe(
|
||||
await expect(access(join(outdir, 'index.amp.html'))).resolves.toBe(
|
||||
undefined
|
||||
)
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ module.exports = phase => {
|
|||
bar: 'bar'
|
||||
},
|
||||
experimental: {
|
||||
// exportTrailingSlash: false,
|
||||
exportTrailingSlash: true
|
||||
},
|
||||
exportPathMap: function () {
|
||||
return {
|
||||
|
|
|
@ -56,8 +56,8 @@ describe('Static Export', () => {
|
|||
await nextExport(appDir, { outdir })
|
||||
|
||||
nextConfig.replace(
|
||||
`// exportTrailingSlash: false,`,
|
||||
`exportTrailingSlash: false,`
|
||||
`exportTrailingSlash: true`,
|
||||
`exportTrailingSlash: false`
|
||||
)
|
||||
await nextBuild(appDir)
|
||||
await nextExport(appDir, { outdir: outNoTrailSlash })
|
||||
|
|
|
@ -40,4 +40,6 @@ const About = () => (
|
|||
</div>
|
||||
)
|
||||
|
||||
About.getInitialProps = () => ({})
|
||||
|
||||
export default About
|
||||
|
|
|
@ -40,4 +40,6 @@ const About = () => (
|
|||
</div>
|
||||
)
|
||||
|
||||
About.getInitialProps = () => ({})
|
||||
|
||||
export default About
|
||||
|
|
|
@ -39,4 +39,6 @@ const Home = () => (
|
|||
</div>
|
||||
)
|
||||
|
||||
Home.getInitialProps = () => ({})
|
||||
|
||||
export default Home
|
||||
|
|
|
@ -39,4 +39,6 @@ const Home = () => (
|
|||
</div>
|
||||
)
|
||||
|
||||
Home.getInitialProps = () => ({})
|
||||
|
||||
export default Home
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
module.exports = {
|
||||
experimental: {
|
||||
autoExport: true
|
||||
}
|
||||
}
|
|
@ -2,8 +2,5 @@ module.exports = {
|
|||
onDemandEntries: {
|
||||
// Make sure entries are not getting disposed.
|
||||
maxInactiveAge: 1000 * 60 * 60
|
||||
},
|
||||
experimental: {
|
||||
autoExport: true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,5 @@ module.exports = {
|
|||
onDemandEntries: {
|
||||
// Make sure entries are not getting disposed.
|
||||
maxInactiveAge: 1000 * 60 * 60
|
||||
},
|
||||
experimental: {
|
||||
autoExport: true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,5 @@ module.exports = {
|
|||
onDemandEntries: {
|
||||
// Make sure entries are not getting disposed.
|
||||
maxInactiveAge: 1000 * 60 * 60
|
||||
},
|
||||
experimental: {
|
||||
autoExport: true
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue