Skip to content

Commit 15ab027

Browse files
authored
Merge pull request webpack#6536 from jevan0307/sideEffects-selectors
Add support for more complex sideEffects selectors
2 parents 1611ce1 + a63bb77 commit 15ab027

File tree

19 files changed

+687
-11
lines changed

19 files changed

+687
-11
lines changed

lib/optimize/SideEffectsFlagPlugin.js

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
"use strict";
66

7+
const mm = require("micromatch");
78
const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
89
const HarmonyImportSideEffectDependency = require("../dependencies/HarmonyImportSideEffectDependency");
910
const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportSpecifierDependency");
@@ -15,8 +16,8 @@ class SideEffectsFlagPlugin {
1516
const resolveData = data.resourceResolveData;
1617
if(resolveData && resolveData.descriptionFileData && resolveData.relativePath) {
1718
const sideEffects = resolveData.descriptionFileData.sideEffects;
18-
const isSideEffectFree = sideEffects === false; // TODO allow more complex expressions
19-
if(isSideEffectFree) {
19+
const hasSideEffects = SideEffectsFlagPlugin.moduleHasSideEffects(resolveData.relativePath, sideEffects);
20+
if(!hasSideEffects) {
2021
module.factoryMeta.sideEffectFree = true;
2122
}
2223
}
@@ -117,5 +118,23 @@ class SideEffectsFlagPlugin {
117118
});
118119
});
119120
}
121+
122+
static moduleHasSideEffects(moduleName, flagValue) {
123+
switch(typeof flagValue) {
124+
case "undefined":
125+
return true;
126+
case "boolean":
127+
return flagValue;
128+
case "string":
129+
if(process.platform === "win32") {
130+
flagValue = flagValue.replace(/\\/g, "/");
131+
}
132+
return mm.isMatch(moduleName, flagValue, {
133+
matchBase: true
134+
});
135+
case "object":
136+
return flagValue.some(glob => SideEffectsFlagPlugin.moduleHasSideEffects(moduleName, glob));
137+
}
138+
}
120139
}
121140
module.exports = SideEffectsFlagPlugin;

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"loader-runner": "^2.3.0",
1616
"loader-utils": "^1.1.0",
1717
"memory-fs": "~0.4.1",
18+
"micromatch": "^3.1.8",
1819
"mkdirp": "~0.5.0",
1920
"neo-async": "^2.5.0",
2021
"node-libs-browser": "^2.0.0",
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"use strict";
2+
3+
const SideEffectsFlagPlugin = require("../lib/optimize/SideEffectsFlagPlugin");
4+
5+
describe("SideEffectsFlagPlugin", () => {
6+
it("should assume true", () => {
7+
SideEffectsFlagPlugin.moduleHasSideEffects("./foo/bar.js", undefined).should.eql(true);
8+
});
9+
10+
it("should understand boolean values", () => {
11+
SideEffectsFlagPlugin.moduleHasSideEffects("./foo/bar.js", true).should.eql(true);
12+
SideEffectsFlagPlugin.moduleHasSideEffects("./foo/bar.js", false).should.eql(false);
13+
});
14+
15+
it("should understand a glob", () => {
16+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "./src/**/*.js").should.eql(true);
17+
SideEffectsFlagPlugin.moduleHasSideEffects("./x.js", "./src/**/*.js").should.eql(false);
18+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "./**/src/x/y/z.js").should.eql(true);
19+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "**.js").should.eql(true);
20+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "./src/**/z.js").should.eql(true);
21+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "./**/x/**/z.js").should.eql(true);
22+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "./**/src/**").should.eql(true);
23+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "./**/src/*").should.eql(false);
24+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "*.js").should.eql(true);
25+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "x/**/z.js").should.eql(false);
26+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "src/**/z.js").should.eql(true);
27+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "src/**/{x,y,z}.js").should.eql(true);
28+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "src/**/[x-z].js").should.eql(true);
29+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "src/**/[[:lower:]].js").should.eql(true);
30+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "!*.js").should.eql(false);
31+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "!**/*.js").should.eql(false);
32+
});
33+
34+
it("should understand arrays", () => {
35+
const array = [
36+
"./src/**/*.js",
37+
"./dirty.js",
38+
];
39+
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", array).should.eql(true);
40+
SideEffectsFlagPlugin.moduleHasSideEffects("./dirty.js", array).should.eql(true);
41+
SideEffectsFlagPlugin.moduleHasSideEffects("./clean.js", array).should.eql(false);
42+
});
43+
});

test/configCases/side-effects/side-effects-override/webpack.config.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ const path = require("path");
22
module.exports = {
33
mode: "production",
44
module: {
5-
rules: [
6-
7-
{
5+
rules: [{
86
test: path.resolve(__dirname, "node_modules/pmodule"),
97
sideEffects: true
108
},
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { log as booleanValueModuleLog } from "boolean-value-module/tracker";
2+
import booleanValueModule from "boolean-value-module";
3+
import { log as globValueModuleLog } from "glob-value-module/tracker";
4+
import globValueModule from "glob-value-module";
5+
6+
it("should handle a boolean", function() {
7+
booleanValueModule.should.be.eql("def");
8+
booleanValueModuleLog.should.be.eql(["index.js"]);
9+
});
10+
11+
it("should handle globs", function() {
12+
globValueModule.should.be.eql("def");
13+
globValueModuleLog.should.be.eql([
14+
"./src/a.js",
15+
"a.js",
16+
"index.js",
17+
]);
18+
});

test/configCases/side-effects/side-effects-values/node_modules/boolean-value-module/a.js

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/configCases/side-effects/side-effects-values/node_modules/boolean-value-module/b.js

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/configCases/side-effects/side-effects-values/node_modules/boolean-value-module/c.js

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/configCases/side-effects/side-effects-values/node_modules/boolean-value-module/index.js

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/configCases/side-effects/side-effects-values/node_modules/boolean-value-module/package.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/configCases/side-effects/side-effects-values/node_modules/boolean-value-module/tracker.js

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/configCases/side-effects/side-effects-values/node_modules/glob-value-module/a.js

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/configCases/side-effects/side-effects-values/node_modules/glob-value-module/b.js

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/configCases/side-effects/side-effects-values/node_modules/glob-value-module/index.js

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/configCases/side-effects/side-effects-values/node_modules/glob-value-module/package.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/configCases/side-effects/side-effects-values/node_modules/glob-value-module/src/a.js

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/configCases/side-effects/side-effects-values/node_modules/glob-value-module/tracker.js

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
mode: "production",
3+
module: {
4+
rules: []
5+
}
6+
};

0 commit comments

Comments
 (0)