-
Notifications
You must be signed in to change notification settings - Fork 27.9k
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
Upgrade Babel 6 to Babel 7 (major) #4050
Conversation
Also implemented @xtuc's suggestion here: #3428 (comment) based on the implemented version here: babel/babel#7472 it'll be a bit faster after babel/babel#7588 lands. The new API seems to work really well @loganfsmyth (as feedback) |
server/build/babel/find-config.js
Outdated
const configList = buildConfigChain(options).filter(i => i.loc !== 'base') | ||
|
||
return configList[0] | ||
return loadPartialConfig({ babelrc: true, filename }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd recommend against passing babelrc: true
, since you pass filename
that is already the default, and it's possible we may change the meaning of true
still in the beta to be broader than you'd actually want.
server/build/babel/preset.js
Outdated
@@ -36,18 +36,18 @@ const plugins = envPlugins[process.env.NODE_ENV] || envPlugins['development'] | |||
|
|||
module.exports = (context, opts = {}) => ({ | |||
presets: [ | |||
[require.resolve('babel-preset-env'), { | |||
[require.resolve('@babel/preset-env'), { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, is there a specific motivation for using paths here instead of calling require()
on its own?
Since you're passing absolute paths it safe to do this, but it does seem more roundabout since Babel has to process the string into a path.
server/build/babel/find-config.js
Outdated
@@ -1,16 +1,9 @@ | |||
import { join } from 'path' | |||
import buildConfigChain from 'babel-core/lib/transformation/file/options/build-config-chain' | |||
import {loadPartialConfig} from '@babel/core' | |||
|
|||
export default function findBabelConfig (dir) { | |||
// We need to provide a location of a filename inside the `dir`. | |||
// For the name of the file, we could be provide anything. | |||
const filename = join(dir, 'filename.js') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a little concerning. We've got path-based config processing now from babel/babel#7091, so by hard-coding a filename you're essentially making that feature unusable.
If this is done as a performance optimization, I'd caution against worrying too much there. Babel's config processing has a lot more caching now and should be very fast, even when loadPartialConfig
is called for every single file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is done as a performance optimization, I'd caution against worrying too much there. Babel's config processing has a lot more caching now and should be very fast, even when loadPartialConfig is called for every single file.
Basically it's not to pre-optimize, but simply to output which path babel is using when starting the Next process, to be transparent to the user.
Also, it's used to include the next/babel
preset automatically when no babelrc is available.
server/build/webpack.js
Outdated
// That's why we need to do this. | ||
const { options } = externalBabelConfig | ||
mainBabelOptions.babelrc = options.babelrc !== false | ||
mainBabelOptions.babelrc = true | ||
} else { | ||
mainBabelOptions.babelrc = false | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd recommend using the createConfigItem
utility on the mainBabelOptions.presets.push(require.resolve('./babel/preset'))
line below this, rather than just passing the string, otherwise this will end up doing a lot more work.
@@ -33,17 +33,13 @@ function babelConfig (dir, {isServer, dev}) { | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as below about babel.createConfigItem
for the hot loader listing above this.
server/build/webpack.js
Outdated
// That's why we need to do this. | ||
const { options } = externalBabelConfig | ||
mainBabelOptions.babelrc = options.babelrc !== false | ||
mainBabelOptions.babelrc = true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you change up this logic to just be per-filename like I'd recommend, you shouldn't need to assign this to anything. e.g.
const presetItem = createConfigItem(require.resolve('./babel/preset'));
const hotLoaderItem = createConfigItem(require.resolve('react-hot-loader/babel'));
function getBabelConfig(filename, {isServer, dev}) {
const config = loadPartialConfig({
filename,
plugins: [
dev && !isServer && hotLoaderItem
].filter(Boolean),
});
if (!config) return null;
let options = config.options;
if (config.babelrc) {
if (!isServer) {
// Maybe just have some extra logic to avoid printing this multiple times?
console.log(`> Using external babel configuration`)
console.log(`> Location: "${config.babelrc}"`)
}
} else {
options.presets.push(presetItem);
}
return options;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm in that case babel-loader needs to be changed to support a function that has the file path as argument and resolves to a babel config right 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea though 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, I'd totally forgotten that this is used via babel-loader. That makes this a lot clearer.
Hmmm in that case babel-loader needs to be changed to support a function that has the file path as argument and resolves to a babel config right
Maybe that's something we should explore. I hadn't thought about it but it may well make sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated to this specific comment, I'd remove the mainBabelOptions.babelrc = true
line, since searching for the config file is already the default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed the line 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@loganfsmyth created an issue here: babel/babel-loader#598
I had more comments than I originally expected! Hope they help though :D |
.babelrc
Outdated
], | ||
"env": { | ||
"test": { | ||
"presets": [ | ||
"es2015", | ||
"@babel/preset-es2015", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Obviously an existing issue, but since you're using preset-env
already, I'd be very surprised if this was necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, we can solve it differently 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed 👌
], | ||
"env": { | ||
"test": { | ||
"presets": [ | ||
"es2015", | ||
"./babel" | ||
["./babel", { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we're on the same page, I'm a little confused about the expectations you have for this vs the presets you have in the top-level presets
array. As it is, this test
env will just run both sets of presets. What specifically is the goal of the test
env here? It'll add a few extra plugins around styling and react it looks like, but it also doubles up on a ton of the stuff you're already specifying in the top level config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, this should probably be broken out into .babelrc
in the test
directory. Will do that after this PR lands. Since it's not directly related to babel 7 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since babel is removing the babelrc:false
support, there's no point in having it.
BTW: It'd be amazing if you could separate out lint fixes to another PR.
It's an option that you can programmatically pass to Babel, but it's not an option that is available in config files, even in Babel 6. It would have been a no-op where Next was using it in the |
Unfortunately the older |
Cherry picked the commit: #4064 |
# Conflicts: # yarn.lock
# Conflicts: # .babelrc # package.json # server/build/webpack.js # yarn.lock
Thank you very much for all the reviews @loganfsmyth very much appreciated ❤️ |
@@ -77,7 +78,7 @@ | |||
"fresh": "0.5.2", | |||
"friendly-errors-webpack-plugin": "1.6.1", | |||
"glob": "7.1.2", | |||
"hoist-non-react-statics": "2.5.0", | |||
"hoist-non-react-statics": "2.3.1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🍶
@@ -1,6 +1,6 @@ | |||
{ | |||
"name": "next", | |||
"version": "6.0.0-canary.2", | |||
"version": "5.0.1-canary.17", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this accidentally reverted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah fixed already
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's release as 6.0.0-canary.3
Fixes #2654 #3356
Babel 7 does schema validation of
.babelrc
and doesn't support"babelrc": false
.Meaning that if you want similar behaviour you should just do
I'm not sure what the benefit of
babelrc: false
is over above 🤔cc @arunoda
Also, this is pending a release of taskr: lukeed/taskr#305
And styled-jsx seems to work, but can be improved vercel/styled-jsx#362