Webpack's default resolve.mainFields are:
https://webpack.js.org/configuration/resolve/#resolvemainfields
server = ['module', 'main']
browser = ['browser', 'module', 'main']
But next's:
mainFields: isServer ? ['main', 'module'] : ['browser', 'module', 'main'],
The server build prefers main over module which may lead to unexpected results (for example, when having a package whose main points to ES5+CJS source but module points to ESNext+ESM).
Have a package with module field that points to a different source than main, in server build it prefers the main.
Prefer module over main in server build. Or, remove this setting completely and use webpack's default.
bam! also ran into that one some days ago and it drove me crazy!
maybe there was a problem with some node packages? But i think in a project like next, that runs code isomorphic in server and client, its a bad idea to resolve packages differently, so this has to be changed.
Edit: changing it did not solve my issue, though. But something with the webpack config seems to be odd in nextjs
Indeed, an override not working as expected. With this next.config.js:
module.exports = {
webpack: (config, { isServer }) => {
return {
...config,
resolve: {
...config.resolve,
mainFields: isServer ? ['module', 'main'] : ['browser', 'module', 'main'],
},
}
},
};
I believe server builds runs purely on node and use externals on all dependencies, which make them load with native require that goes to main.
I ended up pointing my main to what module had because everything goes through webpack anyway and I'm not planning on using that package in other contexts (e.g. pure node scripts).
It's very common that browser-only code is shipped under the module key in package.json.
We've tried to change this before and it ends up breaking more cases than it fixes.
We're going to leave this option as-is. If you really need it overridden, you can manually do it like you mentioned above.
@Timer, preferring module over main in server builds is webpack鈥檚 default, so it means that many packages _would break_ there, but I haven鈥檛 really seen this case. I haven鈥檛 encountered packages using module for browser only code, as this is browser field role (doesn鈥檛 mean it doesn鈥檛 exists, but it鈥檚 probably not _very_ common).
As a side note, even with my workaround, the way next runs the code in server prevents from module to be used. From my understanding it keeps all dependencies as externals and runs code in standard node, which uses require and goes to main. I haven鈥檛 dug too deep but seems like module isn鈥檛 working on server builds at all.