Skip to content

Commit

Permalink
Support issuer filtering when matching rules (fixes #149) (#150)
Browse files Browse the repository at this point in the history
* fix(loader): add support for issuer when matching rules

With Webpack v2 one can use svg-sprite-loader for JavaScript/JSX modules
while still using other loaders in other contexts (CSS for example).
This is possible by using the "issuer" configuration for loader rules.
For use with Webpack v1 an error will still occur.

Fixes #149

* test(loader): add coverage for Webpack v1+2 handling of issuer in rules

This adds coverage to the loader tests so that the "issuer" attribute on loader rules is honored
when evaluating Webpack v2 config. For v1 configuration the issuer attribute is ignored and the
previous errors are expected.
  • Loading branch information
coleturner authored and kisenka committed Jul 17, 2017
1 parent 0640a40 commit 5d21b2f
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 5 deletions.
3 changes: 2 additions & 1 deletion lib/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ module.exports = function loader(content) {
throw new Exceptions.InvalidRuntimeException(config.runtimeGenerator);
}

const matchedRules = utils.getMatchedRules(resource, utils.getLoadersRules(compiler));
const issuer = loaderContext._module && loaderContext._module.issuer;
const matchedRules = utils.getMatchedRules(resource, utils.getLoadersRules(compiler), issuer);
if (matchedRules.length > 1 && !compiler.isChild()) {
this.emitWarning(new Exceptions.SeveralRulesAppliedException(resource, matchedRules));
}
Expand Down
22 changes: 19 additions & 3 deletions lib/utils/get-matched-rules.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
// eslint-disable-next-line import/no-extraneous-dependencies
/* eslint-disable import/no-extraneous-dependencies */
const ruleMatcher = require('webpack/lib/ModuleFilenameHelpers').matchObject;
const isWebpack1 = require('./is-webpack-1');
const RuleSet = !isWebpack1 ? require('webpack/lib/RuleSet') : null;

/**
* @param {string} request
* @param {Rule[]} rules Webpack loaders config
* @return {Rule[]}
*/
function getMatchedRules(request, rules) {
return rules.filter(rule => ruleMatcher(rule, request));
function getMatchedRules(request, rules, issuer) {
const matchedRules = rules.filter(rule => ruleMatcher(rule, request));

if (issuer) {
return matchedRules.filter((rule) => {
// If rule doesn't have an issuer or RuleSet is not available
if (!rule.issuer || !RuleSet) {
return true;
}

const matcher = RuleSet.normalizeCondition(rule.issuer);
return matcher(issuer);
});
}

return matchedRules;
}

module.exports = getMatchedRules;
17 changes: 16 additions & 1 deletion test/loader.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ describe('loader and plugin', () => {
errors[0].error.should.be.instanceOf(Exceptions.InvalidRuntimeException);
});

it('should warn if several rules applied to module', async () => {
it('should warn if several rules applied to module without issuer applied', async () => {
const { warnings } = await compile({
entry: './entry',
module: rules(
Expand All @@ -64,6 +64,21 @@ describe('loader and plugin', () => {

assets['main.js'].source().should.contain('olala');
});

it('should filter rules against issuer', async () => {
const { warnings } = await compile({
entry: './entry',
module: rules(
svgRule(),
rule({ test: /\.svg$/, loader: loaderPath, issuer: /\.css$/ })
)
});

warnings.should.be.lengthOf(isWebpack1 ? 2 : 0);
if (isWebpack1) {
warnings[0].warning.should.be.instanceOf(Exceptions.SeveralRulesAppliedException);
}
});
});

describe('extract mode', () => {
Expand Down

0 comments on commit 5d21b2f

Please sign in to comment.