From f861e0da751fc85a402ce7caab022a888beb1d50 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Tue, 30 Apr 2019 13:11:19 -0500 Subject: [PATCH] Make sure not to require react before NODE_ENV has been set (#7200) * Make sure not to require react before NODE_ENV has been set * Update to use force kill to make windows happy --- packages/next/bin/next.ts | 14 ++++--- test/integration/ssr-ctx/pages/index.js | 17 ++++++++ test/integration/ssr-ctx/test/index.test.js | 43 +++++++++++++++++++++ test/lib/next-test-utils.js | 4 +- 4 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 test/integration/ssr-ctx/pages/index.js create mode 100644 test/integration/ssr-ctx/test/index.test.js diff --git a/packages/next/bin/next.ts b/packages/next/bin/next.ts index c0294b36d0..f5fa1896ff 100755 --- a/packages/next/bin/next.ts +++ b/packages/next/bin/next.ts @@ -11,12 +11,6 @@ import arg from 'next/dist/compiled/arg/index.js' } }) -const React = require('react') - -if (typeof React.Suspense === 'undefined') { - throw new Error(`The version of React you are using is lower than the minimum required version needed for Next.js. Please upgrade "react" and "react-dom": "npm install --save react react-dom" https://err.sh/zeit/next.js/invalid-react-version`) -} - const defaultCommand = 'dev' export type cliCommand = (argv?: string[]) => void const commands: {[command: string]: () => Promise} = { @@ -84,6 +78,14 @@ if (args['--help']) { const defaultEnv = command === 'dev' ? 'development' : 'production' process.env.NODE_ENV = process.env.NODE_ENV || defaultEnv +// this needs to come after we set the correct NODE_ENV or +// else it might cause SSR to break +const React = require('react') + +if (typeof React.Suspense === 'undefined') { + throw new Error(`The version of React you are using is lower than the minimum required version needed for Next.js. Please upgrade "react" and "react-dom": "npm install --save react react-dom" https://err.sh/zeit/next.js/invalid-react-version`) +} + commands[command]().then((exec) => exec(forwardedArgs)) if (command === 'dev') { diff --git a/test/integration/ssr-ctx/pages/index.js b/test/integration/ssr-ctx/pages/index.js new file mode 100644 index 0000000000..231c71719a --- /dev/null +++ b/test/integration/ssr-ctx/pages/index.js @@ -0,0 +1,17 @@ +import React from 'react' + +const Idk = React.createContext(null) + +export default () => { + return ( +
+ + + {(idk) => ( +

Value: {idk}

+ )} +
+
+
+ ) +} diff --git a/test/integration/ssr-ctx/test/index.test.js b/test/integration/ssr-ctx/test/index.test.js new file mode 100644 index 0000000000..98924fd904 --- /dev/null +++ b/test/integration/ssr-ctx/test/index.test.js @@ -0,0 +1,43 @@ +/* eslint-env jest */ +/* global jasmine */ +import { join } from 'path' +import { + killApp, + findPort, + runNextCommand, + renderViaHTTP +} from 'next-test-utils' + +jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 30 + +const appDir = join(__dirname, '../') +let appPort +let app + +describe('Production Usage', () => { + beforeAll(async () => { + await runNextCommand(['build', appDir]) + }) + + it('should render a page with context', async () => { + appPort = await findPort() + + await new Promise((resolve, reject) => { + runNextCommand(['start', appDir, '-p', appPort], { + instance: (child) => { + app = child + child.stdout.on('data', chunk => { + if (chunk.toString().match(/ready on/i)) resolve() + }) + child.stderr.on('data', + chunk => reject(new Error('got error ' + chunk.toString())) + ) + } + }).catch(err => reject(err)) + }) + + const html = await renderViaHTTP(appPort, '/') + expect(html).toMatch(/Value: .*?hello world/) + await killApp(app) + }) +}) diff --git a/test/lib/next-test-utils.js b/test/lib/next-test-utils.js index b264712f28..2e7e190abc 100644 --- a/test/lib/next-test-utils.js +++ b/test/lib/next-test-utils.js @@ -75,7 +75,7 @@ export function runNextCommand (argv, options = {}) { const nextBin = path.join(nextDir, 'dist/bin/next') const cwd = options.cwd || nextDir // Let Next.js decide the environment - const env = { ...process.env, ...options.env, NODE_ENV: undefined } + const env = { ...process.env, ...options.env, NODE_ENV: '' } return new Promise((resolve, reject) => { console.log(`Running command "next ${argv.join(' ')}"`) @@ -162,7 +162,7 @@ export function nextExport (dir, { outdir }) { // Kill a launched app export async function killApp (instance) { - await fkill(instance.pid) + await fkill(instance.pid, { force: true }) } export async function startApp (app) {