Skip to content

Commit 714a732

Browse files
committed
Add "include_node_modules" option to configureBabel
1 parent 6c8f073 commit 714a732

File tree

3 files changed

+92
-10
lines changed

3 files changed

+92
-10
lines changed

index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,12 @@ class Encore {
649649
* A Webpack Condition passed to the JS/JSX rule that
650650
* determines which files and folders should not be
651651
* processed by Babel (https://webpack.js.org/configuration/module/#condition).
652+
* Cannot be used if the "include_node_modules" option is
653+
* also set.
654+
* * {string[]} include_node_modules
655+
* If set that option will include the given Node modules to
656+
* the files that are processed by Babel. Cannot be used if
657+
* the "exclude" option is also set.
652658
*
653659
* @param {function} callback
654660
* @param {object} encoreOptions

lib/WebpackConfig.js

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class WebpackConfig {
8080
fonts: false
8181
};
8282
this.babelOptions = {
83-
exclude: /(node_modules|bower_components)/,
83+
exclude: /(node_modules|bower_components)/
8484
};
8585

8686
// Features/Loaders options callbacks
@@ -316,11 +316,40 @@ class WebpackConfig {
316316
this.babelConfigurationCallback = callback;
317317

318318
for (const optionKey of Object.keys(options)) {
319-
if (!(optionKey in this.babelOptions)) {
319+
if (optionKey === 'include_node_modules') {
320+
if (Object.keys(options).includes('exclude')) {
321+
throw new Error('"include_node_modules" and "exclude" options can\'t be used together when calling configureBabel().');
322+
}
323+
324+
if (!Array.isArray(options[optionKey])) {
325+
throw new Error('Option "include_node_modules" passed to configureBabel() must be an Array.');
326+
}
327+
328+
this.babelOptions['exclude'] = (filePath) => {
329+
// Don't exclude modules outside of node_modules/bower_components
330+
if (!/(node_modules|bower_components)/.test(filePath)) {
331+
return false;
332+
}
333+
334+
// Don't exclude whitelisted Node modules
335+
const whitelistedModules = options[optionKey].map(
336+
module => path.join('node_modules', module) + path.sep
337+
);
338+
339+
for (const modulePath of whitelistedModules) {
340+
if (filePath.includes(modulePath)) {
341+
return false;
342+
}
343+
}
344+
345+
// Exclude other modules
346+
return true;
347+
};
348+
} else if (!(optionKey in this.babelOptions)) {
320349
throw new Error(`Invalid option "${optionKey}" passed to configureBabel(). Valid keys are ${Object.keys(this.babelOptions).join(', ')}`);
350+
} else {
351+
this.babelOptions[optionKey] = options[optionKey];
321352
}
322-
323-
this.babelOptions[optionKey] = options[optionKey];
324353
}
325354
}
326355

test/WebpackConfig.js

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,44 @@ describe('WebpackConfig object', () => {
410410
expect(String(config.babelOptions.exclude)).to.equal(String(/(node_modules|bower_components)/));
411411
});
412412

413+
it('Calling with "exclude" option', () => {
414+
const config = createConfig();
415+
config.configureBabel(() => {}, { exclude: 'foo' });
416+
417+
expect(config.babelOptions.exclude).to.equal('foo');
418+
});
419+
420+
it('Calling with "include_node_modules" option', () => {
421+
const config = createConfig();
422+
config.configureBabel(() => {}, { include_node_modules: ['foo', 'bar'] });
423+
424+
expect(config.babelOptions.exclude).to.be.a('Function');
425+
426+
const includedPaths = [
427+
path.join('test', 'lib', 'index.js'),
428+
path.join('test', 'node_modules', 'foo', 'index.js'),
429+
path.join('test', 'node_modules', 'foo', 'lib', 'index.js'),
430+
path.join('test', 'node_modules', 'bar', 'lib', 'index.js'),
431+
path.join('test', 'node_modules', 'baz', 'node_modules', 'foo', 'index.js'),
432+
];
433+
434+
const excludedPaths = [
435+
path.join('test', 'bower_components', 'foo', 'index.js'),
436+
path.join('test', 'bower_components', 'bar', 'index.js'),
437+
path.join('test', 'bower_components', 'baz', 'index.js'),
438+
path.join('test', 'node_modules', 'baz', 'lib', 'index.js'),
439+
path.join('test', 'node_modules', 'baz', 'lib', 'foo', 'index.js')
440+
];
441+
442+
for (const filePath of includedPaths) {
443+
expect(config.babelOptions.exclude(filePath)).to.equal(false);
444+
}
445+
446+
for (const filePath of excludedPaths) {
447+
expect(config.babelOptions.exclude(filePath)).to.equal(true);
448+
}
449+
});
450+
413451
it('Calling with non-callback throws an error', () => {
414452
const config = createConfig();
415453

@@ -427,19 +465,28 @@ describe('WebpackConfig object', () => {
427465
}).to.throw('configureBabel() cannot be called because your app already has Babel configuration');
428466
});
429467

430-
it('Pass valid config', () => {
468+
it('Pass invalid config', () => {
431469
const config = createConfig();
432-
config.configureBabel(() => {}, { exclude: 'foo' });
433470

434-
expect(config.babelOptions.exclude).to.equal('foo');
471+
expect(() => {
472+
config.configureBabel(() => {}, { fake_option: 'foo' });
473+
}).to.throw('Invalid option "fake_option" passed to configureBabel()');
435474
});
436475

437-
it('Pass invalid config', () => {
476+
it('Calling with both "include_node_modules" and "exclude" options', () => {
438477
const config = createConfig();
439478

440479
expect(() => {
441-
config.configureBabel(() => {}, { fake_option: 'foo' });
442-
}).to.throw('Invalid option "fake_option" passed to configureBabel()');
480+
config.configureBabel(() => {}, { exclude: 'foo', include_node_modules: ['bar', 'baz'] });
481+
}).to.throw('can\'t be used together');
482+
});
483+
484+
it('Calling with an invalid "include_node_modules" option value', () => {
485+
const config = createConfig();
486+
487+
expect(() => {
488+
config.configureBabel(() => {}, { include_node_modules: 'foo' });
489+
}).to.throw('must be an Array');
443490
});
444491
});
445492

0 commit comments

Comments
 (0)