From 5b08ab51c3fde7d01d3b92f97c9d5195a89e93cf Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 22 May 2019 08:03:44 +0200 Subject: [PATCH] fixes #9156 node: false should not disable CommonJs features --- lib/CommonJsStuffPlugin.js | 114 ++++++++++++++++++ lib/NodeStuffPlugin.js | 83 ------------- lib/WebpackOptionsApply.js | 2 + test/configCases/parsing/issue-9156/index.js | 7 ++ .../parsing/issue-9156/webpack.config.js | 4 + 5 files changed, 127 insertions(+), 83 deletions(-) create mode 100644 lib/CommonJsStuffPlugin.js create mode 100644 test/configCases/parsing/issue-9156/index.js create mode 100644 test/configCases/parsing/issue-9156/webpack.config.js diff --git a/lib/CommonJsStuffPlugin.js b/lib/CommonJsStuffPlugin.js new file mode 100644 index 000000000..4b82c60b7 --- /dev/null +++ b/lib/CommonJsStuffPlugin.js @@ -0,0 +1,114 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const path = require("path"); +const ParserHelpers = require("./ParserHelpers"); + +class CommonJsStuffPlugin { + apply(compiler) { + compiler.hooks.compilation.tap( + "CommonJsStuffPlugin", + (compilation, { normalModuleFactory }) => { + const handler = (parser, parserOptions) => { + parser.hooks.expression + .for("require.main.require") + .tap( + "CommonJsStuffPlugin", + ParserHelpers.expressionIsUnsupported( + parser, + "require.main.require is not supported by webpack." + ) + ); + parser.hooks.expression + .for("module.parent.require") + .tap( + "CommonJsStuffPlugin", + ParserHelpers.expressionIsUnsupported( + parser, + "module.parent.require is not supported by webpack." + ) + ); + parser.hooks.expression + .for("require.main") + .tap( + "CommonJsStuffPlugin", + ParserHelpers.toConstantDependencyWithWebpackRequire( + parser, + "__webpack_require__.c[__webpack_require__.s]" + ) + ); + parser.hooks.expression + .for("module.loaded") + .tap("CommonJsStuffPlugin", expr => { + parser.state.module.buildMeta.moduleConcatenationBailout = + "module.loaded"; + return ParserHelpers.toConstantDependency(parser, "module.l")( + expr + ); + }); + parser.hooks.expression + .for("module.id") + .tap("CommonJsStuffPlugin", expr => { + parser.state.module.buildMeta.moduleConcatenationBailout = + "module.id"; + return ParserHelpers.toConstantDependency(parser, "module.i")( + expr + ); + }); + parser.hooks.expression + .for("module.exports") + .tap("CommonJsStuffPlugin", () => { + const module = parser.state.module; + const isHarmony = + module.buildMeta && module.buildMeta.exportsType; + if (!isHarmony) return true; + }); + parser.hooks.evaluateIdentifier + .for("module.hot") + .tap( + "CommonJsStuffPlugin", + ParserHelpers.evaluateToIdentifier("module.hot", false) + ); + parser.hooks.expression + .for("module") + .tap("CommonJsStuffPlugin", () => { + const module = parser.state.module; + const isHarmony = + module.buildMeta && module.buildMeta.exportsType; + let moduleJsPath = path.join( + __dirname, + "..", + "buildin", + isHarmony ? "harmony-module.js" : "module.js" + ); + if (module.context) { + moduleJsPath = path.relative( + parser.state.module.context, + moduleJsPath + ); + if (!/^[A-Z]:/i.test(moduleJsPath)) { + moduleJsPath = `./${moduleJsPath.replace(/\\/g, "/")}`; + } + } + return ParserHelpers.addParsedVariableToModule( + parser, + "module", + `require(${JSON.stringify(moduleJsPath)})(module)` + ); + }); + }; + + normalModuleFactory.hooks.parser + .for("javascript/auto") + .tap("CommonJsStuffPlugin", handler); + normalModuleFactory.hooks.parser + .for("javascript/dynamic") + .tap("CommonJsStuffPlugin", handler); + } + ); + } +} +module.exports = CommonJsStuffPlugin; diff --git a/lib/NodeStuffPlugin.js b/lib/NodeStuffPlugin.js index fc0338ae5..5b3826809 100644 --- a/lib/NodeStuffPlugin.js +++ b/lib/NodeStuffPlugin.js @@ -94,15 +94,6 @@ class NodeStuffPlugin { )(expr); }); } - parser.hooks.expression - .for("require.main") - .tap( - "NodeStuffPlugin", - ParserHelpers.toConstantDependencyWithWebpackRequire( - parser, - "__webpack_require__.c[__webpack_require__.s]" - ) - ); parser.hooks.expression .for("require.extensions") .tap( @@ -112,80 +103,6 @@ class NodeStuffPlugin { "require.extensions is not supported by webpack. Use a loader instead." ) ); - parser.hooks.expression - .for("require.main.require") - .tap( - "NodeStuffPlugin", - ParserHelpers.expressionIsUnsupported( - parser, - "require.main.require is not supported by webpack." - ) - ); - parser.hooks.expression - .for("module.parent.require") - .tap( - "NodeStuffPlugin", - ParserHelpers.expressionIsUnsupported( - parser, - "module.parent.require is not supported by webpack." - ) - ); - parser.hooks.expression - .for("module.loaded") - .tap("NodeStuffPlugin", expr => { - parser.state.module.buildMeta.moduleConcatenationBailout = - "module.loaded"; - return ParserHelpers.toConstantDependency(parser, "module.l")( - expr - ); - }); - parser.hooks.expression - .for("module.id") - .tap("NodeStuffPlugin", expr => { - parser.state.module.buildMeta.moduleConcatenationBailout = - "module.id"; - return ParserHelpers.toConstantDependency(parser, "module.i")( - expr - ); - }); - parser.hooks.expression - .for("module.exports") - .tap("NodeStuffPlugin", () => { - const module = parser.state.module; - const isHarmony = - module.buildMeta && module.buildMeta.exportsType; - if (!isHarmony) return true; - }); - parser.hooks.evaluateIdentifier - .for("module.hot") - .tap( - "NodeStuffPlugin", - ParserHelpers.evaluateToIdentifier("module.hot", false) - ); - parser.hooks.expression.for("module").tap("NodeStuffPlugin", () => { - const module = parser.state.module; - const isHarmony = module.buildMeta && module.buildMeta.exportsType; - let moduleJsPath = path.join( - __dirname, - "..", - "buildin", - isHarmony ? "harmony-module.js" : "module.js" - ); - if (module.context) { - moduleJsPath = path.relative( - parser.state.module.context, - moduleJsPath - ); - if (!/^[A-Z]:/i.test(moduleJsPath)) { - moduleJsPath = `./${moduleJsPath.replace(/\\/g, "/")}`; - } - } - return ParserHelpers.addParsedVariableToModule( - parser, - "module", - `require(${JSON.stringify(moduleJsPath)})(module)` - ); - }); }; normalModuleFactory.hooks.parser diff --git a/lib/WebpackOptionsApply.js b/lib/WebpackOptionsApply.js index bfe7d920b..ff4601cee 100644 --- a/lib/WebpackOptionsApply.js +++ b/lib/WebpackOptionsApply.js @@ -21,6 +21,7 @@ const RecordIdsPlugin = require("./RecordIdsPlugin"); const APIPlugin = require("./APIPlugin"); const ConstPlugin = require("./ConstPlugin"); +const CommonJsStuffPlugin = require("./CommonJsStuffPlugin"); const CompatibilityPlugin = require("./CompatibilityPlugin"); const TemplatedPathPlugin = require("./TemplatedPathPlugin"); @@ -293,6 +294,7 @@ class WebpackOptionsApply extends OptionsApply { const NodeStuffPlugin = require("./NodeStuffPlugin"); new NodeStuffPlugin(options.node).apply(compiler); } + new CommonJsStuffPlugin().apply(compiler); new APIPlugin().apply(compiler); new ConstPlugin().apply(compiler); new UseStrictPlugin().apply(compiler); diff --git a/test/configCases/parsing/issue-9156/index.js b/test/configCases/parsing/issue-9156/index.js new file mode 100644 index 000000000..16a3dd252 --- /dev/null +++ b/test/configCases/parsing/issue-9156/index.js @@ -0,0 +1,7 @@ +it("should allow to access module.id when node option is set to false", function() { + expect(module.id).toBeDefined(); +}); + +it("should allow to access module.loaded when node option is set to false", function() { + expect(module.loaded).toBeDefined(); +}); diff --git a/test/configCases/parsing/issue-9156/webpack.config.js b/test/configCases/parsing/issue-9156/webpack.config.js new file mode 100644 index 000000000..9f1a00b55 --- /dev/null +++ b/test/configCases/parsing/issue-9156/webpack.config.js @@ -0,0 +1,4 @@ +module.exports = { + target: "web", + node: false +};