diff --git a/buildin/harmony-module.js b/buildin/harmony-module.js index c16146586..4a88d266a 100644 --- a/buildin/harmony-module.js +++ b/buildin/harmony-module.js @@ -1,6 +1,6 @@ -module.exports = function(originalModule) { - if (!originalModule.webpackPolyfill) { - var module = Object.create(originalModule); +module.exports = function(module) { + if (!module.webpackPolyfill) { + module = Object.create(module); // module.parent = undefined by default if (!module.children) module.children = []; Object.defineProperty(module, "loaded", { diff --git a/lib/NodeStuffPlugin.js b/lib/NodeStuffPlugin.js index 51327f092..3933f002d 100644 --- a/lib/NodeStuffPlugin.js +++ b/lib/NodeStuffPlugin.js @@ -6,8 +6,8 @@ "use strict"; const path = require("path"); +const InitFragment = require("./InitFragment"); const { - addParsedVariableToModule, evaluateToIdentifier, evaluateToString, expressionIsUnsupported, @@ -16,6 +16,12 @@ const { toConstantDependencyWithWebpackRequire } = require("./JavascriptParserHelpers"); const CachedConstDependency = require("./dependencies/CachedConstDependency"); +const ModuleDependency = require("./dependencies/ModuleDependency"); + +/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */ +/** @typedef {import("./Dependency")} Dependency */ +/** @typedef {import("./DependencyTemplates")} DependencyTemplates */ +/** @typedef {import("./RuntimeTemplate")} RuntimeTemplate */ class NodeStuffPlugin { constructor(options) { @@ -27,6 +33,15 @@ class NodeStuffPlugin { compiler.hooks.compilation.tap( "NodeStuffPlugin", (compilation, { normalModuleFactory }) => { + compilation.dependencyFactories.set( + ModuleDecoratorDependency, + normalModuleFactory + ); + compilation.dependencyTemplates.set( + ModuleDecoratorDependency, + new ModuleDecoratorDependencyTemplate() + ); + const handler = (parser, parserOptions) => { if (parserOptions.node === false) return; @@ -145,22 +160,25 @@ class NodeStuffPlugin { parser.hooks.evaluateIdentifier .for("module.hot") .tap("NodeStuffPlugin", evaluateToIdentifier("module.hot", false)); - parser.hooks.expression.for("module").tap("NodeStuffPlugin", () => { - const module = parser.state.module; - const isHarmony = module.buildMeta && module.buildMeta.exportsType; - const moduleJsPath = getModulePath( - module.context, - require.resolve( - isHarmony - ? "../buildin/harmony-module.js" - : "../buildin/module.js" - ) - ); - return addParsedVariableToModule( - parser, - "module", - `require(${JSON.stringify(moduleJsPath)})(module)` + parser.hooks.expression.for("module").tap("NodeStuffPlugin", expr => { + const isHarmony = + parser.state.module.buildMeta && + parser.state.module.buildMeta.exportsType; + const dep = new ModuleDecoratorDependency( + getModulePath( + parser.state.module.context, + require.resolve( + isHarmony + ? "../buildin/harmony-module.js" + : "../buildin/module.js" + ) + ), + parser.state.module, + expr.range ); + dep.loc = expr.loc; + parser.state.module.addDependency(dep); + return true; }); }; @@ -174,4 +192,47 @@ class NodeStuffPlugin { ); } } + +class ModuleDecoratorDependency extends ModuleDependency { + constructor(request, originalModule, range) { + super(request); + this.originalModule = originalModule; + this.range = range; + } +} + +class ModuleDecoratorDependencyTemplate extends ModuleDependency.Template { + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {RuntimeTemplate} runtimeTemplate the runtime template + * @param {DependencyTemplates} dependencyTemplates the dependency templates + * @returns {void} + */ + apply(dependency, source, runtimeTemplate, dependencyTemplates) {} + + /** + * @param {Dependency} dependency the dependency for which the template should be applied + * @param {ReplaceSource} source the current replace source which can be modified + * @param {RuntimeTemplate} runtimeTemplate the runtime template + * @param {DependencyTemplates} dependencyTemplates the dependency templates + * @returns {InitFragment[]|null} the init fragments + */ + getInitFragments(dependency, source, runtimeTemplate, dependencyTemplates) { + const dep = /** @type {ModuleDecoratorDependency} */ (dependency); + return [ + new InitFragment( + `/* module decorator */ ${ + dep.originalModule.moduleArgument + } = ${runtimeTemplate.moduleExports({ + module: dep.module, + request: dep.request + })}(${dep.originalModule.moduleArgument});\n`, + -1, + `module decorator ${dep.originalModule.id}` + ) + ]; + } +} + module.exports = NodeStuffPlugin; diff --git a/lib/dependencies/SystemPlugin.js b/lib/dependencies/SystemPlugin.js index 62e54533c..a176e0c84 100644 --- a/lib/dependencies/SystemPlugin.js +++ b/lib/dependencies/SystemPlugin.js @@ -90,7 +90,7 @@ class SystemPlugin { expr.range ); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addDependency(dep); return true; }); diff --git a/lib/node/NodeSourcePlugin.js b/lib/node/NodeSourcePlugin.js index 90111c644..73bd79799 100644 --- a/lib/node/NodeSourcePlugin.js +++ b/lib/node/NodeSourcePlugin.js @@ -57,7 +57,7 @@ module.exports = class NodeSourcePlugin { expr.range ); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addDependency(dep); return true; }); }; @@ -96,7 +96,7 @@ module.exports = class NodeSourcePlugin { expr.range ); dep.loc = expr.loc; - parser.state.current.addDependency(dep); + parser.state.module.addDependency(dep); }); } if (localOptions.process) {