Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable html post optimization for react 18 #36837

Merged
merged 12 commits into from May 12, 2022
93 changes: 44 additions & 49 deletions packages/next/server/render.tsx
Expand Up @@ -1751,56 +1751,51 @@ export async function renderToHTML(
return RenderResult.fromStatic((renderOpts as any).pageData)
}

const postProcessors: Array<((html: string) => Promise<string>) | null> = (
generateStaticHTML
? [
inAmpMode
? async (html: string) => {
html = await optimizeAmp(html, renderOpts.ampOptimizerConfig)
if (!renderOpts.ampSkipValidation && renderOpts.ampValidator) {
await renderOpts.ampValidator(html, pathname)
}
return html
}
: null,
process.env.NEXT_RUNTIME !== 'edge' &&
process.env.__NEXT_OPTIMIZE_FONTS
? async (html: string) => {
return await postProcess(
html,
{ getFontDefinition },
{
optimizeFonts: renderOpts.optimizeFonts,
}
)
}
: null,
process.env.NEXT_RUNTIME !== 'edge' && renderOpts.optimizeCss
? async (html: string) => {
// eslint-disable-next-line import/no-extraneous-dependencies
const Critters = require('critters')
const cssOptimizer = new Critters({
ssrMode: true,
reduceInlineStyles: false,
path: renderOpts.distDir,
publicPath: `${renderOpts.assetPrefix}/_next/`,
preload: 'media',
fonts: false,
...renderOpts.optimizeCss,
})
return await cssOptimizer.process(html)
}
: null,
inAmpMode || hybridAmp
? async (html: string) => {
return html.replace(/&amp;amp=1/g, '&amp=1')
}
: null,
]
: []
).filter(Boolean)
const postProcessors: Array<((html: string) => Promise<string>) | null> = [
inAmpMode
? async (html: string) => {
html = await optimizeAmp(html, renderOpts.ampOptimizerConfig)
if (!renderOpts.ampSkipValidation && renderOpts.ampValidator) {
await renderOpts.ampValidator(html, pathname)
}
return html
}
: null,
process.env.NEXT_RUNTIME !== 'edge' && process.env.__NEXT_OPTIMIZE_FONTS
? async (html: string) => {
return await postProcess(
html,
{ getFontDefinition },
{
optimizeFonts: renderOpts.optimizeFonts,
}
)
}
: null,
process.env.NEXT_RUNTIME !== 'edge' && renderOpts.optimizeCss
? async (html: string) => {
// eslint-disable-next-line import/no-extraneous-dependencies
const Critters = require('critters')
const cssOptimizer = new Critters({
ssrMode: true,
reduceInlineStyles: false,
path: renderOpts.distDir,
publicPath: `${renderOpts.assetPrefix}/_next/`,
preload: 'media',
fonts: false,
...renderOpts.optimizeCss,
})
return await cssOptimizer.process(html)
}
: null,
inAmpMode || hybridAmp
? async (html: string) => {
return html.replace(/&amp;amp=1/g, '&amp=1')
}
: null,
].filter(Boolean)

if (generateStaticHTML || postProcessors.length > 0) {
if (postProcessors.length > 0) {
let html = await streamToString(chainStreams(streams))
huozhi marked this conversation as resolved.
Show resolved Hide resolved
for (const postProcessor of postProcessors) {
if (postProcessor) {
Expand Down
5 changes: 2 additions & 3 deletions test/integration/amphtml-custom-optimizer/next.config.js
@@ -1,5 +1,4 @@
const path = require('path')
module.exports = require(path.join(__dirname, '../../lib/with-react-17.js'))({
module.exports = {
experimental: {
amp: {
optimizer: {
Expand All @@ -10,4 +9,4 @@ module.exports = require(path.join(__dirname, '../../lib/with-react-17.js'))({
skipValidation: true,
},
},
})
}
13 changes: 4 additions & 9 deletions test/integration/amphtml-custom-optimizer/test/index.test.js
Expand Up @@ -12,19 +12,14 @@ import {
let app
let appPort
const appDir = join(__dirname, '../')
const nodeArgs = ['-r', join(appDir, '../../lib/react-17-require-hook.js')]

describe('AMP Custom Optimizer', () => {
it('should build and start for static page', async () => {
const { code } = await nextBuild(appDir, undefined, {
nodeArgs,
})
const { code } = await nextBuild(appDir)
expect(code).toBe(0)

appPort = await findPort()
app = await nextStart(appDir, appPort, {
nodeArgs,
})
app = await nextStart(appDir, appPort)

const html = await renderViaHTTP(appPort, '/')
await killApp(app)
Expand All @@ -39,11 +34,11 @@ describe('AMP Custom Optimizer', () => {
})

it('should build and start for dynamic page', async () => {
const { code } = await nextBuild(appDir, undefined, { nodeArgs })
const { code } = await nextBuild(appDir)
expect(code).toBe(0)

appPort = await findPort()
app = await nextStart(appDir, appPort, { nodeArgs })
app = await nextStart(appDir, appPort)

const html = await renderViaHTTP(appPort, '/dynamic')
await killApp(app)
Expand Down
5 changes: 2 additions & 3 deletions test/integration/amphtml/next.config.js
@@ -1,5 +1,4 @@
const path = require('path')
module.exports = require(path.join(__dirname, '../../lib/with-react-17.js'))({
module.exports = {
onDemandEntries: {
// Make sure entries are not getting disposed.
maxInactiveAge: 1000 * 60 * 60,
Expand All @@ -8,4 +7,4 @@ module.exports = require(path.join(__dirname, '../../lib/with-react-17.js'))({
canonicalBase: 'http://localhost:1234',
},
// edit here
})
}
9 changes: 1 addition & 8 deletions test/integration/amphtml/test/index.test.js
Expand Up @@ -18,7 +18,6 @@ import webdriver from 'next-webdriver'
import { join } from 'path'

const appDir = join(__dirname, '../')
const nodeArgs = ['-r', join(appDir, '../../lib/react-17-require-hook.js')]
let appPort
let app

Expand All @@ -36,14 +35,11 @@ describe('AMP Usage', () => {
const result = await nextBuild(appDir, undefined, {
stdout: true,
stderr: true,
nodeArgs,
})
output = result.stdout + result.stderr

appPort = context.appPort = await findPort()
app = await nextStart(appDir, context.appPort, {
nodeArgs,
})
app = await nextStart(appDir, context.appPort)
})
afterAll(async () => {
await rename(
Expand Down Expand Up @@ -276,7 +272,6 @@ describe('AMP Usage', () => {
onStderr(msg) {
inspectPayload += msg
},
nodeArgs,
})

await renderViaHTTP(dynamicAppPort, '/only-amp')
Expand All @@ -301,7 +296,6 @@ describe('AMP Usage', () => {
onStderr(msg) {
output += msg
},
nodeArgs,
})
})

Expand Down Expand Up @@ -549,7 +543,6 @@ describe('AMP Usage', () => {
onStderr(msg) {
inspectPayload += msg
},
nodeArgs,
})

await renderViaHTTP(dynamicAppPort, '/invalid-amp')
Expand Down
5 changes: 1 addition & 4 deletions test/integration/app-document/next.config.js
@@ -1,4 +1 @@
const path = require('path')
module.exports = require(path.join(__dirname, '../../lib/with-react-17.js'))({
crossOrigin: 'anonymous',
})
module.exports = { crossOrigin: 'anonymous' }
2 changes: 1 addition & 1 deletion test/integration/app-document/pages/_document.js
Expand Up @@ -38,7 +38,7 @@ export default class MyDocument extends Document {
}
}

const result = ctx.renderPage(options)
const result = await ctx.renderPage(options)

return {
...result,
Expand Down
4 changes: 0 additions & 4 deletions test/integration/app-document/test/index.test.js
Expand Up @@ -28,10 +28,6 @@ describe('Document and App', () => {
context.server = await launchApp(join(__dirname, '../'), context.appPort, {
onStdout: collectOutput,
onStderr: collectOutput,
nodeArgs: [
'-r',
join(__dirname, '../../../lib/react-17-require-hook.js'),
],
})

// pre-build all pages at the start
Expand Down
@@ -1,7 +1 @@
const path = require('path')
module.exports = require(path.join(
__dirname,
'../../../../lib/with-react-17.js'
))({
cleanDistDir: false,
})
module.exports = { cleanDistDir: false }
@@ -1,7 +1,3 @@
const path = require('path')
module.exports = require(path.join(
__dirname,
'../../../../lib/with-react-17.js'
))({
module.exports = {
cleanDistDir: false,
})
}
50 changes: 11 additions & 39 deletions test/integration/font-optimization/test/index.test.js
Expand Up @@ -15,10 +15,6 @@ import {
import webdriver from 'next-webdriver'

const fixturesDir = join(__dirname, '..', 'fixtures')
const nodeArgs = [
'-r',
join(__dirname, '../../../lib/react-17-require-hook.js'),
]

const fsExists = (file) =>
fs
Expand Down Expand Up @@ -229,9 +225,7 @@ describe('Font Optimization', () => {

// Re-run build to check if it works when build is cached
it('should work when build is cached', async () => {
await nextBuild(appDir, undefined, {
nodeArgs,
})
await nextBuild(appDir)
const testJson = JSON.parse(
await fs.readFile(builtPage('font-manifest.json'), {
encoding: 'utf-8',
Expand All @@ -246,13 +240,9 @@ describe('Font Optimization', () => {
if (fs.pathExistsSync(join(appDir, '.next'))) {
await fs.remove(join(appDir, '.next'))
}
await nextBuild(appDir, undefined, {
nodeArgs,
})
await nextBuild(appDir)
appPort = await findPort()
app = await nextStart(appDir, appPort, {
nodeArgs,
})
app = await nextStart(appDir, appPort)
builtServerPagesDir = join(appDir, '.next', 'server')
builtPage = (file) => join(builtServerPagesDir, file)
})
Expand All @@ -266,19 +256,12 @@ describe('Font Optimization', () => {
beforeAll(async () => {
await fs.writeFile(
nextConfig,
`
const path = require('path')
module.exports = require(path.join(__dirname, '../../../../lib/with-react-17.js'))({ target: 'serverless', cleanDistDir: false })
`,
`module.exports = ({ target: 'serverless', cleanDistDir: false })`,
'utf8'
)
await nextBuild(appDir, undefined, {
nodeArgs,
})
await nextBuild(appDir)
appPort = await findPort()
app = await nextStart(appDir, appPort, {
nodeArgs,
})
app = await nextStart(appDir, appPort)
builtServerPagesDir = join(appDir, '.next', 'serverless')
builtPage = (file) => join(builtServerPagesDir, file)
})
Expand All @@ -295,19 +278,12 @@ describe('Font Optimization', () => {
beforeAll(async () => {
await fs.writeFile(
nextConfig,
`
const path = require('path')
module.exports = require(path.join(__dirname, '../../../../lib/with-react-17.js'))({ target: 'experimental-serverless-trace', cleanDistDir: false })
`,
`module.exports = ({ target: 'experimental-serverless-trace', cleanDistDir: false })`,
'utf8'
)
await nextBuild(appDir, undefined, {
nodeArgs,
})
await nextBuild(appDir)
appPort = await findPort()
app = await startServerlessEmulator(appDir, appPort, {
nodeArgs,
})
app = await startServerlessEmulator(appDir, appPort)
builtServerPagesDir = join(appDir, '.next', 'serverless')
builtPage = (file) => join(builtServerPagesDir, file)
})
Expand All @@ -320,18 +296,14 @@ describe('Font Optimization', () => {

describe('Font optimization for unreachable font definitions.', () => {
beforeAll(async () => {
await nextBuild(appDir, undefined, {
nodeArgs,
})
await nextBuild(appDir)
await fs.writeFile(
join(appDir, '.next', 'server', 'font-manifest.json'),
'[]',
'utf8'
)
appPort = await findPort()
app = await nextStart(appDir, appPort, {
nodeArgs,
})
app = await nextStart(appDir, appPort)
builtServerPagesDir = join(appDir, '.next', 'serverless')
builtPage = (file) => join(builtServerPagesDir, file)
})
Expand Down