core-js@3 has been released in March 2019, adding a lot of new features. It's a great time to revamp the Babel config provided by Next.
A modern-ish approach to configure Babel.
Got rid of next/babel
preset in custom Babel config, adding everything by hand.
So, I had this quite straightforward Babel config (.babelrc
) for ages:
{
"plugins": [
"@babel/plugin-transform-flow-strip-types",
"babel-plugin-styled-components",
"inline-react-svg"
],
"presets": [
"next/babel"
]
}
with the following .browserslistrc
:
node 10.16
last 4 chrome versions
last 4 firefox versions
last 4 edge versions
last 2 safari versions
ie 11
not dead
and eventually I discovered that the app doesn't work in IE 11. I mean, something worked and something didn't. So I started to dig up to make sure every feature which Internet Explorer 11 is missing is polyfilled.
I checked the next/babel preset and figured out that it contains both @babel/plugin-transform-runtime
plugin and @babel/preset-env
:
[
require('@babel/plugin-transform-runtime'),
{
corejs: 2,
helpers: true,
regenerator: true,
useESModules: supportsESM && presetEnvConfig.modules !== 'commonjs',
...options['transform-runtime'],
},
],
Here, the polyfilling is being done by the @babel/plugin-transform-runtime
plugin, using core-js@2. But in the age of Babel ^7.4, it's suggested to use @babel/preset-env
for that, setting its useBuiltIns
and corejs
options.
Being unable to use @babel/preset-env
and disable @babel/plugin-transform-runtime
, I "dissected" the whole next/babel
preset and reassembled it in custom .babelrc
, excluding some plugins which are irrelevant for my project (like AMP and styled-jsx
).
So I ended up with this:
{
"plugins": [
"@babel/plugin-transform-flow-strip-types",
"inline-react-svg"
],
"env": {
"development": {
"plugins": [
"babel-plugin-styled-components",
"babel-plugin-react-require",
"@babel/plugin-syntax-dynamic-import",
"./node_modules/next/dist/build/babel/plugins/react-loadable-plugin",
"@babel/plugin-proposal-class-properties",
[
"@babel/plugin-proposal-object-rest-spread",
{
"useBuiltIns": true
}
]
],
"presets": [
[
"@babel/preset-env",
{
"debug": true,
"modules": false,
"exclude": [
"transform-typeof-symbol"
],
"useBuiltIns": "usage",
"corejs": "3.1"
}
],
[
"@babel/preset-react",
{
"development": true
}
]
]
},
"production": {
"plugins": [
"babel-plugin-styled-components",
"babel-plugin-react-require",
"@babel/plugin-syntax-dynamic-import",
"./node_modules/next/dist/build/babel/plugins/react-loadable-plugin",
"@babel/plugin-proposal-class-properties",
[
"@babel/plugin-proposal-object-rest-spread",
{
"useBuiltIns": true
}
]
],
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"exclude": [
"transform-typeof-symbol"
],
"useBuiltIns": "usage",
"corejs": "3.1"
}
],
"@babel/preset-react"
]
},
"test": {
"plugins": [
"babel-plugin-styled-components",
"@babel/plugin-proposal-class-properties"
],
"presets": [
[
"@babel/preset-react",
{
"development": true
}
],
[
"@babel/preset-env",
{
"targets": "node 10.16",
"useBuiltIns": false,
"ignoreBrowserslistConfig": true
}
]
]
}
}
}
(Note: babel.config.js
didn't work for me, so I stayed with the .babelrc
for now)
That being said, please consider upgrading the next/babel
preset to make sure it's using all the latest/greatest stuff.
Nice project by the way :slightly_smiling_face:.
@Timer @HaNdTriX so Babel guys confirmed, that useBuiltIns
and @babel/plugin-transform-runtime
are mutually exclusive.
Also, look out for the new useBuiltIns: pure
option which will be added to the Babel soon.
Thanks for digging into this @awthwathje! We'll try to update the babel configuration soon.
@Timer great, thanks a lot for the effort. Ping me if you need any help.
@Timer
I was trying to make the bundle size as small as possible (we don't need IE11 at all, and rely on the latest browsers)
our .browserslistrc is
last 2 version
> 2%
maintained node versions
not dead
not ie <= 11
not op_mini all
I moved from core-js@2
to core-js@3
using:
"next/babel", {
"preset-env": {
"corejs": 3,
"useBuiltIns": "entry"
}
}
And as I understood from the topic the following setting does not work:
"transform-runtime": {
"corejs": 3
}
For me it just does not finish bundling process at all.
Do you have any suggestions? I assume it makes sense to wait until the support of core-js@3
will be enabled by default, right?
@Carduelis I'm not @Timer, but you are correct: @babel/preset-env
's useBuiltIns
option and @babel/plugin-transform-runtime
are mutually exclusive and should not be used together.
You could use custom Babel config, like I do (it's in the original post), while waiting for the core-js@3
integration into Next.
Whit "next": "^9.1.3", I get:
warning next > @babel/runtime-corejs2 > [email protected]: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3
and warning next > styled-jsx > babel-types > babel-runtime > [email protected]: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
Updating the deps would fix this warning I guess :)
Can't count how many times i have encountered this crap in the last 6 months...
This is a burden now. Everything moved on to core-js 3 but "next" did not
We're removing core-js being included in Next.js completely in favor of a separate chunk only loaded in older browsers: https://github.com/zeit/next.js/pull/10212
@timneutkens thats great news. Currently there is a experimental: {modern:true}
flag, is this one now replaced with the experimental:{polyfillsOptimization: true}
flag?
No those 2 are completely separate efforts and do different things.
Btw the message shown by npm is very out of context and needlessly pressing. We never had any issues with core-js@2 and I wish we could instruct npm to not show certain messages when installing Next.js 馃槙
@timneutkens could you point out the difference between them? I thought themodern
build is taking care of browser switch between old and new browsers?
polyfillsOptimization
-> removes core-js
from modern browsers and adds all required IE11 polyfills loaded only for older browsers using the nomodule
propertymodern
-> preserves for example async/await
and other modern language features like const
let
etc. and loads that only in browsers that support script type="module"
and compiles down async/await
in a separate bundle and serves that for older browsers using nomodule
@timneutkens when trying to use polyfillsOptimzation it seems I still have to use the react-app-polyfill to get our app to run in IE11.
@timneutkens thanks for the heads up
@lifeiscontent a reproduction would be helpful otherwise it's hard to do anything actionable.
@timneutkens I'll see if I have time to put something together later this week, thanks!
@timneutkens what is the recommended babel.config.js after this changes?
@dohomi no babel config? There's only a few reasons to have it.
@Timer @timneutkens thanks a lot guys, this is super-helpful and now Next.js apps work in IE11 without any additional configuration!
Just wanted to mention, that it worked for me only with [email protected]
and not with [email protected]
. I bootstrapped the project with create-next-app
.
@awthwathje it was not released yet, will be part of 9.3, you can opt-in on stable through:
// next.config.js
module.exports = {
experimental: { polyfillsOptimization: true }
}
@timneutkens thanks for the clarification, for some reason I thought that the fact that this ticket was closed means that the feature has landed in stable, that is 9.2. My bad.
Most helpful comment
Whit "next": "^9.1.3", I get:
warning next > @babel/runtime-corejs2 > [email protected]: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3
andwarning next > styled-jsx > babel-types > babel-runtime > [email protected]: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
Updating the deps would fix this warning I guess :)