| 
									
										
										
										
											2019-03-02 05:26:36 +08:00
										 |  |  | /* | 
					
						
							|  |  |  |  MIT License http://www.opensource.org/licenses/mit-license.php
 | 
					
						
							|  |  |  |  Author Joel Denning @joeldenning | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | "use strict"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const { ConcatSource } = require("webpack-sources"); | 
					
						
							|  |  |  | 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 externals = chunk.getModules().filter(m => m.external); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// The name this bundle should be registered as with System
 | 
					
						
							| 
									
										
										
										
											2019-07-30 22:11:50 +08:00
										 |  |  | 			const name = this.name | 
					
						
							|  |  |  | 				? `${JSON.stringify( | 
					
						
							|  |  |  | 						mainTemplate.getAssetPath(this.name, { hash, chunk }) | 
					
						
							|  |  |  | 				  )}, `
 | 
					
						
							|  |  |  | 				: ""; | 
					
						
							| 
									
										
										
										
											2019-03-02 05:26:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// 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" ? m.request.amd : m.request | 
					
						
							|  |  |  | 				) | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// The name of the variable provided by System for exporting
 | 
					
						
							| 
									
										
										
										
											2019-03-19 05:20:28 +08:00
										 |  |  | 			const dynamicExport = "__WEBPACK_DYNAMIC_EXPORT__"; | 
					
						
							| 
									
										
										
										
											2019-03-02 05:26:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// An array of the internal variable names for the webpack externals
 | 
					
						
							|  |  |  | 			const externalWebpackNames = externals.map( | 
					
						
							|  |  |  | 				m => `__WEBPACK_EXTERNAL_MODULE_${Template.toIdentifier(`${m.id}`)}__` | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// Declaring variables for the internal variable names for the webpack externals
 | 
					
						
							|  |  |  | 			const externalVarDeclarations = | 
					
						
							|  |  |  | 				externalWebpackNames.length > 0 | 
					
						
							| 
									
										
										
										
											2019-03-19 05:20:28 +08:00
										 |  |  | 					? `var ${externalWebpackNames.join(", ")};` | 
					
						
							|  |  |  | 					: ""; | 
					
						
							| 
									
										
										
										
											2019-03-02 05:26:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// The system.register format requires an array of setter functions for externals.
 | 
					
						
							|  |  |  | 			const setters = | 
					
						
							|  |  |  | 				externalWebpackNames.length === 0 | 
					
						
							|  |  |  | 					? "" | 
					
						
							| 
									
										
										
										
											2019-03-19 05:20:28 +08:00
										 |  |  | 					: Template.asString([ | 
					
						
							|  |  |  | 							"setters: [", | 
					
						
							|  |  |  | 							Template.indent( | 
					
						
							| 
									
										
										
										
											2019-04-10 19:29:35 +08:00
										 |  |  | 								externalWebpackNames | 
					
						
							|  |  |  | 									.map(external => | 
					
						
							|  |  |  | 										Template.asString([ | 
					
						
							|  |  |  | 											"function(module) {", | 
					
						
							|  |  |  | 											Template.indent(`${external} = module;`), | 
					
						
							|  |  |  | 											"}" | 
					
						
							|  |  |  | 										]) | 
					
						
							|  |  |  | 									) | 
					
						
							|  |  |  | 									.join(",\n") | 
					
						
							| 
									
										
										
										
											2019-03-19 05:20:28 +08:00
										 |  |  | 							), | 
					
						
							|  |  |  | 							"]," | 
					
						
							|  |  |  | 					  ]); | 
					
						
							| 
									
										
										
										
											2019-03-02 05:26:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			return new ConcatSource( | 
					
						
							| 
									
										
										
										
											2019-03-19 05:20:28 +08:00
										 |  |  | 				Template.asString([ | 
					
						
							|  |  |  | 					`System.register(${name}${systemDependencies}, function(${dynamicExport}) {`, | 
					
						
							|  |  |  | 					Template.indent([ | 
					
						
							|  |  |  | 						externalVarDeclarations, | 
					
						
							|  |  |  | 						"return {", | 
					
						
							|  |  |  | 						Template.indent([ | 
					
						
							|  |  |  | 							setters, | 
					
						
							|  |  |  | 							"execute: function() {", | 
					
						
							|  |  |  | 							Template.indent(`${dynamicExport}(`) | 
					
						
							|  |  |  | 						]) | 
					
						
							|  |  |  | 					]) | 
					
						
							| 
									
										
										
										
											2019-04-10 19:29:35 +08:00
										 |  |  | 				]) + "\n", | 
					
						
							| 
									
										
										
										
											2019-03-02 05:26:36 +08:00
										 |  |  | 				source, | 
					
						
							| 
									
										
										
										
											2019-04-10 19:29:35 +08:00
										 |  |  | 				"\n" + | 
					
						
							|  |  |  | 					Template.asString([ | 
					
						
							|  |  |  | 						Template.indent([ | 
					
						
							|  |  |  | 							Template.indent([Template.indent([");"]), "}"]), | 
					
						
							|  |  |  | 							"};" | 
					
						
							|  |  |  | 						]), | 
					
						
							|  |  |  | 						"})" | 
					
						
							|  |  |  | 					]) | 
					
						
							| 
									
										
										
										
											2019-03-02 05:26:36 +08:00
										 |  |  | 			); | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		for (const template of [mainTemplate, chunkTemplate]) { | 
					
						
							|  |  |  | 			template.hooks.renderWithEntry.tap( | 
					
						
							|  |  |  | 				"SystemMainTemplatePlugin", | 
					
						
							|  |  |  | 				onRenderWithEntry | 
					
						
							|  |  |  | 			); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		mainTemplate.hooks.globalHashPaths.tap( | 
					
						
							|  |  |  | 			"SystemMainTemplatePlugin", | 
					
						
							|  |  |  | 			paths => { | 
					
						
							|  |  |  | 				if (this.name) { | 
					
						
							|  |  |  | 					paths.push(this.name); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				return paths; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		mainTemplate.hooks.hash.tap("SystemMainTemplatePlugin", hash => { | 
					
						
							|  |  |  | 			hash.update("exports system"); | 
					
						
							|  |  |  | 			if (this.name) { | 
					
						
							|  |  |  | 				hash.update(this.name); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = SystemMainTemplatePlugin; |