diff --git a/lib/NormalModuleFactory.js b/lib/NormalModuleFactory.js index 4ec7b2199..0cfdede23 100644 --- a/lib/NormalModuleFactory.js +++ b/lib/NormalModuleFactory.js @@ -249,6 +249,7 @@ class NormalModuleFactory extends Tapable { loaders, resource, resourceResolveData, + settings, type, parser: this.getParser(type, settings.parser), resolveOptions diff --git a/lib/optimize/SideEffectsFlagPlugin.js b/lib/optimize/SideEffectsFlagPlugin.js index b2f066dbd..58cc3be0f 100644 --- a/lib/optimize/SideEffectsFlagPlugin.js +++ b/lib/optimize/SideEffectsFlagPlugin.js @@ -24,6 +24,12 @@ class SideEffectsFlagPlugin { return module; }); + nmf.hooks.module.tap("SideEffectsFlagPlugin", (module, data) => { + if(data.settings.sideEffects === false) + module.factoryMeta.sideEffectFree = true; + else if(data.settings.sideEffects === true) + module.factoryMeta.sideEffectFree = false; + }); }); compiler.hooks.compilation.tap("SideEffectsFlagPlugin", (compilation) => { compilation.hooks.optimizeDependencies.tap("SideEffectsFlagPlugin", (modules) => { diff --git a/schemas/WebpackOptions.json b/schemas/WebpackOptions.json index 473ad498f..a1d6d341c 100644 --- a/schemas/WebpackOptions.json +++ b/schemas/WebpackOptions.json @@ -872,6 +872,10 @@ } ] }, + "sideEffects": { + "description": "Flags a module as with or without side effects", + "type": "boolean" + }, "query": { "description": "Shortcut for use.query", "anyOf": [ diff --git a/test/Validation.test.js b/test/Validation.test.js index de8b6db43..3cb4e3ee2 100644 --- a/test/Validation.test.js +++ b/test/Validation.test.js @@ -174,7 +174,7 @@ describe("Validation", () => { }, message: [ " - configuration.module.rules[0].oneOf[0] has an unknown property 'paser'. These properties are valid:", - " object { enforce?, exclude?, include?, issuer?, loader?, loaders?, oneOf?, options?, parser?, resolve?, query?, type?, resource?, resourceQuery?, compiler?, rules?, test?, use? }", + " object { enforce?, exclude?, include?, issuer?, loader?, loaders?, oneOf?, options?, parser?, resolve?, sideEffects?, query?, type?, resource?, resourceQuery?, compiler?, rules?, test?, use? }", " -> A rule" ] }, { diff --git a/test/configCases/side-effects/side-effects-override/index.js b/test/configCases/side-effects/side-effects-override/index.js new file mode 100644 index 000000000..b15057fe0 --- /dev/null +++ b/test/configCases/side-effects/side-effects-override/index.js @@ -0,0 +1,11 @@ +import { log as plog } from "pmodule/tracker"; +import { log as nlog } from "nmodule/tracker"; +import p from "pmodule"; +import n from "nmodule"; + +it("should be able to override side effects", function() { + p.should.be.eql("def"); + n.should.be.eql("def"); + plog.should.be.eql(["a.js", "b.js", "c.js", "index.js"]); + nlog.should.be.eql(["index.js"]); +}); diff --git a/test/configCases/side-effects/side-effects-override/node_modules/nmodule/a.js b/test/configCases/side-effects/side-effects-override/node_modules/nmodule/a.js new file mode 100644 index 000000000..515d49e6a --- /dev/null +++ b/test/configCases/side-effects/side-effects-override/node_modules/nmodule/a.js @@ -0,0 +1,8 @@ +var a = "a"; +var b = "b"; +var c = "c"; + +export { a, b, c }; + +import { track } from "./tracker"; +track("a.js"); diff --git a/test/configCases/side-effects/side-effects-override/node_modules/nmodule/b.js b/test/configCases/side-effects/side-effects-override/node_modules/nmodule/b.js new file mode 100644 index 000000000..239bde672 --- /dev/null +++ b/test/configCases/side-effects/side-effects-override/node_modules/nmodule/b.js @@ -0,0 +1,8 @@ +var x = "x"; +var y = "y"; + +export { x, y }; +export { z } from "./c"; + +import { track } from "./tracker"; +track("b.js"); diff --git a/test/configCases/side-effects/side-effects-override/node_modules/nmodule/c.js b/test/configCases/side-effects/side-effects-override/node_modules/nmodule/c.js new file mode 100644 index 000000000..06d472502 --- /dev/null +++ b/test/configCases/side-effects/side-effects-override/node_modules/nmodule/c.js @@ -0,0 +1,6 @@ +var z = "z"; + +export { z }; + +import { track } from "./tracker"; +track("c.js"); diff --git a/test/configCases/side-effects/side-effects-override/node_modules/nmodule/index.js b/test/configCases/side-effects/side-effects-override/node_modules/nmodule/index.js new file mode 100644 index 000000000..c7b32fec3 --- /dev/null +++ b/test/configCases/side-effects/side-effects-override/node_modules/nmodule/index.js @@ -0,0 +1,7 @@ +export * from "./a"; +export { x, y, z } from "./b"; + +import { track } from "./tracker"; +track("index.js"); + +export default "def"; diff --git a/test/configCases/side-effects/side-effects-override/node_modules/nmodule/package.json b/test/configCases/side-effects/side-effects-override/node_modules/nmodule/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/test/configCases/side-effects/side-effects-override/node_modules/nmodule/package.json @@ -0,0 +1 @@ +{} diff --git a/test/configCases/side-effects/side-effects-override/node_modules/nmodule/tracker.js b/test/configCases/side-effects/side-effects-override/node_modules/nmodule/tracker.js new file mode 100644 index 000000000..42b014d4f --- /dev/null +++ b/test/configCases/side-effects/side-effects-override/node_modules/nmodule/tracker.js @@ -0,0 +1,10 @@ +export function track(file) { + log.push(file); + log.sort(); +} + +export var log = []; + +export function reset() { + log.length = 0; +} diff --git a/test/configCases/side-effects/side-effects-override/node_modules/pmodule/a.js b/test/configCases/side-effects/side-effects-override/node_modules/pmodule/a.js new file mode 100644 index 000000000..515d49e6a --- /dev/null +++ b/test/configCases/side-effects/side-effects-override/node_modules/pmodule/a.js @@ -0,0 +1,8 @@ +var a = "a"; +var b = "b"; +var c = "c"; + +export { a, b, c }; + +import { track } from "./tracker"; +track("a.js"); diff --git a/test/configCases/side-effects/side-effects-override/node_modules/pmodule/b.js b/test/configCases/side-effects/side-effects-override/node_modules/pmodule/b.js new file mode 100644 index 000000000..239bde672 --- /dev/null +++ b/test/configCases/side-effects/side-effects-override/node_modules/pmodule/b.js @@ -0,0 +1,8 @@ +var x = "x"; +var y = "y"; + +export { x, y }; +export { z } from "./c"; + +import { track } from "./tracker"; +track("b.js"); diff --git a/test/configCases/side-effects/side-effects-override/node_modules/pmodule/c.js b/test/configCases/side-effects/side-effects-override/node_modules/pmodule/c.js new file mode 100644 index 000000000..06d472502 --- /dev/null +++ b/test/configCases/side-effects/side-effects-override/node_modules/pmodule/c.js @@ -0,0 +1,6 @@ +var z = "z"; + +export { z }; + +import { track } from "./tracker"; +track("c.js"); diff --git a/test/configCases/side-effects/side-effects-override/node_modules/pmodule/index.js b/test/configCases/side-effects/side-effects-override/node_modules/pmodule/index.js new file mode 100644 index 000000000..c7b32fec3 --- /dev/null +++ b/test/configCases/side-effects/side-effects-override/node_modules/pmodule/index.js @@ -0,0 +1,7 @@ +export * from "./a"; +export { x, y, z } from "./b"; + +import { track } from "./tracker"; +track("index.js"); + +export default "def"; diff --git a/test/configCases/side-effects/side-effects-override/node_modules/pmodule/package.json b/test/configCases/side-effects/side-effects-override/node_modules/pmodule/package.json new file mode 100644 index 000000000..43c38c1bb --- /dev/null +++ b/test/configCases/side-effects/side-effects-override/node_modules/pmodule/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": false +} diff --git a/test/configCases/side-effects/side-effects-override/node_modules/pmodule/tracker.js b/test/configCases/side-effects/side-effects-override/node_modules/pmodule/tracker.js new file mode 100644 index 000000000..42b014d4f --- /dev/null +++ b/test/configCases/side-effects/side-effects-override/node_modules/pmodule/tracker.js @@ -0,0 +1,10 @@ +export function track(file) { + log.push(file); + log.sort(); +} + +export var log = []; + +export function reset() { + log.length = 0; +} diff --git a/test/configCases/side-effects/side-effects-override/webpack.config.js b/test/configCases/side-effects/side-effects-override/webpack.config.js new file mode 100644 index 000000000..789ad53cf --- /dev/null +++ b/test/configCases/side-effects/side-effects-override/webpack.config.js @@ -0,0 +1,16 @@ +const path = require("path"); +module.exports = { + mode: "production", + module: { + rules: [ + { + test: path.resolve(__dirname, "node_modules/pmodule"), + sideEffects: true + }, + { + test: path.resolve(__dirname, "node_modules/nmodule"), + sideEffects: false + } + ] + } +};