Skip to content

Commit

Permalink
Add options configuration callback to Encore.enableReactPreset()
Browse files Browse the repository at this point in the history
  • Loading branch information
Kocal committed Sep 26, 2024
1 parent ac0fd39 commit 70e8b89
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 7 deletions.
12 changes: 10 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1106,10 +1106,18 @@ class Encore {
*
* https://babeljs.io/docs/plugins/preset-react/
*
* You can configure the preset by passing a callback:
* ```
* Encore.enableReactPreset(function(options) {
* // https://babeljs.io/docs/babel-preset-react/#options
* options.development = !Encore.isProduction();
* });
* ```
*
* @returns {Encore}
*/
enableReactPreset() {
webpackConfig.enableReactPreset();
enableReactPreset(callback = () => {}) {
webpackConfig.enableReactPreset(callback);

return this;
}
Expand Down
12 changes: 11 additions & 1 deletion lib/WebpackConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ class WebpackConfig {
/** @type {OptionsCallback<object>} */
this.babelPresetEnvOptionsCallback = () => {};
/** @type {OptionsCallback<object>} */
this.babelReactPresetOptionsCallback = () => {};
/** @type {OptionsCallback<object>} */
this.cssLoaderConfigurationCallback = () => {};
/** @type {OptionsCallback<object>} */
this.styleLoaderConfigurationCallback = () => {};
Expand Down Expand Up @@ -793,8 +795,16 @@ class WebpackConfig {
this.persistentCacheCallback = callback;
}

enableReactPreset() {
/**
* @param {OptionsCallback<object>} callback
*/
enableReactPreset(callback = () => {}) {
if (typeof callback !== 'function') {
throw new Error('Argument 1 to enableForkedTypeScriptTypesChecking() must be a callback function.');
}

this.useReact = true;
this.babelReactPresetOptionsCallback = callback;
}

enablePreactPreset(options = {}) {
Expand Down
11 changes: 7 additions & 4 deletions lib/loaders/babel.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,13 @@ module.exports = {
if (webpackConfig.useReact) {
loaderFeatures.ensurePackagesExistAndAreCorrectVersion('react');

babelConfig.presets.push([require.resolve('@babel/preset-react'), {
// TODO: To remove when Babel 8, "automatic" will become the default value
runtime: 'automatic',
}]);
babelConfig.presets.push([
require.resolve('@babel/preset-react'),
applyOptionsCallback(webpackConfig.babelReactPresetOptionsCallback, {
// TODO: To remove when Babel 8, "automatic" will become the default value
runtime: 'automatic',
})
]);
}

if (webpackConfig.usePreact) {
Expand Down
17 changes: 17 additions & 0 deletions test/WebpackConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,23 @@ describe('WebpackConfig object', () => {
});
});

describe('enableReactPreset', () => {
it('Calling method sets it', () => {
const config = createConfig();
const testCallback = () => {};
config.enableReactPreset(testCallback);
expect(config.babelReactPresetOptionsCallback).to.equal(testCallback);
});

it('Calling with non-callback throws an error', () => {
const config = createConfig();

expect(() => {
config.enableReactPreset('FOO');
}).to.throw('must be a callback function');
});
})

Check failure on line 1000 in test/WebpackConfig.js

View workflow job for this annotation

GitHub Actions / ESLint

Missing semicolon

describe('enablePreactPreset', () => {
it('Without preact-compat', () => {
const config = createConfig();
Expand Down
34 changes: 34 additions & 0 deletions test/loaders/babel.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,40 @@ describe('loaders/babel', () => {
expect(actualLoaders[0].options.presets[2]).to.equal('foo');
});

it('getLoaders() with react and callback', () => {
const config = createConfig();
config.enableReactPreset((options) => {
options.development = !config.isProduction();
});

config.configureBabel(function(babelConfig) {
babelConfig.presets.push('foo');
});

const actualLoaders = babelLoader.getLoaders(config);

// env, react & foo
expect(actualLoaders[0].options.presets).to.have.lengthOf(3);
expect(actualLoaders[0].options.presets[0]).to.deep.equal([
require.resolve('@babel/preset-env'),
{
corejs: null,
modules: false,
targets: {},
useBuiltIns: false,
},
]);
expect(actualLoaders[0].options.presets[1]).to.deep.equal([
require.resolve('@babel/preset-react'),
{
runtime: 'automatic',
development: true,
}
]);
// foo is also still there, not overridden
expect(actualLoaders[0].options.presets[2]).to.equal('foo');
});

it('getLoaders() with preact', () => {
const config = createConfig();
config.enablePreactPreset();
Expand Down

0 comments on commit 70e8b89

Please sign in to comment.