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

Update to only apply experimental process.env stub in development #12055

Merged
merged 1 commit into from
Apr 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 3 additions & 8 deletions packages/next/build/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -867,15 +867,10 @@ export default async function getBaseWebpackConfig(
}
: undefined),
// stub process.env with proxy to warn a missing value is
// being accessed
...(config.experimental.pageEnv
// being accessed in development mode
...(config.experimental.pageEnv && process.env.NODE_ENV !== 'production'
? {
'process.env':
process.env.NODE_ENV === 'production'
? isServer
? 'process.env'
: '{}'
: `
'process.env': `
new Proxy(${isServer ? 'process.env' : '{}'}, {
get(target, prop) {
if (typeof target[prop] === 'undefined') {
Expand Down
11 changes: 11 additions & 0 deletions test/integration/process-env-stub/components/hello.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { PHASE_PRODUCTION_BUILD } from 'next/constants'

const { NODE_ENV } = process.env
const { NEXT_PHASE } = process.env
const SENTRY_DSN = process.env.NEXT_PUBLIC_SENTRY_DSN

if (NODE_ENV !== 'development' && NEXT_PHASE !== PHASE_PRODUCTION_BUILD) {
console.log('next start', SENTRY_DSN)
}

export default () => process.env.HELLO || 'hi'
15 changes: 13 additions & 2 deletions test/integration/process-env-stub/pages/missing.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
import dynamic from 'next/dynamic'

const Hello = dynamic(() => import('../components/hello'), { ssr: true })

export default () => {
console.log(process.env.hi)
return <p>hi there 👋</p>
// make sure we handle this syntax correctly
const { hi } = process.env
console.log(hi)
return (
<>
<p>hi there 👋</p>
<Hello />
</>
)
}
130 changes: 94 additions & 36 deletions test/integration/process-env-stub/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
launchApp,
renderViaHTTP,
waitFor,
nextBuild,
nextStart,
} from 'next-test-utils'
import { join } from 'path'
import webdriver from 'next-webdriver'
Expand Down Expand Up @@ -54,57 +56,113 @@ const checkMissingClient = async (pathname, prop, shouldWarn = false) => {
}

describe('process.env stubbing', () => {
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort, {
env: {
NEXT_PUBLIC_HI: 'hi',
I_SHOULD_BE_HERE: 'hello',
},
onStderr(msg) {
stderr += msg || ''
},
describe('dev mode', () => {
beforeAll(async () => {
appPort = await findPort()
app = await launchApp(appDir, appPort, {
env: {
NEXT_PUBLIC_HI: 'hi',
I_SHOULD_BE_HERE: 'hello',
},
onStderr(msg) {
stderr += msg || ''
},
})
})
})
afterAll(() => killApp(app))
afterAll(() => killApp(app))

describe('server side', () => {
it('should not show missing env value when its not missing public', async () => {
await checkMissing('/not-missing', 'NEXT_PUBLIC_HI')
})
describe('server side', () => {
it('should not show missing env value when its not missing public', async () => {
await checkMissing('/not-missing', 'NEXT_PUBLIC_HI')
})

it('should not show missing env value when its not missing runtime', async () => {
await checkMissing('/also-not-missing', 'I_SHOULD_BE_HERE')
})
it('should not show missing env value when its not missing runtime', async () => {
await checkMissing('/also-not-missing', 'I_SHOULD_BE_HERE')
})

it('should show missing env value when its missing normal', async () => {
await checkMissing('/missing', 'hi', true)
})
it('should show missing env value when its missing normal', async () => {
await checkMissing('/missing', 'hi', true)
})

it('should show missing env value when its missing GSP', async () => {
await checkMissing('/missing-gsp', 'SECRET', true)
})
it('should show missing env value when its missing GSP', async () => {
await checkMissing('/missing-gsp', 'SECRET', true)
})

it('should show missing env value when its missing GSSP', async () => {
await checkMissing('/missing-gssp', 'SECRET', true)
})

it('should show missing env value when its missing GSSP', async () => {
await checkMissing('/missing-gssp', 'SECRET', true)
it('should show missing env value when its missing API', async () => {
await checkMissing('/api/hi', 'where_is_it', true)
})
})

it('should show missing env value when its missing API', async () => {
await checkMissing('/api/hi', 'where_is_it', true)
describe('client side', () => {
it('should not show missing env value when its not missing public', async () => {
await checkMissingClient('/not-missing', 'NEXT_PUBLIC_HI')
})

it('should show missing env value when its missing runtime', async () => {
await checkMissingClient('/also-not-missing', 'I_SHOULD_BE_HERE', true)
})

it('should show missing env value when its missing normal', async () => {
await checkMissingClient('/missing', 'hi', true)
})
})
})

describe('client side', () => {
it('should not show missing env value when its not missing public', async () => {
await checkMissingClient('/not-missing', 'NEXT_PUBLIC_HI')
describe('production mode', () => {
beforeAll(async () => {
const { code } = await nextBuild(appDir)
if (code !== 0) throw new Error(`build failed with code ${code}`)
appPort = await findPort()
app = await nextStart(appDir, appPort, {
onStderr(msg) {
stderr += msg || ''
},
})
})
afterAll(() => killApp(app))

it('should show missing env value when its missing runtime', async () => {
await checkMissingClient('/also-not-missing', 'I_SHOULD_BE_HERE', true)
describe('server side', () => {
it('should not show missing env value when its not missing public', async () => {
await checkMissing('/not-missing', 'NEXT_PUBLIC_HI')
})

it('should not show missing env value when its not missing runtime', async () => {
await checkMissing('/also-not-missing', 'I_SHOULD_BE_HERE')
})

it('should not show missing env value when its missing normal', async () => {
await checkMissing('/missing', 'hi')
})

it('should not show missing env value when its missing GSP', async () => {
await checkMissing('/missing-gsp', 'SECRET')
})

it('should not show missing env value when its missing GSSP', async () => {
await checkMissing('/missing-gssp', 'SECRET')
})

it('should not show missing env value when its missing API', async () => {
await checkMissing('/api/hi', 'where_is_it')
})
})

it('should show missing env value when its missing normal', async () => {
await checkMissingClient('/missing', 'hi', true)
describe('client side', () => {
it('should not show missing env value when its not missing public', async () => {
await checkMissingClient('/not-missing', 'NEXT_PUBLIC_HI')
})

it('should not show missing env value when its missing runtime', async () => {
await checkMissingClient('/also-not-missing', 'I_SHOULD_BE_HERE')
})

it('should not show missing env value when its missing normal', async () => {
await checkMissingClient('/missing', 'hi')
})
})
})
})