305 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			305 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/*
 | 
						|
	MIT License http://www.opensource.org/licenses/mit-license.php
 | 
						|
	Author Tobias Koppers @sokra
 | 
						|
*/
 | 
						|
 | 
						|
"use strict";
 | 
						|
 | 
						|
const {
 | 
						|
	JAVASCRIPT_MODULE_TYPE_AUTO,
 | 
						|
	JAVASCRIPT_MODULE_TYPE_DYNAMIC
 | 
						|
} = require("../ModuleTypeConstants");
 | 
						|
const RuntimeGlobals = require("../RuntimeGlobals");
 | 
						|
const RuntimeModule = require("../RuntimeModule");
 | 
						|
const SelfModuleFactory = require("../SelfModuleFactory");
 | 
						|
const Template = require("../Template");
 | 
						|
const {
 | 
						|
	evaluateToIdentifier,
 | 
						|
	toConstantDependency
 | 
						|
} = require("../javascript/JavascriptParserHelpers");
 | 
						|
const CommonJsExportRequireDependency = require("./CommonJsExportRequireDependency");
 | 
						|
const CommonJsExportsDependency = require("./CommonJsExportsDependency");
 | 
						|
const CommonJsExportsParserPlugin = require("./CommonJsExportsParserPlugin");
 | 
						|
const CommonJsFullRequireDependency = require("./CommonJsFullRequireDependency");
 | 
						|
const CommonJsImportsParserPlugin = require("./CommonJsImportsParserPlugin");
 | 
						|
const CommonJsRequireContextDependency = require("./CommonJsRequireContextDependency");
 | 
						|
const CommonJsRequireDependency = require("./CommonJsRequireDependency");
 | 
						|
const CommonJsSelfReferenceDependency = require("./CommonJsSelfReferenceDependency");
 | 
						|
const ModuleDecoratorDependency = require("./ModuleDecoratorDependency");
 | 
						|
const RequireHeaderDependency = require("./RequireHeaderDependency");
 | 
						|
const RequireResolveContextDependency = require("./RequireResolveContextDependency");
 | 
						|
const RequireResolveDependency = require("./RequireResolveDependency");
 | 
						|
const RequireResolveHeaderDependency = require("./RequireResolveHeaderDependency");
 | 
						|
const RuntimeRequirementsDependency = require("./RuntimeRequirementsDependency");
 | 
						|
 | 
						|
/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
 | 
						|
/** @typedef {import("../Compilation")} Compilation */
 | 
						|
/** @typedef {import("../Compiler")} Compiler */
 | 
						|
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
 | 
						|
/** @typedef {import("../Module").BuildInfo} BuildInfo */
 | 
						|
/** @typedef {import("../javascript/JavascriptParser")} Parser */
 | 
						|
 | 
						|
const PLUGIN_NAME = "CommonJsPlugin";
 | 
						|
 | 
						|
class CommonJsPlugin {
 | 
						|
	/**
 | 
						|
	 * Apply the plugin
 | 
						|
	 * @param {Compiler} compiler the compiler instance
 | 
						|
	 * @returns {void}
 | 
						|
	 */
 | 
						|
	apply(compiler) {
 | 
						|
		compiler.hooks.compilation.tap(
 | 
						|
			PLUGIN_NAME,
 | 
						|
			(compilation, { contextModuleFactory, normalModuleFactory }) => {
 | 
						|
				compilation.dependencyFactories.set(
 | 
						|
					CommonJsRequireDependency,
 | 
						|
					normalModuleFactory
 | 
						|
				);
 | 
						|
				compilation.dependencyTemplates.set(
 | 
						|
					CommonJsRequireDependency,
 | 
						|
					new CommonJsRequireDependency.Template()
 | 
						|
				);
 | 
						|
 | 
						|
				compilation.dependencyFactories.set(
 | 
						|
					CommonJsFullRequireDependency,
 | 
						|
					normalModuleFactory
 | 
						|
				);
 | 
						|
				compilation.dependencyTemplates.set(
 | 
						|
					CommonJsFullRequireDependency,
 | 
						|
					new CommonJsFullRequireDependency.Template()
 | 
						|
				);
 | 
						|
 | 
						|
				compilation.dependencyFactories.set(
 | 
						|
					CommonJsRequireContextDependency,
 | 
						|
					contextModuleFactory
 | 
						|
				);
 | 
						|
				compilation.dependencyTemplates.set(
 | 
						|
					CommonJsRequireContextDependency,
 | 
						|
					new CommonJsRequireContextDependency.Template()
 | 
						|
				);
 | 
						|
 | 
						|
				compilation.dependencyFactories.set(
 | 
						|
					RequireResolveDependency,
 | 
						|
					normalModuleFactory
 | 
						|
				);
 | 
						|
				compilation.dependencyTemplates.set(
 | 
						|
					RequireResolveDependency,
 | 
						|
					new RequireResolveDependency.Template()
 | 
						|
				);
 | 
						|
 | 
						|
				compilation.dependencyFactories.set(
 | 
						|
					RequireResolveContextDependency,
 | 
						|
					contextModuleFactory
 | 
						|
				);
 | 
						|
				compilation.dependencyTemplates.set(
 | 
						|
					RequireResolveContextDependency,
 | 
						|
					new RequireResolveContextDependency.Template()
 | 
						|
				);
 | 
						|
 | 
						|
				compilation.dependencyTemplates.set(
 | 
						|
					RequireResolveHeaderDependency,
 | 
						|
					new RequireResolveHeaderDependency.Template()
 | 
						|
				);
 | 
						|
 | 
						|
				compilation.dependencyTemplates.set(
 | 
						|
					RequireHeaderDependency,
 | 
						|
					new RequireHeaderDependency.Template()
 | 
						|
				);
 | 
						|
 | 
						|
				compilation.dependencyTemplates.set(
 | 
						|
					CommonJsExportsDependency,
 | 
						|
					new CommonJsExportsDependency.Template()
 | 
						|
				);
 | 
						|
 | 
						|
				compilation.dependencyFactories.set(
 | 
						|
					CommonJsExportRequireDependency,
 | 
						|
					normalModuleFactory
 | 
						|
				);
 | 
						|
				compilation.dependencyTemplates.set(
 | 
						|
					CommonJsExportRequireDependency,
 | 
						|
					new CommonJsExportRequireDependency.Template()
 | 
						|
				);
 | 
						|
 | 
						|
				const selfFactory = new SelfModuleFactory(compilation.moduleGraph);
 | 
						|
 | 
						|
				compilation.dependencyFactories.set(
 | 
						|
					CommonJsSelfReferenceDependency,
 | 
						|
					selfFactory
 | 
						|
				);
 | 
						|
				compilation.dependencyTemplates.set(
 | 
						|
					CommonJsSelfReferenceDependency,
 | 
						|
					new CommonJsSelfReferenceDependency.Template()
 | 
						|
				);
 | 
						|
 | 
						|
				compilation.dependencyFactories.set(
 | 
						|
					ModuleDecoratorDependency,
 | 
						|
					selfFactory
 | 
						|
				);
 | 
						|
				compilation.dependencyTemplates.set(
 | 
						|
					ModuleDecoratorDependency,
 | 
						|
					new ModuleDecoratorDependency.Template()
 | 
						|
				);
 | 
						|
 | 
						|
				compilation.hooks.runtimeRequirementInModule
 | 
						|
					.for(RuntimeGlobals.harmonyModuleDecorator)
 | 
						|
					.tap(PLUGIN_NAME, (module, set) => {
 | 
						|
						set.add(RuntimeGlobals.module);
 | 
						|
						set.add(RuntimeGlobals.requireScope);
 | 
						|
					});
 | 
						|
 | 
						|
				compilation.hooks.runtimeRequirementInModule
 | 
						|
					.for(RuntimeGlobals.nodeModuleDecorator)
 | 
						|
					.tap(PLUGIN_NAME, (module, set) => {
 | 
						|
						set.add(RuntimeGlobals.module);
 | 
						|
						set.add(RuntimeGlobals.requireScope);
 | 
						|
					});
 | 
						|
 | 
						|
				compilation.hooks.runtimeRequirementInTree
 | 
						|
					.for(RuntimeGlobals.harmonyModuleDecorator)
 | 
						|
					.tap(PLUGIN_NAME, (chunk, _set) => {
 | 
						|
						compilation.addRuntimeModule(
 | 
						|
							chunk,
 | 
						|
							new HarmonyModuleDecoratorRuntimeModule()
 | 
						|
						);
 | 
						|
					});
 | 
						|
 | 
						|
				compilation.hooks.runtimeRequirementInTree
 | 
						|
					.for(RuntimeGlobals.nodeModuleDecorator)
 | 
						|
					.tap(PLUGIN_NAME, (chunk, _set) => {
 | 
						|
						compilation.addRuntimeModule(
 | 
						|
							chunk,
 | 
						|
							new NodeModuleDecoratorRuntimeModule()
 | 
						|
						);
 | 
						|
					});
 | 
						|
 | 
						|
				/**
 | 
						|
				 * @param {Parser} parser parser parser
 | 
						|
				 * @param {JavascriptParserOptions} parserOptions parserOptions
 | 
						|
				 * @returns {void}
 | 
						|
				 */
 | 
						|
				const handler = (parser, parserOptions) => {
 | 
						|
					if (parserOptions.commonjs !== undefined && !parserOptions.commonjs) {
 | 
						|
						return;
 | 
						|
					}
 | 
						|
					parser.hooks.typeof
 | 
						|
						.for("module")
 | 
						|
						.tap(
 | 
						|
							PLUGIN_NAME,
 | 
						|
							toConstantDependency(parser, JSON.stringify("object"))
 | 
						|
						);
 | 
						|
 | 
						|
					parser.hooks.expression
 | 
						|
						.for("require.main")
 | 
						|
						.tap(
 | 
						|
							PLUGIN_NAME,
 | 
						|
							toConstantDependency(
 | 
						|
								parser,
 | 
						|
								`${RuntimeGlobals.moduleCache}[${RuntimeGlobals.entryModuleId}]`,
 | 
						|
								[RuntimeGlobals.moduleCache, RuntimeGlobals.entryModuleId]
 | 
						|
							)
 | 
						|
						);
 | 
						|
					parser.hooks.expression
 | 
						|
						.for(RuntimeGlobals.moduleLoaded)
 | 
						|
						.tap(PLUGIN_NAME, (expr) => {
 | 
						|
							/** @type {BuildInfo} */
 | 
						|
							(parser.state.module.buildInfo).moduleConcatenationBailout =
 | 
						|
								RuntimeGlobals.moduleLoaded;
 | 
						|
							const dep = new RuntimeRequirementsDependency([
 | 
						|
								RuntimeGlobals.moduleLoaded
 | 
						|
							]);
 | 
						|
							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
 | 
						|
							parser.state.module.addPresentationalDependency(dep);
 | 
						|
							return true;
 | 
						|
						});
 | 
						|
 | 
						|
					parser.hooks.expression
 | 
						|
						.for(RuntimeGlobals.moduleId)
 | 
						|
						.tap(PLUGIN_NAME, (expr) => {
 | 
						|
							/** @type {BuildInfo} */
 | 
						|
							(parser.state.module.buildInfo).moduleConcatenationBailout =
 | 
						|
								RuntimeGlobals.moduleId;
 | 
						|
							const dep = new RuntimeRequirementsDependency([
 | 
						|
								RuntimeGlobals.moduleId
 | 
						|
							]);
 | 
						|
							dep.loc = /** @type {DependencyLocation} */ (expr.loc);
 | 
						|
							parser.state.module.addPresentationalDependency(dep);
 | 
						|
							return true;
 | 
						|
						});
 | 
						|
 | 
						|
					parser.hooks.evaluateIdentifier.for("module.hot").tap(
 | 
						|
						PLUGIN_NAME,
 | 
						|
						evaluateToIdentifier("module.hot", "module", () => ["hot"], null)
 | 
						|
					);
 | 
						|
 | 
						|
					new CommonJsImportsParserPlugin(parserOptions).apply(parser);
 | 
						|
					new CommonJsExportsParserPlugin(compilation.moduleGraph).apply(
 | 
						|
						parser
 | 
						|
					);
 | 
						|
				};
 | 
						|
 | 
						|
				normalModuleFactory.hooks.parser
 | 
						|
					.for(JAVASCRIPT_MODULE_TYPE_AUTO)
 | 
						|
					.tap(PLUGIN_NAME, handler);
 | 
						|
				normalModuleFactory.hooks.parser
 | 
						|
					.for(JAVASCRIPT_MODULE_TYPE_DYNAMIC)
 | 
						|
					.tap(PLUGIN_NAME, handler);
 | 
						|
			}
 | 
						|
		);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
class HarmonyModuleDecoratorRuntimeModule extends RuntimeModule {
 | 
						|
	constructor() {
 | 
						|
		super("harmony module decorator");
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * @returns {string | null} runtime code
 | 
						|
	 */
 | 
						|
	generate() {
 | 
						|
		const { runtimeTemplate } = /** @type {Compilation} */ (this.compilation);
 | 
						|
		return Template.asString([
 | 
						|
			`${
 | 
						|
				RuntimeGlobals.harmonyModuleDecorator
 | 
						|
			} = ${runtimeTemplate.basicFunction("module", [
 | 
						|
				"module = Object.create(module);",
 | 
						|
				"if (!module.children) module.children = [];",
 | 
						|
				"Object.defineProperty(module, 'exports', {",
 | 
						|
				Template.indent([
 | 
						|
					"enumerable: true,",
 | 
						|
					`set: ${runtimeTemplate.basicFunction("", [
 | 
						|
						"throw new Error('ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' + module.id);"
 | 
						|
					])}`
 | 
						|
				]),
 | 
						|
				"});",
 | 
						|
				"return module;"
 | 
						|
			])};`
 | 
						|
		]);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
class NodeModuleDecoratorRuntimeModule extends RuntimeModule {
 | 
						|
	constructor() {
 | 
						|
		super("node module decorator");
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * @returns {string | null} runtime code
 | 
						|
	 */
 | 
						|
	generate() {
 | 
						|
		const { runtimeTemplate } = /** @type {Compilation} */ (this.compilation);
 | 
						|
		return Template.asString([
 | 
						|
			`${RuntimeGlobals.nodeModuleDecorator} = ${runtimeTemplate.basicFunction(
 | 
						|
				"module",
 | 
						|
				[
 | 
						|
					"module.paths = [];",
 | 
						|
					"if (!module.children) module.children = [];",
 | 
						|
					"return module;"
 | 
						|
				]
 | 
						|
			)};`
 | 
						|
		]);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
module.exports = CommonJsPlugin;
 |