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

Improve user errors for invalid pageExtensions #10178

Merged
merged 3 commits into from Jan 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
29 changes: 29 additions & 0 deletions packages/next/next-server/server/config.ts
Expand Up @@ -89,6 +89,35 @@ function assignDefaults(userConfig: { [key: string]: any }) {
)
}

if (key === 'pageExtensions') {
const pageExtensions = userConfig[key]

if (pageExtensions === undefined) {
delete userConfig[key]
return
}

if (!Array.isArray(pageExtensions)) {
lfades marked this conversation as resolved.
Show resolved Hide resolved
throw new Error(
`Specified pageExtensions is not an array of strings, found "${pageExtensions}". Please update this config or remove it.`
)
}

if (!pageExtensions.length) {
throw new Error(
`Specified pageExtensions is an empty array. Please update it with the relevant extensions or remove it.`
)
}

pageExtensions.forEach(ext => {
if (typeof ext !== 'string') {
throw new Error(
`Specified pageExtensions is not an array of strings, found "${ext}" of type "${typeof ext}". Please update this config or remove it.`
)
}
})
}

const maybeObject = userConfig[key]
if (!!maybeObject && maybeObject.constructor === Object) {
userConfig[key] = {
Expand Down
6 changes: 0 additions & 6 deletions test/integration/page-extensions/.babelrc

This file was deleted.

7 changes: 0 additions & 7 deletions test/integration/page-extensions/next.config.js

This file was deleted.

23 changes: 0 additions & 23 deletions test/integration/page-extensions/pages/hmr/some-page.tsx

This file was deleted.

1 change: 1 addition & 0 deletions test/integration/page-extensions/pages/index.js
@@ -0,0 +1 @@
export default () => 'Hello World'
9 changes: 0 additions & 9 deletions test/integration/page-extensions/test/.babelrc

This file was deleted.

42 changes: 0 additions & 42 deletions test/integration/page-extensions/test/hmr.js

This file was deleted.

82 changes: 70 additions & 12 deletions test/integration/page-extensions/test/index.test.js
@@ -1,23 +1,81 @@
/* eslint-env jest */
/* global jasmine */
import { join } from 'path'
import { renderViaHTTP, findPort, launchApp, killApp } from 'next-test-utils'
import fs from 'fs-extra'
import { runNextCommand } from 'next-test-utils'

// test suits
import hmr from './hmr'

const context = {}
jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 5

const appDir = join(__dirname, '..')
const nextConfig = join(appDir, 'next.config.js')

describe('Page Extensions', () => {
beforeAll(async () => {
context.appPort = await findPort()
context.server = await launchApp(join(__dirname, '../'), context.appPort)
it('should use the default pageExtensions if set to undefined', async () => {
await fs.writeFile(
nextConfig,
`module.exports = { pageExtensions: undefined }`
)

const { stdout } = await runNextCommand(['build', appDir], { stdout: true })

await fs.remove(nextConfig)

expect(stdout).toContain('Compiled successfully')
})

// pre-build all pages at the start
await Promise.all([renderViaHTTP(context.appPort, '/hmr/some-page')])
it('should throw if pageExtensions is not an array', async () => {
await fs.writeFile(nextConfig, `module.exports = { pageExtensions: null }`)

const { stderr } = await runNextCommand(['build', appDir], { stderr: true })

await fs.remove(nextConfig)

expect(stderr).toContain(
'Specified pageExtensions is not an array of strings, found "null". Please update this config or remove it'
)
})
afterAll(() => killApp(context.server))

hmr(context, (p, q) => renderViaHTTP(context.appPort, p, q))
it('should throw if pageExtensions is an empty array', async () => {
await fs.writeFile(nextConfig, `module.exports = { pageExtensions: [] }`)

const { stderr } = await runNextCommand(['build', appDir], { stderr: true })

await fs.remove(nextConfig)

expect(stderr).toContain(
'Specified pageExtensions is an empty array. Please update it with the relevant extensions or remove it'
)
})

it('should throw if pageExtensions has invalid extensions', async () => {
await fs.writeFile(
nextConfig,
`module.exports = { pageExtensions: ['js', 123] }`
)

const { stderr } = await runNextCommand(['build', appDir], { stderr: true })

await fs.remove(nextConfig)

expect(stderr).toContain(
'Specified pageExtensions is not an array of strings, found "123" of type "number". Please update this config or remove it'
)
})

it('should throw if @zeit/next-typescript is used', async () => {
await fs.writeFile(
nextConfig,
`const withTypescript = require('@zeit/next-typescript')
module.exports = withTypescript()
`
)

const { stderr } = await runNextCommand(['build', appDir], { stderr: true })

await fs.remove(nextConfig)

expect(stderr).toContain(
'@zeit/next-typescript is no longer needed since Next.js has built-in support for TypeScript now'
)
})
})