Throw error when Promise is returned in next.config (#6476)

After discussion, it was decided we should throw an error when a promise is returned in `next.config.js` as this isn't supported

Fixes: #6416
This commit is contained in:
JJ Kasper 2019-02-28 07:39:51 -06:00 committed by Tim Neutkens
parent 23178db575
commit 1c1d5d01f8
6 changed files with 94 additions and 2 deletions

View file

@ -0,0 +1,19 @@
# Promise In Next Config
#### Why This Error Occurred
The webpack function in `next.config.js` returned a promise which is not supported in Next.js. For example, below is not supported:
```js
module.exports = {
webpack: async function(config) {
return config
}
}
```
#### Possible Ways to Fix It
Check your `next.config.js` for `async` or `return Promise`
Potentially a plugin is returning a `Promise` from the webpack function.

View file

@ -41,9 +41,14 @@ function assignDefaults (userConfig) {
function normalizeConfig (phase, config) {
if (typeof config === 'function') {
return config(phase, { defaultConfig })
}
config = config(phase, { defaultConfig })
if (typeof config.then === 'function') {
throw new Error(
'> Promise returned in next config. https://err.sh/zeit/next.js/promise-in-next-config.md'
)
}
}
return config
}

View file

@ -296,6 +296,13 @@ export default function getBaseWebpackConfig (dir: string, {dev = false, isServe
if (typeof config.webpack === 'function') {
webpackConfig = config.webpack(webpackConfig, { dir, dev, isServer, buildId, config, defaultLoaders, totalPages })
// @ts-ignore: Property 'then' does not exist on type 'Configuration'
if (typeof webpackConfig.then === 'function') {
throw new Error(
'> Promise returned in next config. https://err.sh/zeit/next.js/promise-in-next-config.md'
)
}
}
// Backwards compat for `main.js` entry key

View file

@ -0,0 +1,5 @@
module.exports = (phase, { isServer }) => {
return new Promise((resolve) => {
resolve({ target: 'serverless' })
})
}

View file

@ -0,0 +1,5 @@
export default function Index (props) {
return (
<div>Index Page</div>
)
}

View file

@ -0,0 +1,51 @@
/* eslint-env jest */
/* global jasmine */
import { join } from 'path'
import {
runNextCommand,
findPort,
File
} from 'next-test-utils'
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 30
const configFile = new File(join(__dirname, '../next.config.js'))
describe('Promise in next config', () => {
afterAll(() => configFile.restore())
it('should throw error when a promise is return on config', async () => {
configFile.write(`
module.exports = (phase, { isServer }) => {
return new Promise((resolve) => {
resolve({ target: 'serverless' })
})
}
`)
const { stderr } = await runNextCommand(
['dev', join(__dirname, '..'), '-p', await findPort()],
{ stderr: true }
)
expect(stderr).toMatch(/Error: > Promise returned in next config\. https:\/\/err\.sh\/zeit\/next\.js\/promise-in-next-config\.md/)
})
it('should throw error when a promise is returned on webpack', async () => {
configFile.write(`
module.exports = (phase, { isServer }) => {
return {
webpack: async (config) => {
return config
}
}
}
`)
const { stderr } = await runNextCommand(
['dev', join(__dirname, '..'), '-p', await findPort()],
{ stderr: true }
)
expect(stderr).toMatch(/Error: > Promise returned in next config\. https:\/\/err\.sh\/zeit\/next\.js\/promise-in-next-config\.md/)
})
})