Skip to content

Commit

Permalink
feat(config): warn usage of non exist exprimental features
Browse files Browse the repository at this point in the history
  • Loading branch information
SukkaW committed Jun 17, 2022
1 parent 28e26c6 commit 8c23684
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 16 deletions.
44 changes: 37 additions & 7 deletions packages/next/server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,23 @@ const experimentalWarning = execOnce(
}
)

const notExistedExperimentalFeatureWarning = execOnce(
(configFileName: string, features: string[]) => {
const s = features.length > 1 ? 's' : ''
const dont = features.length > 1 ? 'do not' : 'does not'
const them = features.length > 1 ? 'them' : 'it'
Log.warn(
chalk.bold(
`You have defined experimental feature${s} (${features.join(
', '
)}) in ${configFileName} that ${dont} exist in this version of Next.js.`
)
)
Log.warn(`Please remove ${them} from your configuration.`)
console.warn()
}
)

function assignDefaults(userConfig: { [key: string]: any }) {
const configFileName = userConfig.configFileName
if (typeof userConfig.exportTrailingSlash !== 'undefined') {
Expand Down Expand Up @@ -79,16 +96,29 @@ function assignDefaults(userConfig: { [key: string]: any }) {
}

if (key === 'experimental' && typeof value === 'object') {
const enabledExperimentalFeatures = (
Object.keys(value) as (keyof ExperimentalConfig)[]
).filter(
// defaultConfig is pre-defined, thus defaultConfig.experimental can not be undefined
(featureName) =>
const notExistedExperimentalFeatures: string[] = []
const enabledExperimentalFeatures: (keyof ExperimentalConfig)[] = []

for (const featureName of Object.keys(
value
) as (keyof ExperimentalConfig)[]) {
if (!(featureName in defaultConfig.experimental!)) {
notExistedExperimentalFeatures.push(featureName)
} else if (
value[featureName] !== defaultConfig.experimental![featureName]
)
) {
enabledExperimentalFeatures.push(featureName)
}
}

if (notExistedExperimentalFeatures.length > 0) {
notExistedExperimentalFeatureWarning(
configFileName,
notExistedExperimentalFeatures
)
}
if (enabledExperimentalFeatures.length > 0) {
experimentalWarning(configFileName, Object.keys(value))
experimentalWarning(configFileName, enabledExperimentalFeatures)
}
}

Expand Down
79 changes: 70 additions & 9 deletions test/integration/config-experimental-warning/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ describe('Config Experimental Warning', () => {
module.exports = {
target: 'server',
experimental: {
something: true
newNextLinkBehavior: true
}
}
`)
const { stderr } = await nextBuild(appDir, [], { stderr: true })
expect(stderr).toMatch(
'You have enabled experimental feature (something) in next.config.js.'
'You have enabled experimental feature (newNextLinkBehavior) in next.config.js.'
)
})

Expand All @@ -59,43 +59,104 @@ describe('Config Experimental Warning', () => {
module.exports = (phase) => ({
target: 'server',
experimental: {
something: true
newNextLinkBehavior: true
}
})
`)
const { stderr } = await nextBuild(appDir, [], { stderr: true })
expect(stderr).toMatch(
'You have enabled experimental feature (something) in next.config.js.'
'You have enabled experimental feature (newNextLinkBehavior) in next.config.js.'
)
})

it('should not show warning with default value', async () => {
configFile.write(`
module.exports = (phase) => ({
target: 'server',
experimental: {
newNextLinkBehavior: false
}
})
`)
const { stderr } = await nextBuild(appDir, [], { stderr: true })
expect(stderr).not.toMatch(
'You have enabled experimental feature (newNextLinkBehavior) in next.config.js.'
)
})

it('should show warning with config from object with experimental and multiple keys', async () => {
configFile.write(`
module.exports = {
experimental: {
something: true,
another: 1,
newNextLinkBehavior: true,
legacyBrowsers: false,
}
}
`)
const { stderr } = await nextBuild(appDir, [], { stderr: true })
expect(stderr).toMatch(
'You have enabled experimental features (something, another) in next.config.js.'
'You have enabled experimental features (newNextLinkBehavior, legacyBrowsers) in next.config.js.'
)
})

it('should show warning with next.config.mjs from object with experimental', async () => {
configFileMjs.write(`
const config = {
experimental: {
something: true,
newNextLinkBehavior: true,
}
}
export default config
`)
const { stderr } = await nextBuild(appDir, [], { stderr: true })
expect(stderr).toMatch(
'You have enabled experimental feature (something) in next.config.mjs.'
'You have enabled experimental feature (newNextLinkBehavior) in next.config.mjs.'
)
})

it('should show warning with next.config.js from object with non-exist experimental', async () => {
configFile.write(`
const config = {
experimental: {
foo: true
}
}
module.exports = config
`)
const { stderr } = await nextBuild(appDir, [], { stderr: true })
expect(stderr).toMatch(
'You have defined experimental feature (foo) in next.config.js that does not exist in this version'
)
})

it('should show warning with next.config.mjs from object with non-exist experimental', async () => {
configFileMjs.write(`
const config = {
experimental: {
foo: true
}
}
export default config
`)
const { stderr } = await nextBuild(appDir, [], { stderr: true })
expect(stderr).toMatch(
'You have defined experimental feature (foo) in next.config.mjs that does not exist in this version'
)
})

it('should show warning with next.config.js from object with multiple non-exist experimental', async () => {
configFile.write(`
const config = {
experimental: {
foo: true,
bar: false
}
}
module.exports = config
`)
const { stderr } = await nextBuild(appDir, [], { stderr: true })
expect(stderr).toMatch(
'You have defined experimental features (foo, bar) in next.config.js that do not exist in this version'
)
})
})

0 comments on commit 8c23684

Please sign in to comment.