replace micromatch with glob-to-regexp for sideEffects flag
This commit is contained in:
parent
9b849e8d9c
commit
a3f2314a63
|
@ -5,7 +5,7 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const mm = require("micromatch");
|
||||
const glob2regexp = require("glob-to-regexp");
|
||||
const { STAGE_DEFAULT } = require("../OptimizationStages");
|
||||
const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency");
|
||||
const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportSpecifierDependency");
|
||||
|
@ -20,12 +20,38 @@ const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportS
|
|||
* @property {string} exportName the name of the export
|
||||
*/
|
||||
|
||||
/** @type {WeakMap<any, Map<string, RegExp>>} */
|
||||
const globToRegexpCache = new WeakMap();
|
||||
|
||||
/**
|
||||
* @param {string} glob the pattern
|
||||
* @param {Map<string, RegExp>} cache the glob to RegExp cache
|
||||
* @returns {RegExp} a regular expression
|
||||
*/
|
||||
const globToRegexp = (glob, cache) => {
|
||||
const cacheEntry = cache.get(glob);
|
||||
if (cacheEntry !== undefined) return cacheEntry;
|
||||
if (!glob.includes("/")) {
|
||||
glob = `**/${glob}`;
|
||||
}
|
||||
const baseRegexp = glob2regexp(glob, { globstar: true, extended: true });
|
||||
const regexpSource = baseRegexp.source;
|
||||
const regexp = new RegExp("^(\\./)?" + regexpSource.slice(1));
|
||||
cache.set(glob, regexp);
|
||||
return regexp;
|
||||
};
|
||||
|
||||
class SideEffectsFlagPlugin {
|
||||
/**
|
||||
* @param {Compiler} compiler webpack compiler
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
let cache = globToRegexpCache.get(compiler.root);
|
||||
if (cache === undefined) {
|
||||
cache = new Map();
|
||||
globToRegexpCache.set(compiler.root, cache);
|
||||
}
|
||||
compiler.hooks.normalModuleFactory.tap("SideEffectsFlagPlugin", nmf => {
|
||||
nmf.hooks.module.tap("SideEffectsFlagPlugin", (module, data) => {
|
||||
const resolveData = data.resourceResolveData;
|
||||
|
@ -37,7 +63,8 @@ class SideEffectsFlagPlugin {
|
|||
const sideEffects = resolveData.descriptionFileData.sideEffects;
|
||||
const hasSideEffects = SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
resolveData.relativePath,
|
||||
sideEffects
|
||||
sideEffects,
|
||||
cache
|
||||
);
|
||||
if (!hasSideEffects) {
|
||||
module.factoryMeta.sideEffectFree = true;
|
||||
|
@ -137,22 +164,17 @@ class SideEffectsFlagPlugin {
|
|||
});
|
||||
}
|
||||
|
||||
static moduleHasSideEffects(moduleName, flagValue) {
|
||||
static moduleHasSideEffects(moduleName, flagValue, cache) {
|
||||
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
|
||||
});
|
||||
return globToRegexp(flagValue, cache).test(moduleName);
|
||||
case "object":
|
||||
return flagValue.some(glob =>
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(moduleName, glob)
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(moduleName, glob, cache)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
"eslint-scope": "^4.0.0",
|
||||
"events": "^3.0.0",
|
||||
"find-cache-dir": "^2.1.0",
|
||||
"glob-to-regexp": "^0.4.1",
|
||||
"json-parse-better-errors": "^1.0.2",
|
||||
"loader-runner": "3.0.0",
|
||||
"loader-utils": "^1.1.0",
|
||||
"memory-fs": "~0.4.1",
|
||||
"micromatch": "^3.1.8",
|
||||
"mkdirp": "~0.5.0",
|
||||
"neo-async": "^2.5.0",
|
||||
"schema-utils": "^1.0.0",
|
||||
|
|
|
@ -5,16 +5,28 @@ const SideEffectsFlagPlugin = require("../lib/optimize/SideEffectsFlagPlugin");
|
|||
describe("SideEffectsFlagPlugin", () => {
|
||||
it("should assume true", () => {
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./foo/bar.js", undefined)
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./foo/bar.js",
|
||||
undefined,
|
||||
new Map()
|
||||
)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("should understand boolean values", () => {
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./foo/bar.js", true)
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./foo/bar.js",
|
||||
true,
|
||||
new Map()
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./foo/bar.js", false)
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./foo/bar.js",
|
||||
false,
|
||||
new Map()
|
||||
)
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
|
@ -22,90 +34,110 @@ describe("SideEffectsFlagPlugin", () => {
|
|||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"./src/**/*.js"
|
||||
"./src/**/*.js",
|
||||
new Map()
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./x.js", "./src/**/*.js")
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./x.js",
|
||||
"./src/**/*.js",
|
||||
new Map()
|
||||
)
|
||||
).toBe(false);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"./**/src/x/y/z.js"
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "**.js")
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"./src/**/z.js"
|
||||
"./**/src/x/y/z.js",
|
||||
new Map()
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"./**/x/**/z.js"
|
||||
"**.js",
|
||||
new Map()
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"./**/src/**"
|
||||
"./src/**/z.js",
|
||||
new Map()
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "./**/src/*")
|
||||
).toBe(false);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "*.js")
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"./**/x/**/z.js",
|
||||
new Map()
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "x/**/z.js")
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"./**/src/**",
|
||||
new Map()
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"./**/src/*",
|
||||
new Map()
|
||||
)
|
||||
).toBe(false);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"src/**/z.js"
|
||||
"*.js",
|
||||
new Map()
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"src/**/{x,y,z}.js"
|
||||
"x/**/z.js",
|
||||
new Map()
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"src/**/[x-z].js"
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"src/**/[[:lower:]].js"
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "!*.js")
|
||||
).toBe(false);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", "!**/*.js")
|
||||
).toBe(false);
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"src/**/z.js",
|
||||
new Map()
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"src/**/{x,y,z}.js",
|
||||
new Map()
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
"src/**/[x-z].js",
|
||||
new Map()
|
||||
)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("should understand arrays", () => {
|
||||
const array = ["./src/**/*.js", "./dirty.js"];
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./src/x/y/z.js", array)
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects(
|
||||
"./src/x/y/z.js",
|
||||
array,
|
||||
new Map()
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./dirty.js", array)
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./dirty.js", array, new Map())
|
||||
).toBe(true);
|
||||
expect(
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./clean.js", array)
|
||||
SideEffectsFlagPlugin.moduleHasSideEffects("./clean.js", array, new Map())
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2226,6 +2226,11 @@ getpass@^0.1.1:
|
|||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
glob-to-regexp@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
|
||||
integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
|
||||
|
||||
glob@^5.0.15:
|
||||
version "5.0.15"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
|
||||
|
|
Loading…
Reference in New Issue