Skip to content

Commit 407d81e

Browse files
committed
bug #738 Fix babel config file detection (jdreesen)
This PR was squashed before being merged into the master branch. Discussion ---------- Fix babel config file detection Since v7 [Babel supports two types of config formats](https://babeljs.io/docs/en/config-files): - Project-wide configuration - `babel.config` files, with the different extensions (`json`, `js`, `cjs`, `mjs`) - File-relative configuration - `.babelrc` files, with the different extensions (none, `json`, `js`, `cjs`, `mjs`) - `package.json` files with a "babel" key Encore, however, only checks for the existence of **file-relative** config files. This is a problem if you want to compile packages from the `node_modules` folder (via `.configureBabel(null, {includeNodeModules: ['...']})`) because **project-wide** configuration files are needed for this. This means that if you only have a `.babelrc.js` file, the package from the `node_modules` folder **will** be compiled by Babel, but **without** the settings defined in the `.babelrc.js` file. If you now rename the `.babelrc.js` to `babel.config.js`, Encore fails to detect it and applies its default Babel config, which results in everything being complied without the settings defined in `babel.config.js`. > Note: Configuring babel through Encore is not an option for me, because I want to make use of Babels [Config Function API](https://babeljs.io/docs/en/config-files#config-function-api) which is not available in Encore afaik. And apart from that I prefer to have the configuration in dedicated files. So my solution for now is to keep an empty `.babelrc.js` to make Encore think there is a Babel config file, and have an additional `babel.config.js` file with the real config. This results in both the application code and node modules being compiled with the desired settings. --- But of course I dug a little deeper into Encore and Babel to fix the problem and the fix is using the `hasFilesystemConfig()` method instead of checking the `babelrc` property (the wording in the comment is a bit outdated, I already created a PR for that ;)): https://github.com/babel/babel/blob/af669297efd775016725ee39318cdb391cf00a21/packages/babel-core/src/config/partial.js#L191-L200 I added some tests, too. I'm not sure if it's worth it to add tests for the different config file extensions, though. I tried to improve the error messages as well. Tell me if you want another wording or different file examples and I'll change it. Commits ------- 5ce489e Fix babel config file detection
2 parents 134f47a + 5ce489e commit 407d81e

File tree

3 files changed

+37
-13
lines changed

3 files changed

+37
-13
lines changed

lib/WebpackConfig.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ class WebpackConfig {
396396
}
397397

398398
if (this.doesBabelRcFileExist()) {
399-
logger.warning('The "callback" argument of configureBabel() will not be used because your app already provides an external Babel configuration (a ".babelrc" file, ".babelrc.js" file or "babel" key in "package.json"). Use null as a first argument to remove that warning.');
399+
logger.warning('The "callback" argument of configureBabel() will not be used because your app already provides an external Babel configuration (e.g. a ".babelrc" or "babelrc.config.js" file or "babel" key in "package.json"). Use null as a first argument to remove that warning.');
400400
}
401401
}
402402

@@ -415,7 +415,7 @@ class WebpackConfig {
415415
}
416416

417417
if (this.doesBabelRcFileExist() && !allowedOptionsWithExternalConfig.includes(normalizedOptionKey)) {
418-
logger.warning(`The "${normalizedOptionKey}" option of configureBabel() will not be used because your app already provides an external Babel configuration (a ".babelrc" file, ".babelrc.js" file or "babel" key in "package.json").`);
418+
logger.warning(`The "${normalizedOptionKey}" option of configureBabel() will not be used because your app already provides an external Babel configuration (e.g. a ".babelrc" or "babelrc.config.js" file or "babel" key in "package.json").`);
419419
continue;
420420
}
421421

@@ -462,7 +462,7 @@ class WebpackConfig {
462462
}
463463

464464
if (this.doesBabelRcFileExist()) {
465-
throw new Error('The "callback" argument of configureBabelPresetEnv() will not be used because your app already provides an external Babel configuration (a ".babelrc" file, ".babelrc.js" file or "babel" key in "package.json").');
465+
throw new Error('The "callback" argument of configureBabelPresetEnv() will not be used because your app already provides an external Babel configuration (e.g. a ".babelrc" or "babelrc.config.js" file or "babel" key in "package.json").');
466466
}
467467

468468
this.babelPresetEnvOptionsCallback = callback;

lib/config/parse-runtime.js

+10-10
Original file line numberDiff line numberDiff line change
@@ -87,21 +87,21 @@ module.exports = function(argv, cwd) {
8787

8888
const partialConfig = babel.loadPartialConfig({
8989
/*
90-
* This is a small mystery. Even if we set the cwd & root
91-
* options, deep in babel, if the filename option is not
92-
* set, then it doesn't see the "cwd" directory as a valid
93-
* directory where it should look for the .babelrc file.
94-
* The fact that this is set to webpack.config.js is not
95-
* significant at all - you could even invent a filename.
96-
* However, as I'm not sure the side effects (the filename
97-
* option is documented as "for error messages"), we're
98-
* setting it to a realistic filename.
90+
* There are two types of babel configuration:
91+
* - project-wide configuration in babel.config.* files
92+
* - file-relative configuration in .babelrc.* files
93+
* or package.json files with a "babel" key
94+
*
95+
* To detect the file-relative configuration we need
96+
* to set the following values. The filename is needed
97+
* for Babel as an example so that it knows where it
98+
* needs to search the relative config for.
9999
*/
100100
root: cwd,
101101
cwd: cwd,
102102
filename: path.join(cwd, 'webpack.config.js')
103103
});
104-
runtimeConfig.babelRcFileExists = (typeof partialConfig.babelrc === 'string');
104+
runtimeConfig.babelRcFileExists = partialConfig.hasFilesystemConfig();
105105

106106
return runtimeConfig;
107107
};

test/config/parse-runtime.js

+24
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,18 @@ describe('parse-runtime', () => {
9696
expect(config.context).to.equal('/tmp/custom-context');
9797
});
9898

99+
it('babel config in package.json detected when present', () => {
100+
const projectDir = createTestDirectory();
101+
fs.writeFileSync(
102+
path.join(projectDir, 'package.json'),
103+
'{"babel": {}}'
104+
);
105+
106+
const config = parseArgv(createArgv(['dev']), projectDir);
107+
108+
expect(config.babelRcFileExists).to.be.true;
109+
});
110+
99111
it('.babelrc detected when present', () => {
100112
const projectDir = createTestDirectory();
101113
fs.writeFileSync(
@@ -108,6 +120,18 @@ describe('parse-runtime', () => {
108120
expect(config.babelRcFileExists).to.be.true;
109121
});
110122

123+
it('babel.config.json detected when present', () => {
124+
const projectDir = createTestDirectory();
125+
fs.writeFileSync(
126+
path.join(projectDir, 'babel.config.json'),
127+
'{}'
128+
);
129+
130+
const config = parseArgv(createArgv(['dev']), projectDir);
131+
132+
expect(config.babelRcFileExists).to.be.true;
133+
});
134+
111135
it('dev-server command hot', () => {
112136
const testDir = createTestDirectory();
113137
const config = parseArgv(createArgv(['dev-server', '--hot']), testDir);

0 commit comments

Comments
 (0)