提交 bf7af1d1 编写于 作者: J JJ Kasper 提交者: Joe Haddad

Add default values for runtime config (#7847)

* Add default values for runtime config

* Add test to ensure default values are set
for runtime config

* Only add runtimeConfig if it's not empty

* Only add runtimeConfig if it's not empty

* Simplify default value adding

* Reduce bundle size

* remove comment changes

* Fix typos

* Add test for runtimeConfig in __NEXT_DATA__
上级 c28f4674
......@@ -167,11 +167,11 @@ type Send<T> = (body: T) => void
*/
export type NextApiResponse<T = any> = ServerResponse & {
/**
* Send data `any` data in reponse
* Send data `any` data in response
*/
send: Send<T>
/**
* Send data `json` data in reponse
* Send data `json` data in response
*/
json: Send<T>
status: (statusCode: number) => NextApiResponse<T>
......
......@@ -39,6 +39,8 @@ const defaultConfig: { [key: string]: any } = {
documentMiddleware: false,
publicDirectory: false,
},
serverRuntimeConfig: {},
publicRuntimeConfig: {},
}
function assignDefaults(userConfig: { [key: string]: any }) {
......@@ -104,6 +106,12 @@ export default function loadConfig(
: canonicalBase) || ''
}
if (userConfig.target === 'serverless' && userConfig.publicRuntimeConfig) {
throw new Error(
'Cannot use publicRuntimeConfig with target=serverless https://err.sh/zeit/next.js/serverless-publicRuntimeConfig'
)
}
return assignDefaults({ configOrigin: CONFIG_FILE, ...userConfig })
}
......
......@@ -118,7 +118,7 @@ export default class Server {
// Only the `publicRuntimeConfig` key is exposed to the client side
// It'll be rendered as part of __NEXT_DATA__ on the client side
if (publicRuntimeConfig) {
if (Object.keys(publicRuntimeConfig).length > 0) {
this.renderOpts.runtimeConfig = publicRuntimeConfig
}
......
......@@ -201,11 +201,6 @@ export default async function build(dir: string, conf = null): Promise<void> {
let result: CompilerResult = { warnings: [], errors: [] }
if (target === 'serverless') {
if (config.publicRuntimeConfig)
throw new Error(
'Cannot use publicRuntimeConfig with target=serverless https://err.sh/zeit/next.js/serverless-publicRuntimeConfig'
)
const clientResult = await runCompiler(configs[0])
// Fail build if clientResult contains errors
if (clientResult.errors.length > 0) {
......
/* global location */
import React, { Suspense } from 'react'
import ReactDOM from 'react-dom'
import HeadManager from './head-manager'
......@@ -49,7 +50,7 @@ __webpack_public_path__ = `${prefix}/_next/` //eslint-disable-line
// Initialize next/config with the environment configuration
envConfig.setConfig({
serverRuntimeConfig: {},
publicRuntimeConfig: runtimeConfig
publicRuntimeConfig: runtimeConfig || {}
})
const asPath = getURL()
......@@ -84,7 +85,7 @@ class Container extends React.Component {
// If it's a dynamic route or has a querystring
if (
data.nextExport &&
(isDynamicRoute(router.pathname) || window.location.search)
(isDynamicRoute(router.pathname) || location.search)
) {
// update query on mount for exported pages
router.replace(
......@@ -92,7 +93,7 @@ class Container extends React.Component {
'?' +
stringifyQs({
...router.query,
...parseQs(window.location.search.substr(1))
...parseQs(location.search.substr(1))
}),
asPath
)
......@@ -104,7 +105,7 @@ class Container extends React.Component {
}
scrollToHash () {
let { hash } = window.location
let { hash } = location
hash = hash && hash.substring(1)
if (!hash) return
......@@ -276,7 +277,7 @@ async function doRender ({ App, Component, props, err }) {
appProps
})
// In development runtime errors are caught by react-error-overlay.
// In development runtime errors are caught by react-error-overlay
if (process.env.NODE_ENV === 'development') {
renderReactElement(
<AppContainer>
......@@ -285,7 +286,7 @@ async function doRender ({ App, Component, props, err }) {
appElement
)
} else {
// In production we catch runtime errors using componentDidCatch which will trigger renderError.
// In production we catch runtime errors using componentDidCatch which will trigger renderError
renderReactElement(
<AppContainer>
<App {...appProps} />
......
......@@ -110,7 +110,7 @@ export default async function (dir, options, configuration) {
const { serverRuntimeConfig, publicRuntimeConfig } = nextConfig
if (publicRuntimeConfig) {
if (Object.keys(publicRuntimeConfig).length > 0) {
renderOpts.runtimeConfig = publicRuntimeConfig
}
......
import getConfig from 'next/config'
const page = () => {
const { publicRuntimeConfig, serverRuntimeConfig } = getConfig()
return (
<>
{publicRuntimeConfig && <p>found public config</p>}
{serverRuntimeConfig && <p>found server config</p>}
</>
)
}
page.getInitialProps = () => ({})
export default page
......@@ -375,6 +375,19 @@ describe('Production Usage', () => {
await browser.close()
})
it('should have default runtime values when not defined', async () => {
const html = await renderViaHTTP(appPort, '/runtime-config')
expect(html).toMatch(/found public config/)
expect(html).toMatch(/found server config/)
})
it('should not have runtimeConfig in __NEXT_DATA__', async () => {
const html = await renderViaHTTP(appPort, '/runtime-config')
const $ = cheerio.load(html)
const script = $('#__NEXT_DATA__').html()
expect(script).not.toMatch(/runtimeConfig/)
})
if (browserName === 'chrome') {
it('should add preload tags when Link prefetch prop is used', async () => {
const browser = await webdriver(appPort, '/prefetch')
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册