Skip to content

Commit

Permalink
feat(IgnorePlugin): allow user to provide his own check functions
Browse files Browse the repository at this point in the history
The user can provide checkResource and checkContext functions that
will be called with current resource or context respectively.

These functions should return a boolean to decide whether the module
should be ignored or not.

Now the constructor can accept a single option object.

```
const resourceRegExp = /a_regex/
const contextRegExp = /another_regex/

// before:
new webpack.IgnorePlugin(resourceRegExp, contextRegExp)

// alternative:
new webpack.ignorePlugin({resourceRegExp, contextRegExp})
```

Note that from Webpack 5, only passing an object will be allowed,
so we could encourage people to migrate already.
  • Loading branch information
AoDev committed Aug 14, 2018
1 parent a02bf99 commit 6235e99
Show file tree
Hide file tree
Showing 27 changed files with 210 additions and 16 deletions.
41 changes: 30 additions & 11 deletions lib/IgnorePlugin.js
Expand Up @@ -4,18 +4,30 @@
*/
"use strict";

const validateOptions = require("schema-utils");
const schema = require("../schemas/plugins/IgnorePlugin.json");

/** @typedef {import("./Compiler")} Compiler */

class IgnorePlugin {
/**
* @param {RegExp} resourceRegExp A RegExp to test the request against
* @param {RegExp=} contextRegExp A RegExp to test the context (directory) against
* @param {object} options IgnorePlugin options
* @param {RegExp} options.resourceRegExp - A RegExp to test the request against
* @param {RegExp} options.contextRegExp - A RegExp to test the context (directory) against
* @param {function(string): boolean=} options.checkResource - A filter function for resource
* @param {function(string): boolean=} options.checkContext - A filter function for context
*/
constructor(resourceRegExp, contextRegExp) {
/** @private @type {RegExp} */
this.resourceRegExp = resourceRegExp;
/** @private @type {RegExp} */
this.contextRegExp = contextRegExp;
constructor(options) {
// TODO webpack 5 remove this compat-layer
if (arguments.length > 1 || options instanceof RegExp) {
options = {
resourceRegExp: arguments[0],
contextRegExp: arguments[1]
};
}

validateOptions(schema, options, "IgnorePlugin");
this.options = options;

/** @private @type {Function} */
this.checkIgnore = this.checkIgnore.bind(this);
Expand All @@ -27,10 +39,13 @@ class IgnorePlugin {
* and the resource given matches the regexp.
*/
checkResource(resource) {
if (!this.resourceRegExp) {
if (this.options.checkResource) {
return this.options.checkResource(resource);
}
if (!this.options.resourceRegExp) {
return false;
}
return this.resourceRegExp.test(resource);
return this.options.resourceRegExp.test(resource);
}

/**
Expand All @@ -39,10 +54,14 @@ class IgnorePlugin {
* or if context matches the given regexp.
*/
checkContext(context) {
if (!this.contextRegExp) {
if (this.options.checkContext) {
return this.options.checkContext(context);
}

if (!this.options.contextRegExp) {
return true;
}
return this.contextRegExp.test(context);
return this.options.contextRegExp.test(context);
}

/**
Expand Down
31 changes: 31 additions & 0 deletions schemas/plugins/IgnorePlugin.json
@@ -0,0 +1,31 @@
{
"type": "object",
"oneOf": [
{
"additionalProperties": false,
"properties": {
"resourceRegExp": {
"description": "A RegExp to test the request against",
"instanceof": "RegExp"
},
"contextRegExp": {
"description": "A RegExp to test the context (directory) against",
"instanceof": "RegExp"
}
}
},
{
"additionalProperties": false,
"properties": {
"checkResource": {
"description": "A filter function for resource",
"instanceof": "Function"
},
"checkContext": {
"description": "A filter function for context",
"instanceof": "Function"
}
}
}
]
}
Expand Up @@ -7,7 +7,11 @@ module.exports = {
output: {
filename: "[name].js"
},
plugins: [new IgnorePlugin(new RegExp(/intentionally-missing-module/))],
plugins: [
new IgnorePlugin({
resourceRegExp: new RegExp(/intentionally-missing-module/)
})
],
node: {
__dirname: false
}
Expand Down
@@ -0,0 +1 @@
module.exports = "ignored";
@@ -0,0 +1 @@
module.exports = require("./normal-module");
@@ -0,0 +1 @@
module.exports = "ignored";
@@ -0,0 +1 @@
module.exports = require("./ignored-module");
@@ -0,0 +1 @@
module.exports = "should be fine";
@@ -0,0 +1 @@
module.exports = require("./only-context-match-require");
20 changes: 20 additions & 0 deletions test/configCases/ignore/checkContextFn/test.js
@@ -0,0 +1,20 @@
/* globals it */
"use strict";

it("should ignore resources that match resource regex and context", function() {
expect(function() {
require("./folder-b/normal-module");
}).toThrowError();
});

it("should not ignore resources that match resource but not context", function() {
expect(function() {
require("./folder-a/normal-module");
}).not.toThrowError();
});

it("should not ignore resources that do not match resource but do match context", function() {
expect(function() {
require("./folder-b/only-context-match");
}).not.toThrowError();
});
17 changes: 17 additions & 0 deletions test/configCases/ignore/checkContextFn/webpack.config.js
@@ -0,0 +1,17 @@
"use strict";

const IgnorePlugin = require("../../../../lib/IgnorePlugin");

module.exports = {
entry: "./test.js",
plugins: [
new IgnorePlugin({
checkResource: function(resource) {
return /ignored-module/.test(resource);
},
checkContext: function(context) {
return /folder-b/.test(context);
}
})
]
};
1 change: 1 addition & 0 deletions test/configCases/ignore/checkResourceFn/ignored-module.js
@@ -0,0 +1 @@
module.exports = "ignored";
1 change: 1 addition & 0 deletions test/configCases/ignore/checkResourceFn/normal-module.js
@@ -0,0 +1 @@
module.exports = "normal";
13 changes: 13 additions & 0 deletions test/configCases/ignore/checkResourceFn/test.js
@@ -0,0 +1,13 @@
/* globals it */
"use strict";

it("should ignore ignored resources", function() {
expect(function() {
require("./ignored-module");
}).toThrowError();
});
it("should not ignore resources that do not match", function() {
expect(function() {
require("./normal-module");
}).not.toThrowError();
});
14 changes: 14 additions & 0 deletions test/configCases/ignore/checkResourceFn/webpack.config.js
@@ -0,0 +1,14 @@
"use strict";

const IgnorePlugin = require("../../../../lib/IgnorePlugin");

module.exports = {
entry: "./test.js",
plugins: [
new IgnorePlugin({
checkResource: function(resource) {
return /ignored-module/.test(resource);
}
})
]
};
@@ -0,0 +1 @@
module.exports = "ignored";
@@ -0,0 +1 @@
module.exports = require("./normal-module");
@@ -0,0 +1 @@
module.exports = "ignored";
@@ -0,0 +1 @@
module.exports = require("./ignored-module");
@@ -0,0 +1 @@
module.exports = "should be fine";
@@ -0,0 +1 @@
module.exports = require("./only-context-match-require");
36 changes: 36 additions & 0 deletions test/configCases/ignore/compatibilityLayer/test.js
@@ -0,0 +1,36 @@
/* globals it */
"use strict";

// TODO: remove in webpack 5
it("should ignore context modules that match resource regex and context (compat-layer)", function() {
const folderBContext = function(mod) {
require("./folder-b/" + mod);
};

expect(function() {
folderBContext("normal-module");
}).toThrowError();
});

it("should not ignore context modules that dont match the resource (compat-layer)", function() {
const folderBContext = function(mod) {
require("./folder-b/" + mod);
};

expect(function() {
folderBContext("only-context-match");
}).not.toThrowError();
});

it("should not ignore context modules that dont match the context (compat-layer)", function() {
const folderBContext = function(mod) {
require("./folder-a/" + mod);
};

expect(function() {
folderBContext("normal-module");
}).not.toThrowError();
expect(function() {
folderBContext("ignored-module");
}).not.toThrowError();
});
8 changes: 8 additions & 0 deletions test/configCases/ignore/compatibilityLayer/webpack.config.js
@@ -0,0 +1,8 @@
"use strict";

const IgnorePlugin = require("../../../../lib/IgnorePlugin");

module.exports = {
entry: "./test.js",
plugins: [new IgnorePlugin(/ignored-module/, /folder-b/)]
};
Expand Up @@ -4,5 +4,9 @@ const IgnorePlugin = require("../../../../lib/IgnorePlugin");

module.exports = {
entry: "./test.js",
plugins: [new IgnorePlugin(/ignored-module/)]
plugins: [
new IgnorePlugin({
resourceRegExp: /ignored-module/
})
]
};
6 changes: 5 additions & 1 deletion test/configCases/ignore/only-resource/webpack.config.js
Expand Up @@ -4,5 +4,9 @@ const IgnorePlugin = require("../../../../lib/IgnorePlugin");

module.exports = {
entry: "./test.js",
plugins: [new IgnorePlugin(/ignored-module/)]
plugins: [
new IgnorePlugin({
resourceRegExp: /ignored-module/
})
]
};
Expand Up @@ -4,5 +4,10 @@ const IgnorePlugin = require("../../../../lib/IgnorePlugin");

module.exports = {
entry: "./test.js",
plugins: [new IgnorePlugin(/ignored-module/, /folder-b/)]
plugins: [
new IgnorePlugin({
resourceRegExp: /ignored-module/,
contextRegExp: /folder-b/
})
]
};
Expand Up @@ -4,5 +4,10 @@ const IgnorePlugin = require("../../../../lib/IgnorePlugin");

module.exports = {
entry: "./test.js",
plugins: [new IgnorePlugin(/ignored-module/, /folder-b/)]
plugins: [
new IgnorePlugin({
resourceRegExp: /ignored-module/,
contextRegExp: /folder-b/
})
]
};

0 comments on commit 6235e99

Please sign in to comment.