CommonJsPlugin.js (8338B)
1 /* 2 MIT License http://www.opensource.org/licenses/mit-license.php 3 Author Tobias Koppers @sokra 4 */ 5 6 "use strict"; 7 8 const RuntimeGlobals = require("../RuntimeGlobals"); 9 const RuntimeModule = require("../RuntimeModule"); 10 const SelfModuleFactory = require("../SelfModuleFactory"); 11 const Template = require("../Template"); 12 const CommonJsExportsDependency = require("./CommonJsExportsDependency"); 13 const CommonJsFullRequireDependency = require("./CommonJsFullRequireDependency"); 14 const CommonJsRequireContextDependency = require("./CommonJsRequireContextDependency"); 15 const CommonJsRequireDependency = require("./CommonJsRequireDependency"); 16 const CommonJsSelfReferenceDependency = require("./CommonJsSelfReferenceDependency"); 17 const ModuleDecoratorDependency = require("./ModuleDecoratorDependency"); 18 const RequireHeaderDependency = require("./RequireHeaderDependency"); 19 const RequireResolveContextDependency = require("./RequireResolveContextDependency"); 20 const RequireResolveDependency = require("./RequireResolveDependency"); 21 const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency"); 22 const RuntimeRequirementsDependency = require("./RuntimeRequirementsDependency"); 23 24 const CommonJsExportsParserPlugin = require("./CommonJsExportsParserPlugin"); 25 const CommonJsImportsParserPlugin = require("./CommonJsImportsParserPlugin"); 26 27 const { 28 evaluateToIdentifier, 29 toConstantDependency 30 } = require("../javascript/JavascriptParserHelpers"); 31 const CommonJsExportRequireDependency = require("./CommonJsExportRequireDependency"); 32 33 class CommonJsPlugin { 34 apply(compiler) { 35 compiler.hooks.compilation.tap( 36 "CommonJsPlugin", 37 (compilation, { contextModuleFactory, normalModuleFactory }) => { 38 compilation.dependencyFactories.set( 39 CommonJsRequireDependency, 40 normalModuleFactory 41 ); 42 compilation.dependencyTemplates.set( 43 CommonJsRequireDependency, 44 new CommonJsRequireDependency.Template() 45 ); 46 47 compilation.dependencyFactories.set( 48 CommonJsFullRequireDependency, 49 normalModuleFactory 50 ); 51 compilation.dependencyTemplates.set( 52 CommonJsFullRequireDependency, 53 new CommonJsFullRequireDependency.Template() 54 ); 55 56 compilation.dependencyFactories.set( 57 CommonJsRequireContextDependency, 58 contextModuleFactory 59 ); 60 compilation.dependencyTemplates.set( 61 CommonJsRequireContextDependency, 62 new CommonJsRequireContextDependency.Template() 63 ); 64 65 compilation.dependencyFactories.set( 66 RequireResolveDependency, 67 normalModuleFactory 68 ); 69 compilation.dependencyTemplates.set( 70 RequireResolveDependency, 71 new RequireResolveDependency.Template() 72 ); 73 74 compilation.dependencyFactories.set( 75 RequireResolveContextDependency, 76 contextModuleFactory 77 ); 78 compilation.dependencyTemplates.set( 79 RequireResolveContextDependency, 80 new RequireResolveContextDependency.Template() 81 ); 82 83 compilation.dependencyTemplates.set( 84 RequireResolveHeaderDependency, 85 new RequireResolveHeaderDependency.Template() 86 ); 87 88 compilation.dependencyTemplates.set( 89 RequireHeaderDependency, 90 new RequireHeaderDependency.Template() 91 ); 92 93 compilation.dependencyTemplates.set( 94 CommonJsExportsDependency, 95 new CommonJsExportsDependency.Template() 96 ); 97 98 compilation.dependencyFactories.set( 99 CommonJsExportRequireDependency, 100 normalModuleFactory 101 ); 102 compilation.dependencyTemplates.set( 103 CommonJsExportRequireDependency, 104 new CommonJsExportRequireDependency.Template() 105 ); 106 107 const selfFactory = new SelfModuleFactory(compilation.moduleGraph); 108 109 compilation.dependencyFactories.set( 110 CommonJsSelfReferenceDependency, 111 selfFactory 112 ); 113 compilation.dependencyTemplates.set( 114 CommonJsSelfReferenceDependency, 115 new CommonJsSelfReferenceDependency.Template() 116 ); 117 118 compilation.dependencyFactories.set( 119 ModuleDecoratorDependency, 120 selfFactory 121 ); 122 compilation.dependencyTemplates.set( 123 ModuleDecoratorDependency, 124 new ModuleDecoratorDependency.Template() 125 ); 126 127 compilation.hooks.runtimeRequirementInModule 128 .for(RuntimeGlobals.harmonyModuleDecorator) 129 .tap("CommonJsPlugin", (module, set) => { 130 set.add(RuntimeGlobals.module); 131 set.add(RuntimeGlobals.requireScope); 132 }); 133 134 compilation.hooks.runtimeRequirementInModule 135 .for(RuntimeGlobals.nodeModuleDecorator) 136 .tap("CommonJsPlugin", (module, set) => { 137 set.add(RuntimeGlobals.module); 138 set.add(RuntimeGlobals.requireScope); 139 }); 140 141 compilation.hooks.runtimeRequirementInTree 142 .for(RuntimeGlobals.harmonyModuleDecorator) 143 .tap("CommonJsPlugin", (chunk, set) => { 144 compilation.addRuntimeModule( 145 chunk, 146 new HarmonyModuleDecoratorRuntimeModule() 147 ); 148 }); 149 150 compilation.hooks.runtimeRequirementInTree 151 .for(RuntimeGlobals.nodeModuleDecorator) 152 .tap("CommonJsPlugin", (chunk, set) => { 153 compilation.addRuntimeModule( 154 chunk, 155 new NodeModuleDecoratorRuntimeModule() 156 ); 157 }); 158 159 const handler = (parser, parserOptions) => { 160 if (parserOptions.commonjs !== undefined && !parserOptions.commonjs) 161 return; 162 parser.hooks.typeof 163 .for("module") 164 .tap( 165 "CommonJsPlugin", 166 toConstantDependency(parser, JSON.stringify("object")) 167 ); 168 169 parser.hooks.expression 170 .for("require.main") 171 .tap( 172 "CommonJsPlugin", 173 toConstantDependency( 174 parser, 175 `${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}]`, 176 [RuntimeGlobals.moduleCache, RuntimeGlobals.entryModuleId] 177 ) 178 ); 179 parser.hooks.expression 180 .for("module.loaded") 181 .tap("CommonJsPlugin", expr => { 182 parser.state.module.buildInfo.moduleConcatenationBailout = 183 "module.loaded"; 184 const dep = new RuntimeRequirementsDependency([ 185 RuntimeGlobals.moduleLoaded 186 ]); 187 dep.loc = expr.loc; 188 parser.state.module.addPresentationalDependency(dep); 189 return true; 190 }); 191 192 parser.hooks.expression 193 .for("module.id") 194 .tap("CommonJsPlugin", expr => { 195 parser.state.module.buildInfo.moduleConcatenationBailout = 196 "module.id"; 197 const dep = new RuntimeRequirementsDependency([ 198 RuntimeGlobals.moduleId 199 ]); 200 dep.loc = expr.loc; 201 parser.state.module.addPresentationalDependency(dep); 202 return true; 203 }); 204 205 parser.hooks.evaluateIdentifier.for("module.hot").tap( 206 "CommonJsPlugin", 207 evaluateToIdentifier("module.hot", "module", () => ["hot"], null) 208 ); 209 210 new CommonJsImportsParserPlugin(parserOptions).apply(parser); 211 new CommonJsExportsParserPlugin(compilation.moduleGraph).apply( 212 parser 213 ); 214 }; 215 216 normalModuleFactory.hooks.parser 217 .for("javascript/auto") 218 .tap("CommonJsPlugin", handler); 219 normalModuleFactory.hooks.parser 220 .for("javascript/dynamic") 221 .tap("CommonJsPlugin", handler); 222 } 223 ); 224 } 225 } 226 227 class HarmonyModuleDecoratorRuntimeModule extends RuntimeModule { 228 constructor() { 229 super("harmony module decorator"); 230 } 231 232 /** 233 * @returns {string} runtime code 234 */ 235 generate() { 236 const { runtimeTemplate } = this.compilation; 237 return Template.asString([ 238 `${ 239 RuntimeGlobals.harmonyModuleDecorator 240 } = ${runtimeTemplate.basicFunction("module", [ 241 "module = Object.create(module);", 242 "if (!module.children) module.children = [];", 243 "Object.defineProperty(module, 'exports', {", 244 Template.indent([ 245 "enumerable: true,", 246 `set: ${runtimeTemplate.basicFunction("", [ 247 "throw new Error('ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' + module.id);" 248 ])}` 249 ]), 250 "});", 251 "return module;" 252 ])};` 253 ]); 254 } 255 } 256 257 class NodeModuleDecoratorRuntimeModule extends RuntimeModule { 258 constructor() { 259 super("node module decorator"); 260 } 261 262 /** 263 * @returns {string} runtime code 264 */ 265 generate() { 266 const { runtimeTemplate } = this.compilation; 267 return Template.asString([ 268 `${RuntimeGlobals.nodeModuleDecorator} = ${runtimeTemplate.basicFunction( 269 "module", 270 [ 271 "module.paths = [];", 272 "if (!module.children) module.children = [];", 273 "return module;" 274 ] 275 )};` 276 ]); 277 } 278 } 279 280 module.exports = CommonJsPlugin;