babel-preset-gatsby: Code-splitting issue when custom babel preset is used
Preliminary Checks
- [X] This issue is not a duplicate. Before opening a new issue, please search existing issues: https://github.com/gatsbyjs/gatsby/issues
- [X] This issue is not a question, feature request, RFC, or anything other than a bug report directly related to Gatsby. Please post those things in GitHub Discussions: https://github.com/gatsbyjs/gatsby/discussions
Description
When using babel-preset-gatsby within a custom Babel Preset (needs to be a function) then Gatsby/Webpack has an issue with code-splitting.
The issue seems to be that the stage, along with all given Babel options, are not passed correctly to the Babel Loader.
So, when I add this line (stage: "build-javascript") to the options, code-splitting works:
presets: [
[
"babel-preset-gatsby",
{
stage: "build-javascript", // This fixes the code splitting issue
},
],
],
We miss the stage when we use babel-preset-gatsby with a Babel Preset.
This can be confirmed when adding console.log('stage 💥', stage) right after the stage on line 35 – I get this:
The reproduction has a babel config: .babelrc:
{
"presets": ["./custom-babel-preset.js"]
}
Which loads a babel preset:
module.exports = function customPreset(api, options) {
return {
presets: [
[
"babel-preset-gatsby",
{
// stage: "build-javascript", // This fixes the code splitting issue
},
],
],
}
}
Reproduction Link
https://github.com/tujoworker/babel-preset-gatsby-bug
Steps to Reproduce
- clone the repo and run
yarn(install). - run
yarn clean && yarn build. - Watch the output from the included
bundle-analyserthat opens.4. - No
component--src-...files are generated and the app bundle is much larger. - Un-comment:
stage: "build-javascript"inside./custom-babel-preset.jsand run the first step again. Now it looks ok.
Expected Result
Normal code-splitting as without a custom Babel preset.
Actual Result
Code-splitting is not properly working. No component--src-... files are generated and the app bundle is much larger.

Environment
System:
OS: macOS 12.4
CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 16.14.2 -
/var/folders/13/vh3krlw95j73h2c3thzjt87h0000gn/T/yarn--1653395556006-0.9630249828797681/node
Yarn: 1.22.17 -
/var/folders/13/vh3krlw95j73h2c3thzjt87h0000gn/T/yarn--1653395556006-0.9630249828797681/yarn
npm: 8.6.0 - ~/.volta/tools/image/npm/8.6.0/bin/npm
Browsers:
Chrome: 101.0.4951.64
Edge: 101.0.1210.47
Firefox: 98.0.2
Safari: 15.5
npmPackages:
gatsby: ^4.14.1 => 4.14.1
gatsby-plugin-gatsby-cloud: ^4.14.0 => 4.14.0
gatsby-plugin-image: ^2.14.1 => 2.14.1
gatsby-plugin-manifest: ^4.14.0 => 4.14.0
gatsby-plugin-offline: ^5.14.1 => 5.14.1
gatsby-plugin-react-helmet: ^5.14.0 => 5.14.0
gatsby-plugin-sharp: ^4.14.1 => 4.14.1
gatsby-plugin-webpack-bundle-analyser-v2: 1.1.27 => 1.1.27
gatsby-source-filesystem: ^4.14.0 => 4.14.0
gatsby-transformer-sharp: ^4.14.0 => 4.14.0
Config Flags
None
I'm having the same symptoms, except my .babelrc file looks like this (it's not a function):
{
"presets": [
[
"babel-preset-gatsby",
{
// "stage": "build-javascript", // without this line, everything is placed in app-hash.js
"targets": {
"browsers": [">0.25%", "not dead"]
}
}
]
],
"plugins": [
"@babel/plugin-proposal-optional-chaining",
[
"babel-plugin-transform-imports",
{
"@fortawesome/free-solid-svg-icons": {
"transform": "@fortawesome/free-solid-svg-icons/${member}",
"skipDefaultConversion": true
},
"nucleo-icons": {
"transform": "nucleo-icons/icons/${member}.svg",
"skipDefaultConversion": false
}
}
]
]
}
It seems adding that stage property fixes the issue.
Here are my system details if that's at all relevant.
System:
OS: macOS 12.4
CPU: (12) x64 Intel(R) Core(TM) i7-8700B CPU @ 3.20GHz
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 16.15.1 - /private/var/folders/dm/pj8g0t455gg16xy2614p_2q40000gn/T/xfs-46d64038/node
Yarn: 3.0.0 - /private/var/folders/dm/pj8g0t455gg16xy2614p_2q40000gn/T/xfs-46d64038/yarn
npm: 8.11.0 - ~/.nvm/versions/node/v16.15.1/bin/npm
Languages:
Python: 3.9.13 - /usr/local/bin/python
Browsers:
Chrome: 102.0.5005.115
Firefox: 101.0.1
Safari: 15.5
So when trying the reproduction logging with
console.log(
require(`util`).inspect(
{ presets, gatsbyPresetResolved, index },
{ depth: null }
)
)
at
https://github.com/gatsbyjs/gatsby/blob/028b1de84385603256822ce38809de2ad77e46e2/packages/gatsby/src/utils/babel-loader-helpers.js#L177-L180
I always get
{
presets: [
ConfigItem {
value: [Function: customPreset],
options: undefined,
dirname: '/Users/lejoe/code/playground/babel-preset-gatsby-bug',
name: undefined,
file: {
request: './custom-babel-preset.js',
resolved: '/Users/lejoe/code/playground/babel-preset-gatsby-bug/custom-babel-preset.js'
}
}
],
gatsbyPresetResolved: '/Users/lejoe/code/playground/babel-preset-gatsby-bug/node_modules/babel-preset-gatsby/index.js',
index: -1
}
So we can't get into the block below where we always add the stage to the preset.
Trying it with just a pure .babelrc without a custom preset like
{
"presets": ["babel-preset-gatsby"]
}
or
{
"presets": [
[
"babel-preset-gatsby",
{
"targets": {
"browsers": [">0.25%", "not dead"]
}
}
]
]
}
it works. So the problem here is nested presets.
Opened PR with changes that would follow nested presets in https://github.com/gatsbyjs/gatsby/pull/36249