Skip to content
This repository was archived by the owner on Dec 5, 2019. It is now read-only.

Commit 5861728

Browse files
committed
feat(options): add chunkFilter option
Adds a chunkFilter option to filter chunks. The existing test/include/exclude options are not useful when the filenames are generated at buildtime, e.g. `[hash].[ext]`.
1 parent bf36e21 commit 5861728

File tree

6 files changed

+176
-0
lines changed

6 files changed

+176
-0
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,20 @@ new UglifyJsPlugin({
8989
})
9090
```
9191

92+
### `chunkFilter`
93+
94+
Type: `Function<(chunk) -> boolean>`
95+
Default: `() => true`
96+
97+
Test for Webpack chunks to include.
98+
99+
```js
100+
// in your webpack.config.js
101+
new UglifyJsPlugin({
102+
chunkFilter: chunk => chunk.name === 'vendor'
103+
})
104+
```
105+
92106
### `cache`
93107

94108
Type: `Boolean|String`

src/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class UglifyJsPlugin {
2020
validateOptions(schema, options, 'UglifyJs Plugin');
2121

2222
const {
23+
chunkFilter = () => true,
2324
minify,
2425
uglifyOptions = {},
2526
test = /\.js(\?.*)?$/i,
@@ -34,6 +35,7 @@ class UglifyJsPlugin {
3435
} = options;
3536

3637
this.options = {
38+
chunkFilter,
3739
test,
3840
warningsFilter,
3941
extractComments,
@@ -166,6 +168,7 @@ class UglifyJsPlugin {
166168
const tasks = [];
167169

168170
Array.from(chunks)
171+
.filter((c) => this.options.chunkFilter(c))
169172
.reduce((acc, chunk) => acc.concat(chunk.files || []), [])
170173
.concat(compilation.additionalChunkAssets || [])
171174
.filter(ModuleFilenameHelpers.matchObject.bind(null, this.options))

src/options.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@
6464
}
6565
]
6666
},
67+
"chunkFilter": {
68+
"instanceof": "Function"
69+
},
6770
"cache": {
6871
"anyOf": [
6972
{
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`when applied with \`chunkFilter\` option matches snapshot for a single \`chunkFilter\`: entry.3d56c95d56b5806e32ad.js 1`] = `
4+
"/******/ (function(modules) { // webpackBootstrap
5+
/******/ // The module cache
6+
/******/ var installedModules = {};
7+
/******/
8+
/******/ // The require function
9+
/******/ function __webpack_require__(moduleId) {
10+
/******/
11+
/******/ // Check if module is in cache
12+
/******/ if(installedModules[moduleId]) {
13+
/******/ return installedModules[moduleId].exports;
14+
/******/ }
15+
/******/ // Create a new module (and put it into the cache)
16+
/******/ var module = installedModules[moduleId] = {
17+
/******/ i: moduleId,
18+
/******/ l: false,
19+
/******/ exports: {}
20+
/******/ };
21+
/******/
22+
/******/ // Execute the module function
23+
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
24+
/******/
25+
/******/ // Flag the module as loaded
26+
/******/ module.l = true;
27+
/******/
28+
/******/ // Return the exports of the module
29+
/******/ return module.exports;
30+
/******/ }
31+
/******/
32+
/******/
33+
/******/ // expose the modules object (__webpack_modules__)
34+
/******/ __webpack_require__.m = modules;
35+
/******/
36+
/******/ // expose the module cache
37+
/******/ __webpack_require__.c = installedModules;
38+
/******/
39+
/******/ // define getter function for harmony exports
40+
/******/ __webpack_require__.d = function(exports, name, getter) {
41+
/******/ if(!__webpack_require__.o(exports, name)) {
42+
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
43+
/******/ }
44+
/******/ };
45+
/******/
46+
/******/ // define __esModule on exports
47+
/******/ __webpack_require__.r = function(exports) {
48+
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
49+
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
50+
/******/ }
51+
/******/ Object.defineProperty(exports, '__esModule', { value: true });
52+
/******/ };
53+
/******/
54+
/******/ // create a fake namespace object
55+
/******/ // mode & 1: value is a module id, require it
56+
/******/ // mode & 2: merge all properties of value into the ns
57+
/******/ // mode & 4: return value when already ns object
58+
/******/ // mode & 8|1: behave like require
59+
/******/ __webpack_require__.t = function(value, mode) {
60+
/******/ if(mode & 1) value = __webpack_require__(value);
61+
/******/ if(mode & 8) return value;
62+
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
63+
/******/ var ns = Object.create(null);
64+
/******/ __webpack_require__.r(ns);
65+
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
66+
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
67+
/******/ return ns;
68+
/******/ };
69+
/******/
70+
/******/ // getDefaultExport function for compatibility with non-harmony modules
71+
/******/ __webpack_require__.n = function(module) {
72+
/******/ var getter = module && module.__esModule ?
73+
/******/ function getDefault() { return module['default']; } :
74+
/******/ function getModuleExports() { return module; };
75+
/******/ __webpack_require__.d(getter, 'a', getter);
76+
/******/ return getter;
77+
/******/ };
78+
/******/
79+
/******/ // Object.prototype.hasOwnProperty.call
80+
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
81+
/******/
82+
/******/ // __webpack_public_path__
83+
/******/ __webpack_require__.p = \\"\\";
84+
/******/
85+
/******/
86+
/******/ // Load entry module and return exports
87+
/******/ return __webpack_require__(__webpack_require__.s = 1);
88+
/******/ })
89+
/************************************************************************/
90+
/******/ ([
91+
/* 0 */,
92+
/* 1 */
93+
/***/ (function(module, exports) {
94+
95+
// foo
96+
/* @preserve*/
97+
// bar
98+
var a = 2 + 2;
99+
100+
module.exports = function Foo() {
101+
var b = 2 + 2;
102+
console.log(b + 1 + 2);
103+
};
104+
105+
106+
/***/ })
107+
/******/ ]);"
108+
`;
109+
110+
exports[`when applied with \`chunkFilter\` option matches snapshot for a single \`chunkFilter\`: errors 1`] = `Array []`;
111+
112+
exports[`when applied with \`chunkFilter\` option matches snapshot for a single \`chunkFilter\`: included.800c2a223cf78009dc09.js 1`] = `"!function(n){var r={};function o(e){if(r[e])return r[e].exports;var t=r[e]={i:e,l:!1,exports:{}};return n[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}o.m=n,o.c=r,o.d=function(e,t,n){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},o.r=function(e){\\"undefined\\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\\"Module\\"}),Object.defineProperty(e,\\"__esModule\\",{value:!0})},o.t=function(t,e){if(1&e&&(t=o(t)),8&e)return t;if(4&e&&\\"object\\"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,\\"default\\",{enumerable:!0,value:t}),2&e&&\\"string\\"!=typeof t)for(var r in t)o.d(n,r,function(e){return t[e]}.bind(null,r));return n},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,\\"a\\",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p=\\"\\",o(o.s=0)}([function(e,t){e.exports=function(){console.log(7)}}]);"`;
113+
114+
exports[`when applied with \`chunkFilter\` option matches snapshot for a single \`chunkFilter\`: warnings 1`] = `Array []`;

test/chunk-filter-option.test.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import UglifyJsPlugin from '../src/index';
2+
3+
import { cleanErrorStack, createCompiler, compile } from './helpers';
4+
5+
describe('when applied with `chunkFilter` option', () => {
6+
let compiler;
7+
8+
beforeEach(() => {
9+
compiler = createCompiler({
10+
entry: {
11+
included: `${__dirname}/fixtures/included1.js`,
12+
entry: `${__dirname}/fixtures/entry.js`,
13+
},
14+
});
15+
});
16+
17+
it('matches snapshot for a single `chunkFilter`', () => {
18+
new UglifyJsPlugin({
19+
chunkFilter: (chunk) => chunk.name === 'included',
20+
}).apply(compiler);
21+
22+
return compile(compiler).then((stats) => {
23+
const errors = stats.compilation.errors.map(cleanErrorStack);
24+
const warnings = stats.compilation.warnings.map(cleanErrorStack);
25+
26+
expect(errors).toMatchSnapshot('errors');
27+
expect(warnings).toMatchSnapshot('warnings');
28+
29+
for (const file in stats.compilation.assets) {
30+
if (
31+
Object.prototype.hasOwnProperty.call(stats.compilation.assets, file)
32+
) {
33+
expect(stats.compilation.assets[file].source()).toMatchSnapshot(file);
34+
}
35+
}
36+
});
37+
});
38+
});

test/validation.test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ it('validation', () => {
2626
new UglifyJsPlugin({ exclude: [/foo/] });
2727
}).not.toThrow();
2828

29+
expect(() => {
30+
new UglifyJsPlugin({ chunkFilter: () => false });
31+
}).not.toThrow();
32+
2933
expect(() => {
3034
new UglifyJsPlugin({ doesntExist: true });
3135
}).toThrowErrorMatchingSnapshot();

0 commit comments

Comments
 (0)