Skip to content

Commit

Permalink
Merge pull request #6536 from jevan0307/sideEffects-selectors
Browse files Browse the repository at this point in the history
Add support for more complex sideEffects selectors
  • Loading branch information
sokra committed Feb 24, 2018
2 parents 1611ce1 + a63bb77 commit 15ab027
Show file tree
Hide file tree
Showing 19 changed files with 687 additions and 11 deletions.
23 changes: 21 additions & 2 deletions lib/optimize/SideEffectsFlagPlugin.js
Expand Up @@ -4,6 +4,7 @@
*/
"use strict";

const mm = require("micromatch");
const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
const HarmonyImportSideEffectDependency = require("../dependencies/HarmonyImportSideEffectDependency");
const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportSpecifierDependency");
Expand All @@ -15,8 +16,8 @@ class SideEffectsFlagPlugin {
const resolveData = data.resourceResolveData;
if(resolveData && resolveData.descriptionFileData && resolveData.relativePath) {
const sideEffects = resolveData.descriptionFileData.sideEffects;
const isSideEffectFree = sideEffects === false; // TODO allow more complex expressions
if(isSideEffectFree) {
const hasSideEffects = SideEffectsFlagPlugin.moduleHasSideEffects(resolveData.relativePath, sideEffects);
if(!hasSideEffects) {
module.factoryMeta.sideEffectFree = true;
}
}
Expand Down Expand Up @@ -117,5 +118,23 @@ class SideEffectsFlagPlugin {
});
});
}

static moduleHasSideEffects(moduleName, flagValue) {
switch(typeof flagValue) {
case "undefined":
return true;
case "boolean":
return flagValue;
case "string":
if(process.platform === "win32") {
flagValue = flagValue.replace(/\\/g, "/");
}
return mm.isMatch(moduleName, flagValue, {
matchBase: true
});
case "object":
return flagValue.some(glob => SideEffectsFlagPlugin.moduleHasSideEffects(moduleName, glob));
}
}
}
module.exports = SideEffectsFlagPlugin;
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -15,6 +15,7 @@
"loader-runner": "^2.3.0",
"loader-utils": "^1.1.0",
"memory-fs": "~0.4.1",
"micromatch": "^3.1.8",
"mkdirp": "~0.5.0",
"neo-async": "^2.5.0",
"node-libs-browser": "^2.0.0",
Expand Down
43 changes: 43 additions & 0 deletions test/SideEffectsFlagPlugin.unittest.js
@@ -0,0 +1,43 @@
"use strict";

const SideEffectsFlagPlugin = require("../lib/optimize/SideEffectsFlagPlugin");

describe("SideEffectsFlagPlugin", () => {
it("should assume true", () => {
SideEffectsFlagPlugin.moduleHasSideEffects("./foo/bar.js", undefined).should.eql(true);
});

it("should understand boolean values", () => {
SideEffectsFlagPlugin.moduleHasSideEffects("./foo/bar.js", true).should.eql(true);
SideEffectsFlagPlugin.moduleHasSideEffects("./foo/bar.js", false).should.eql(false);
});

it("should understand a glob", () => {
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "./src/**/*.js").should.eql(true);
SideEffectsFlagPlugin.moduleHasSideEffects("./x.js", "./src/**/*.js").should.eql(false);
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "./**/src/x/y/z.js").should.eql(true);
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "**.js").should.eql(true);
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "./src/**/z.js").should.eql(true);
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "./**/x/**/z.js").should.eql(true);
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "./**/src/**").should.eql(true);
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "./**/src/*").should.eql(false);
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "*.js").should.eql(true);
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "x/**/z.js").should.eql(false);
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "src/**/z.js").should.eql(true);
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "src/**/{x,y,z}.js").should.eql(true);
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "src/**/[x-z].js").should.eql(true);
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "src/**/[[:lower:]].js").should.eql(true);
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "!*.js").should.eql(false);
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "!**/*.js").should.eql(false);
});

it("should understand arrays", () => {
const array = [
"./src/**/*.js",
"./dirty.js",
];
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", array).should.eql(true);
SideEffectsFlagPlugin.moduleHasSideEffects("./dirty.js", array).should.eql(true);
SideEffectsFlagPlugin.moduleHasSideEffects("./clean.js", array).should.eql(false);
});
});
Expand Up @@ -2,9 +2,7 @@ const path = require("path");
module.exports = {
mode: "production",
module: {
rules: [

{
rules: [{
test: path.resolve(__dirname, "node_modules/pmodule"),
sideEffects: true
},
Expand Down
18 changes: 18 additions & 0 deletions test/configCases/side-effects/side-effects-values/index.js
@@ -0,0 +1,18 @@
import { log as booleanValueModuleLog } from "boolean-value-module/tracker";
import booleanValueModule from "boolean-value-module";
import { log as globValueModuleLog } from "glob-value-module/tracker";
import globValueModule from "glob-value-module";

it("should handle a boolean", function() {
booleanValueModule.should.be.eql("def");
booleanValueModuleLog.should.be.eql(["index.js"]);
});

it("should handle globs", function() {
globValueModule.should.be.eql("def");
globValueModuleLog.should.be.eql([
"./src/a.js",
"a.js",
"index.js",
]);
});

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

@@ -0,0 +1,6 @@
module.exports = {
mode: "production",
module: {
rules: []
}
};

0 comments on commit 15ab027

Please sign in to comment.