Skip to content
Permalink
Browse files
feat(IgnorePlugin): allow user to provide his own check functions
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 6235e99248b3c6ecdad436438c233c5d82145210
Showing 27 changed files with 210 additions and 16 deletions.
@@ -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);
@@ -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);
}

/**
@@ -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);
}

/**
@@ -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"
}
}
}
]
}
@@ -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
}
@@ -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");
@@ -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();
});
@@ -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);
}
})
]
};
@@ -0,0 +1 @@
module.exports = "ignored";
@@ -0,0 +1 @@
module.exports = "normal";
@@ -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();
});
@@ -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");
@@ -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();
});
@@ -0,0 +1,8 @@
"use strict";

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

module.exports = {
entry: "./test.js",
plugins: [new IgnorePlugin(/ignored-module/, /folder-b/)]
};
@@ -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/
})
]
};
@@ -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/
})
]
};
@@ -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/
})
]
};
@@ -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.