Description
The problem
Currently, this tool supports supplying a custom .babelrc
file location via Jest global configuration (jest.globals['vue-jest'].babelRcFile
), which is great.
However, .babelrc
is not an option for us. Due to the fact that it is JSON, we cannot have any logic in the babel configuration. I tried using .babelrc.js
, which babel
supports, but the config loader assumes JSON and parses the file.
Additionally, we have moved to the new project-wide configuration file (babel.config.js
) which is recommended by babel for our use-case, and exports a function instead of an object.
The solution
expand the global jest configuration for vue-jest
to support arbitrary babel options:
{
"jest": {
"globals": {
"vue-jest": {
"babelOptions": {
"presets": [
[
"env",
{
"useBuiltIns": "entry",
"shippedProposals": true
}
]
],
"plugins": [
"syntax-dynamic-import"
],
"env": {
"test": {
"plugins": [
"dynamic-import-node"
]
}
}
}
}
}
}
}
This generic solution opens up many more possibilities for how the tool can be used. For example, if the --config option is used with Jest, we are no longer restricted to JSON. This allows for the configuration to have logic:
// @file jest.config.js
const path = require('path');
const config = require('./config');
const envPreset = [
'@babel/preset-env',
];
if (config.foo) {
envPreset.push({
useBuiltIns: 'entry',
shippedProposals: true,
});
}
module.exports = {
globals: {
'vue-jest': {
babelOptions: {
presets: [envPreset],
plugins: ['babel-plugin-*'],
}
}
}
}
It can also be used to support the configFile option to use a project-wide configuration file (babel.config.js
), e.g.:
// @file jest.config.js
module.exports = {
globals: {
'vue-jest': {
babelOptions: {
configFile: path.resolve(__dirname, './babel.config.js'),
}
}
}
};
This configuration file exports a function that can use the config function API and returns babel options:
// @file babel.config.js
module.exports = (api) => {
api.cache(() => process.env.NODE_ENV === 'production');
return {
presets,
plugins
};
};
This is especially powerful when used in conjunction with webpack
, which can supply the same configuration to it's babel-loader
to ensure functional parity when building the application.
This solution also allows for consumers to take advantage of the new configuration file resolution logic built-in to babel by using the root
option:
// @file jest.config.js
module.exports = {
globals: {
'vue-jest': {
babelOptions: {
root: path.resolve(__dirname),
}
}
}
};
Although I have not explored this option, it could provide an alternative approach to circumvent the current logic provided by third-party find-babel-contrib, which is not owned/maintained by the babel core team. I also found an open PR (#93) which indicates there are needs to make it better, or closer to the native behavior of babel
.