From 394d7a3ec8a28760d35775692a8caa348bcc7fbb Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 3 Mar 2021 11:46:12 -0600 Subject: [PATCH 1/6] Ensure component load order --- packages/next/build/index.ts | 3 ++- packages/next/build/utils.ts | 9 ++++++--- packages/next/next-server/server/config.ts | 5 +++++ packages/next/next-server/server/load-components.ts | 10 +++++----- .../integration/required-server-files/lib/config.js | 13 +++++++++++++ .../required-server-files/next.config.js | 2 ++ .../integration/required-server-files/pages/_app.js | 7 +++++++ .../required-server-files/pages/index.js | 7 +++++++ .../required-server-files/test/index.test.js | 8 +++++++- 9 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 test/integration/required-server-files/lib/config.js create mode 100644 test/integration/required-server-files/pages/_app.js diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 56b334bb19911..2ec1573b9c531 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -680,7 +680,8 @@ export default async function build( ) return staticCheckWorkers.isPageStatic( page, - serverBundle, + distDir, + isLikeServerless, runtimeEnvConfig, config.i18n?.locales, config.i18n?.defaultLocale, diff --git a/packages/next/build/utils.ts b/packages/next/build/utils.ts index 47635d4fa9568..977af5923710a 100644 --- a/packages/next/build/utils.ts +++ b/packages/next/build/utils.ts @@ -31,6 +31,7 @@ import { normalizeLocalePath } from '../next-server/lib/i18n/normalize-locale-pa import * as Log from './output/log' import opentelemetryApi from '@opentelemetry/api' import { tracer, traceAsyncFn } from './tracer' +import { loadComponents } from '../next-server/server/load-components' const fileGzipStats: { [k: string]: Promise } = {} const fsStatGzip = (file: string) => { @@ -713,7 +714,8 @@ export async function buildStaticPaths( export async function isPageStatic( page: string, - serverBundle: string, + distDir: string, + serverless: bollean, runtimeEnvConfig: any, locales?: string[], defaultLocale?: string, @@ -742,8 +744,9 @@ export async function isPageStatic( require('../next-server/lib/runtime-config').setConfig( runtimeEnvConfig ) - const mod = await require(serverBundle) - const Comp = await (mod.default || mod) + const components = await loadComponents(distDir, page, serverless) + const mod = components.ComponentMod + const Comp = components.Component if ( !Comp || diff --git a/packages/next/next-server/server/config.ts b/packages/next/next-server/server/config.ts index 9b3b66aaa6f25..72a3f85237c7d 100644 --- a/packages/next/next-server/server/config.ts +++ b/packages/next/next-server/server/config.ts @@ -2,6 +2,7 @@ import chalk from 'chalk' import findUp from 'next/dist/compiled/find-up' import { basename, extname } from 'path' import * as Log from '../../build/output/log' +import { hasNextSupport } from '../../telemetry/ci-info' import { CONFIG_FILE } from '../lib/constants' import { execOnce } from '../lib/utils' import { defaultConfig, normalizeConfig } from './config-shared' @@ -443,6 +444,10 @@ export default async function loadConfig( ) } + if (hasNextSupport) { + userConfig.target = 'server' + } + return assignDefaults({ configOrigin: CONFIG_FILE, configFile: path, diff --git a/packages/next/next-server/server/load-components.ts b/packages/next/next-server/server/load-components.ts index 4eac4dce0633e..99b100f4caef0 100644 --- a/packages/next/next-server/server/load-components.ts +++ b/packages/next/next-server/server/load-components.ts @@ -32,6 +32,7 @@ export type LoadComponentsReturnType = { getStaticProps?: GetStaticProps getStaticPaths?: GetStaticPaths getServerSideProps?: GetServerSideProps + ComponentMod: any } export async function loadComponents( @@ -57,11 +58,9 @@ export async function loadComponents( } as LoadComponentsReturnType } - const [DocumentMod, AppMod, ComponentMod] = await Promise.all([ - requirePage('/_document', distDir, serverless), - requirePage('/_app', distDir, serverless), - requirePage(pathname, distDir, serverless), - ]) + const AppMod = await requirePage('/_app', distDir, serverless) + const DocumentMod = await requirePage('/_document', distDir, serverless) + const ComponentMod = await requirePage(pathname, distDir, serverless) const [ buildManifest, @@ -86,6 +85,7 @@ export async function loadComponents( buildManifest, reactLoadableManifest, pageConfig: ComponentMod.config || {}, + ComponentMod, getServerSideProps, getStaticProps, getStaticPaths, diff --git a/test/integration/required-server-files/lib/config.js b/test/integration/required-server-files/lib/config.js new file mode 100644 index 0000000000000..8df1465685f58 --- /dev/null +++ b/test/integration/required-server-files/lib/config.js @@ -0,0 +1,13 @@ +let curConfig + +const idk = Math.random() + +export default () => { + console.log('returning config', idk, curConfig) + return curConfig +} + +export function setConfig(configValue) { + curConfig = configValue + console.log('set config', idk, configValue) +} diff --git a/test/integration/required-server-files/next.config.js b/test/integration/required-server-files/next.config.js index 1214e33ad2f06..3636a73ef1f1b 100644 --- a/test/integration/required-server-files/next.config.js +++ b/test/integration/required-server-files/next.config.js @@ -1,4 +1,6 @@ module.exports = { + // ensure incorrect target is overridden by env + target: 'serverless', rewrites() { return [ { diff --git a/test/integration/required-server-files/pages/_app.js b/test/integration/required-server-files/pages/_app.js new file mode 100644 index 0000000000000..066e62144ad8c --- /dev/null +++ b/test/integration/required-server-files/pages/_app.js @@ -0,0 +1,7 @@ +import { setConfig } from '../lib/config' + +setConfig({ hello: 'world' }) + +export default function MyApp({ Component, pageProps }) { + return +} diff --git a/test/integration/required-server-files/pages/index.js b/test/integration/required-server-files/pages/index.js index 5d287f08b6681..336a12d7c95b0 100644 --- a/test/integration/required-server-files/pages/index.js +++ b/test/integration/required-server-files/pages/index.js @@ -1,4 +1,11 @@ import { useRouter } from 'next/router' +import getConfig from '../lib/config' + +const localConfig = getConfig() + +if (localConfig.hello !== 'world') { + throw new Error('oof import order is wrong, _app comes first') +} export const getServerSideProps = ({ req }) => { return { diff --git a/test/integration/required-server-files/test/index.test.js b/test/integration/required-server-files/test/index.test.js index 399fcfedbc748..57b4260e30af9 100644 --- a/test/integration/required-server-files/test/index.test.js +++ b/test/integration/required-server-files/test/index.test.js @@ -25,7 +25,11 @@ let errors = [] describe('Required Server Files', () => { beforeAll(async () => { await fs.remove(join(appDir, '.next')) - await nextBuild(appDir) + await nextBuild(appDir, undefined, { + env: { + NOW_BUILDER: '1', + }, + }) buildId = await fs.readFile(join(appDir, '.next/BUILD_ID'), 'utf8') requiredFilesManifest = await fs.readJSON( @@ -88,6 +92,8 @@ describe('Required Server Files', () => { console.log('checking', file) expect(await fs.exists(join(appDir, file))).toBe(true) } + + expect(await fs.exists(join(appDir, '.next/server'))).toBe(true) }) it('should render SSR page correctly', async () => { From fdbcc0e90e6b238a1ffe2e799a152f0c1eb6c1cc Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 3 Mar 2021 11:55:12 -0600 Subject: [PATCH 2/6] Update type --- packages/next/build/utils.ts | 2 +- packages/next/next-server/server/config.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/next/build/utils.ts b/packages/next/build/utils.ts index 977af5923710a..7587942492f9f 100644 --- a/packages/next/build/utils.ts +++ b/packages/next/build/utils.ts @@ -715,7 +715,7 @@ export async function buildStaticPaths( export async function isPageStatic( page: string, distDir: string, - serverless: bollean, + serverless: boolean, runtimeEnvConfig: any, locales?: string[], defaultLocale?: string, diff --git a/packages/next/next-server/server/config.ts b/packages/next/next-server/server/config.ts index 72a3f85237c7d..edd6fdc34b072 100644 --- a/packages/next/next-server/server/config.ts +++ b/packages/next/next-server/server/config.ts @@ -445,7 +445,7 @@ export default async function loadConfig( } if (hasNextSupport) { - userConfig.target = 'server' + userConfig.target = process.env.NEXT_PRIVATE_TARGET || 'server' } return assignDefaults({ From 2adf7755ca5f6dc1e56702a535c65948652917a8 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 3 Mar 2021 12:12:54 -0600 Subject: [PATCH 3/6] Update serverless load --- packages/next/build/utils.ts | 2 +- packages/next/next-server/server/load-components.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/next/build/utils.ts b/packages/next/build/utils.ts index 7587942492f9f..62c42c3d014d4 100644 --- a/packages/next/build/utils.ts +++ b/packages/next/build/utils.ts @@ -746,7 +746,7 @@ export async function isPageStatic( ) const components = await loadComponents(distDir, page, serverless) const mod = components.ComponentMod - const Comp = components.Component + const Comp = mod.default || mod if ( !Comp || diff --git a/packages/next/next-server/server/load-components.ts b/packages/next/next-server/server/load-components.ts index 99b100f4caef0..27ae8be988772 100644 --- a/packages/next/next-server/server/load-components.ts +++ b/packages/next/next-server/server/load-components.ts @@ -55,6 +55,7 @@ export async function loadComponents( getStaticProps, getStaticPaths, getServerSideProps, + ComponentMod: Component, } as LoadComponentsReturnType } From b7e794a7806e4d8ef39086f829e9633ae9d9ec6c Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 3 Mar 2021 12:29:37 -0600 Subject: [PATCH 4/6] Update test --- test/integration/app-document-import-order/test/index.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/app-document-import-order/test/index.test.js b/test/integration/app-document-import-order/test/index.test.js index 0876420e7dbe4..2b1f453d3ac2d 100644 --- a/test/integration/app-document-import-order/test/index.test.js +++ b/test/integration/app-document-import-order/test/index.test.js @@ -38,7 +38,7 @@ describe('Root components import order', () => { const html = await res.text() const $ = cheerio.load(html) - const expectSideEffectsOrder = ['_document', '_app', 'page'] + const expectSideEffectsOrder = ['_app', '_document', 'page'] const sideEffectCalls = $('.side-effect-calls') From e15db114c2891781fc5f1f5f73e0396ae8249865 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 3 Mar 2021 12:34:00 -0600 Subject: [PATCH 5/6] update order in assertion name --- test/integration/app-document-import-order/test/index.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/app-document-import-order/test/index.test.js b/test/integration/app-document-import-order/test/index.test.js index 2b1f453d3ac2d..3940da6dbfc05 100644 --- a/test/integration/app-document-import-order/test/index.test.js +++ b/test/integration/app-document-import-order/test/index.test.js @@ -87,7 +87,7 @@ describe('Root components import order', () => { afterAll(() => killApp(app)) it( - 'root components should be imported in this order _document > _app > page in order to respect side effects', + 'root components should be imported in this order _app > _document > page in order to respect side effects', respectsSideEffects ) From c2d84838a781dcbec0223af950f897eef7b6e01d Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 3 Mar 2021 12:57:41 -0600 Subject: [PATCH 6/6] Update order in serverless target instead --- .../build/webpack/loaders/next-serverless-loader/index.ts | 4 +++- packages/next/next-server/server/load-components.ts | 2 +- test/integration/app-document-import-order/test/index.test.js | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/next/build/webpack/loaders/next-serverless-loader/index.ts b/packages/next/build/webpack/loaders/next-serverless-loader/index.ts index 7720a6b3df038..2dd6f884153a2 100644 --- a/packages/next/build/webpack/loaders/next-serverless-loader/index.ts +++ b/packages/next/build/webpack/loaders/next-serverless-loader/index.ts @@ -138,6 +138,8 @@ const nextServerlessLoader: webpack.loader.Loader = function () { } import { getPageHandler } from 'next/dist/build/webpack/loaders/next-serverless-loader/page-handler' + const documentModule = require("${absoluteDocumentPath}") + const appMod = require('${absoluteAppPath}') let App = appMod.default || appMod.then && appMod.then(mod => mod.default); @@ -163,7 +165,7 @@ const nextServerlessLoader: webpack.loader.Loader = function () { pageComponent: Component, pageConfig: config, appModule: App, - documentModule: require("${absoluteDocumentPath}"), + documentModule: documentModule, errorModule: require("${absoluteErrorPath}"), notFoundModule: ${ absolute404Path ? `require("${absolute404Path}")` : undefined diff --git a/packages/next/next-server/server/load-components.ts b/packages/next/next-server/server/load-components.ts index 27ae8be988772..7d972bff0d2a1 100644 --- a/packages/next/next-server/server/load-components.ts +++ b/packages/next/next-server/server/load-components.ts @@ -59,8 +59,8 @@ export async function loadComponents( } as LoadComponentsReturnType } - const AppMod = await requirePage('/_app', distDir, serverless) const DocumentMod = await requirePage('/_document', distDir, serverless) + const AppMod = await requirePage('/_app', distDir, serverless) const ComponentMod = await requirePage(pathname, distDir, serverless) const [ diff --git a/test/integration/app-document-import-order/test/index.test.js b/test/integration/app-document-import-order/test/index.test.js index 3940da6dbfc05..0876420e7dbe4 100644 --- a/test/integration/app-document-import-order/test/index.test.js +++ b/test/integration/app-document-import-order/test/index.test.js @@ -38,7 +38,7 @@ describe('Root components import order', () => { const html = await res.text() const $ = cheerio.load(html) - const expectSideEffectsOrder = ['_app', '_document', 'page'] + const expectSideEffectsOrder = ['_document', '_app', 'page'] const sideEffectCalls = $('.side-effect-calls') @@ -87,7 +87,7 @@ describe('Root components import order', () => { afterAll(() => killApp(app)) it( - 'root components should be imported in this order _app > _document > page in order to respect side effects', + 'root components should be imported in this order _document > _app > page in order to respect side effects', respectsSideEffects )