mirror of https://github.com/webpack/webpack.git
				
				
				
			
		
			
				
	
	
		
			132 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| /*
 | |
| 	MIT License http://www.opensource.org/licenses/mit-license.php
 | |
| 	Author Joel Denning @joeldenning
 | |
| */
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| const { ConcatSource } = require("webpack-sources");
 | |
| const ExternalModule = require("./ExternalModule");
 | |
| const Template = require("./Template");
 | |
| 
 | |
| /** @typedef {import("./Compilation")} Compilation */
 | |
| 
 | |
| /**
 | |
|  * @typedef {Object} SystemMainTemplatePluginOptions
 | |
|  * @param {string=} name the library name
 | |
|  */
 | |
| 
 | |
| class SystemMainTemplatePlugin {
 | |
| 	/**
 | |
| 	 * @param {SystemMainTemplatePluginOptions} options the plugin options
 | |
| 	 */
 | |
| 	constructor(options) {
 | |
| 		this.name = options.name;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param {Compilation} compilation the compilation instance
 | |
| 	 * @returns {void}
 | |
| 	 */
 | |
| 	apply(compilation) {
 | |
| 		const { mainTemplate, chunkTemplate } = compilation;
 | |
| 
 | |
| 		const onRenderWithEntry = (source, chunk, hash) => {
 | |
| 			const chunkGraph = compilation.chunkGraph;
 | |
| 			const modules = chunkGraph
 | |
| 				.getChunkModules(chunk)
 | |
| 				.filter(m => m instanceof ExternalModule);
 | |
| 			const externals = /** @type {ExternalModule[]} */ (modules);
 | |
| 
 | |
| 			// The name this bundle should be registered as with System
 | |
| 			const name = this.name ? `${JSON.stringify(this.name)}, ` : "";
 | |
| 
 | |
| 			// The array of dependencies that are external to webpack and will be provided by System
 | |
| 			const systemDependencies = JSON.stringify(
 | |
| 				externals.map(m =>
 | |
| 					typeof m.request === "object" && !Array.isArray(m.request)
 | |
| 						? m.request.amd
 | |
| 						: m.request
 | |
| 				)
 | |
| 			);
 | |
| 
 | |
| 			// The name of the variable provided by System for exporting
 | |
| 			const dynamicExport = "__WEBPACK_DYNAMIC_EXPORT__";
 | |
| 
 | |
| 			// An array of the internal variable names for the webpack externals
 | |
| 			const externalWebpackNames = externals.map(
 | |
| 				m =>
 | |
| 					`__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(
 | |
| 						`${chunkGraph.getModuleId(m)}`
 | |
| 					)}__`
 | |
| 			);
 | |
| 
 | |
| 			// Declaring variables for the internal variable names for the webpack externals
 | |
| 			const externalVarDeclarations =
 | |
| 				externalWebpackNames.length > 0
 | |
| 					? `var ${externalWebpackNames.join(", ")};`
 | |
| 					: "";
 | |
| 
 | |
| 			// The system.register format requires an array of setter functions for externals.
 | |
| 			const setters =
 | |
| 				externalWebpackNames.length === 0
 | |
| 					? ""
 | |
| 					: Template.asString([
 | |
| 							"setters: [",
 | |
| 							Template.indent(
 | |
| 								externalWebpackNames
 | |
| 									.map(external =>
 | |
| 										Template.asString([
 | |
| 											"function(module) {",
 | |
| 											Template.indent(`${external} = module;`),
 | |
| 											"}"
 | |
| 										])
 | |
| 									)
 | |
| 									.join(",\n")
 | |
| 							),
 | |
| 							"],"
 | |
| 					  ]);
 | |
| 
 | |
| 			return new ConcatSource(
 | |
| 				Template.asString([
 | |
| 					`System.register(${name}${systemDependencies}, function(${dynamicExport}) {`,
 | |
| 					Template.indent([
 | |
| 						externalVarDeclarations,
 | |
| 						"return {",
 | |
| 						Template.indent([
 | |
| 							setters,
 | |
| 							"execute: function() {",
 | |
| 							Template.indent(`${dynamicExport}(`)
 | |
| 						])
 | |
| 					])
 | |
| 				]) + "\n",
 | |
| 				source,
 | |
| 				"\n" +
 | |
| 					Template.asString([
 | |
| 						Template.indent([
 | |
| 							Template.indent([Template.indent([");"]), "}"]),
 | |
| 							"};"
 | |
| 						]),
 | |
| 						"})"
 | |
| 					])
 | |
| 			);
 | |
| 		};
 | |
| 
 | |
| 		for (const template of [mainTemplate, chunkTemplate]) {
 | |
| 			template.hooks.renderWithEntry.tap(
 | |
| 				"SystemMainTemplatePlugin",
 | |
| 				onRenderWithEntry
 | |
| 			);
 | |
| 		}
 | |
| 
 | |
| 		mainTemplate.hooks.hash.tap("SystemMainTemplatePlugin", hash => {
 | |
| 			hash.update("exports system");
 | |
| 			if (this.name) {
 | |
| 				hash.update(this.name);
 | |
| 			}
 | |
| 		});
 | |
| 	}
 | |
| }
 | |
| 
 | |
| module.exports = SystemMainTemplatePlugin;
 |