134 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*
 | |
| 	MIT License http://www.opensource.org/licenses/mit-license.php
 | |
| 	Author Ivan Kopeykin @vankop
 | |
| */
 | |
| 
 | |
| "use strict";
 | |
| 
 | |
| const InitFragment = require("../InitFragment");
 | |
| const makeSerializable = require("../util/makeSerializable");
 | |
| 
 | |
| /** @typedef {import("webpack-sources").Source} Source */
 | |
| /** @typedef {import("../Generator").GenerateContext} GenerateContext */
 | |
| /** @typedef {import("../serialization/ObjectMiddleware").ObjectDeserializerContext} ObjectDeserializerContext */
 | |
| /** @typedef {import("../serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
 | |
| /** @typedef {Map<string, Set<string>>} ImportSpecifiers */
 | |
| 
 | |
| /**
 | |
|  * @extends {InitFragment<GenerateContext>}
 | |
|  */
 | |
| class ExternalModuleInitFragment extends InitFragment {
 | |
| 	/**
 | |
| 	 * @param {string} importedModule imported module
 | |
| 	 * @param {Array<{ name: string, value?: string }> | ImportSpecifiers} specifiers import specifiers
 | |
| 	 * @param {string=} defaultImport default import
 | |
| 	 */
 | |
| 	constructor(importedModule, specifiers, defaultImport) {
 | |
| 		super(
 | |
| 			undefined,
 | |
| 			InitFragment.STAGE_CONSTANTS,
 | |
| 			0,
 | |
| 			`external module imports|${importedModule}|${defaultImport || "null"}`
 | |
| 		);
 | |
| 		this.importedModule = importedModule;
 | |
| 		if (Array.isArray(specifiers)) {
 | |
| 			/** @type {ImportSpecifiers} */
 | |
| 			this.specifiers = new Map();
 | |
| 			for (const { name, value } of specifiers) {
 | |
| 				let specifiers = this.specifiers.get(name);
 | |
| 				if (!specifiers) {
 | |
| 					specifiers = new Set();
 | |
| 					this.specifiers.set(name, specifiers);
 | |
| 				}
 | |
| 				specifiers.add(value || name);
 | |
| 			}
 | |
| 		} else {
 | |
| 			this.specifiers = specifiers;
 | |
| 		}
 | |
| 		this.defaultImport = defaultImport;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param {ExternalModuleInitFragment} other other
 | |
| 	 * @returns {ExternalModuleInitFragment} ExternalModuleInitFragment
 | |
| 	 */
 | |
| 	merge(other) {
 | |
| 		const newSpecifiersMap = new Map(this.specifiers);
 | |
| 		for (const [name, specifiers] of other.specifiers) {
 | |
| 			if (newSpecifiersMap.has(name)) {
 | |
| 				const currentSpecifiers =
 | |
| 					/** @type {Set<string>} */
 | |
| 					(newSpecifiersMap.get(name));
 | |
| 				for (const spec of specifiers) currentSpecifiers.add(spec);
 | |
| 			} else {
 | |
| 				newSpecifiersMap.set(name, specifiers);
 | |
| 			}
 | |
| 		}
 | |
| 		return new ExternalModuleInitFragment(
 | |
| 			this.importedModule,
 | |
| 			newSpecifiersMap,
 | |
| 			this.defaultImport
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param {GenerateContext} context context
 | |
| 	 * @returns {string | Source | undefined} the source code that will be included as initialization code
 | |
| 	 */
 | |
| 	getContent({ runtimeRequirements }) {
 | |
| 		const namedImports = [];
 | |
| 
 | |
| 		for (const [name, specifiers] of this.specifiers) {
 | |
| 			for (const spec of specifiers) {
 | |
| 				if (spec === name) {
 | |
| 					namedImports.push(name);
 | |
| 				} else {
 | |
| 					namedImports.push(`${name} as ${spec}`);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		let importsString =
 | |
| 			namedImports.length > 0 ? `{${namedImports.join(",")}}` : "";
 | |
| 
 | |
| 		if (this.defaultImport) {
 | |
| 			importsString = `${this.defaultImport}${
 | |
| 				importsString ? `, ${importsString}` : ""
 | |
| 			}`;
 | |
| 		}
 | |
| 
 | |
| 		return `import ${importsString} from ${JSON.stringify(
 | |
| 			this.importedModule
 | |
| 		)};`;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param {ObjectSerializerContext} context context
 | |
| 	 */
 | |
| 	serialize(context) {
 | |
| 		super.serialize(context);
 | |
| 		const { write } = context;
 | |
| 		write(this.importedModule);
 | |
| 		write(this.specifiers);
 | |
| 		write(this.defaultImport);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param {ObjectDeserializerContext} context context
 | |
| 	 */
 | |
| 	deserialize(context) {
 | |
| 		super.deserialize(context);
 | |
| 		const { read } = context;
 | |
| 		this.importedModule = read();
 | |
| 		this.specifiers = read();
 | |
| 		this.defaultImport = read();
 | |
| 	}
 | |
| }
 | |
| 
 | |
| makeSerializable(
 | |
| 	ExternalModuleInitFragment,
 | |
| 	"webpack/lib/dependencies/ExternalModuleInitFragment"
 | |
| );
 | |
| 
 | |
| module.exports = ExternalModuleInitFragment;
 |