Description
Feature request
With Node 12.17.x landing native support for ES modules, I would expect next.config.js
to support ES module format in addition to CJS.
When using type: module
in package.json
on Node v13.1.0 and an ESM next.config.js
format, Next throws an error due to the config resolution logic relying on require
.
Describe the solution you'd like
Next should follow Node’s module semantics and allow either CJS or ESM file, depending on user configuration.
Currently, next.config.js
uses CJS with require
and module.exports
. ESM format would allow users to import
dependencies and export default
the config object.
This theoretically also opens the door to mirror Node’s explicit file extension pattern, which would suggest support for next.config.cjs
and next.config.mjs
files. This is likely controversial, but it is part of the language.
Describe alternatives you've considered
As statically analyzing the native module format of next.config.js
likely introduces a fair amount of complexity, this could be used as an opportunity to introduce "superset" config files (ESM, TypeScript [see #5318, #8044]) which are transpiled to CJS
, emitted to the distDir
(.next
), and read from that location. This would also allow users pinned versions of Node below 13 to benefit from ESM format or strongly typed config files (see @stencil/core for prior art.)
Additional context
The following error is thrown, minimum reproducible files below.
node:97960) Warning: require() of ES modules is not supported.
require() of /PROJECT_NAME/next.config.js from /PROJECT_NAME/node_modules/next/dist/next-server/server/config.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename next.config.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /PROJECT_NAME/package.json.
/PROJECT_NAME/next.config.js:1
import path from "path";
^^^^^^
SyntaxError: Cannot use import statement outside a module
at wrapSafe (internal/modules/cjs/loader.js:983:16)
at Module._compile (internal/modules/cjs/loader.js:1033:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1103:10)
at Module.load (internal/modules/cjs/loader.js:914:32)
at Function.Module._load (internal/modules/cjs/loader.js:822:14)
at Module.require (internal/modules/cjs/loader.js:956:19)
at require (internal/modules/cjs/helpers.js:74:18)
at Object.loadConfig [as default] (/PROJECT_NAME/node_modules/next/dist/next-server/server/config.js:105:34)
at new Server (/PROJECT_NAME/node_modules/next/dist/next-server/server/next-server.js:42:43)
at new DevServer (/PROJECT_NAME/node_modules/next/dist/server/next-dev-server.js:1:2508)
package.json
{
"type": "module"
...
}
next.config.js
// next.config.js
import withCSS from '@zeit/next-css';
export default withCSS();