123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- /*
- MIT License http://www.opensource.org/licenses/mit-license.php
- Author Tobias Koppers @sokra
- */
- "use strict";
- const NullDependency = require("./NullDependency");
-
- class HarmonyExportImportedSpecifierDependency extends NullDependency {
- constructor(originModule, importDependency, importedVar, id, name, activeExports, otherStarExports) {
- super();
- this.originModule = originModule;
- this.importDependency = importDependency;
- this.importedVar = importedVar;
- this.id = id;
- this.name = name;
- this.activeExports = activeExports;
- this.otherStarExports = otherStarExports;
- }
-
- get type() {
- return "harmony export imported specifier";
- }
-
- getReference() {
- const name = this.name;
- const used = this.originModule.isUsed(name);
- const importedModule = this.importDependency.module;
-
- if(!importedModule || !used || !this.originModule.usedExports) return null;
-
- const hasUsedExports = Array.isArray(this.originModule.usedExports);
-
- if(name) {
- const nameIsNotInUsedExports = hasUsedExports && this.originModule.usedExports.indexOf(name) < 0;
- if(nameIsNotInUsedExports) return null;
-
- // export { name as name }
- if(this.id) {
- return {
- module: importedModule,
- importedNames: [this.id]
- };
- }
-
- // export { * as name }
- return {
- module: importedModule,
- importedNames: true
- };
- }
-
- const hasProvidedExports = Array.isArray(importedModule.providedExports);
- const activeFromOtherStarExports = this._discoverActiveExportsFromOtherStartExports();
-
- // export *
- if(hasUsedExports) {
- // reexport * with known used exports
- const importedNames = this.originModule.usedExports.filter(id => {
- if(id === "default") return false;
- if(this.activeExports.has(id)) return false;
- if(activeFromOtherStarExports.has(id)) return false;
- if(hasProvidedExports && importedModule.providedExports.indexOf(id) < 0) return false;
-
- return true;
- });
-
- return {
- module: importedModule,
- importedNames
- };
- }
-
- if(hasProvidedExports) {
- return {
- module: importedModule,
- importedNames: importedModule.providedExports.filter(id => {
- if(id === "default") return false;
- if(this.activeExports.has(id)) return false;
- if(activeFromOtherStarExports.has(id)) return false;
-
- return true;
- })
- };
- }
-
- return {
- module: importedModule,
- importedNames: true,
- };
- }
-
- _discoverActiveExportsFromOtherStartExports() {
- if(!this.otherStarExports)
- return new Set();
- const result = new Set();
- // try to learn impossible exports from other star exports with provided exports
- for(const otherStarExport of this.otherStarExports) {
- const otherImportedModule = otherStarExport.importDependency.module;
- if(otherImportedModule && Array.isArray(otherImportedModule.providedExports)) {
- for(const exportName of otherImportedModule.providedExports)
- result.add(exportName);
- }
- }
- return result;
- }
-
- getExports() {
- if(this.name) {
- return {
- exports: [this.name]
- };
- }
-
- const importedModule = this.importDependency.module;
-
- if(!importedModule) {
- // no imported module available
- return {
- exports: null
- };
- }
-
- if(Array.isArray(importedModule.providedExports)) {
- return {
- exports: importedModule.providedExports.filter(id => id !== "default"),
- dependencies: [importedModule]
- };
- }
-
- if(importedModule.providedExports) {
- return {
- exports: true
- };
- }
-
- return {
- exports: null,
- dependencies: [importedModule]
- };
- }
-
- updateHash(hash) {
- super.updateHash(hash);
- const hashValue = this.getHashValue(this.importDependency.module);
- hash.update(hashValue);
- }
-
- getHashValue(importedModule) {
- if(!importedModule) {
- return "";
- }
-
- const stringifiedUsedExport = JSON.stringify(importedModule.usedExports);
- const stringifiedProvidedExport = JSON.stringify(importedModule.providedExports);
- return importedModule.used + stringifiedUsedExport + stringifiedProvidedExport;
- }
- }
-
- module.exports = HarmonyExportImportedSpecifierDependency;
-
- HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedSpecifierDependencyTemplate {
- apply(dep, source, outputOptions, requestShortener) {
- const content = this.getContent(dep);
- source.insert(-1, content);
- }
-
- getContent(dep) {
- const name = dep.importedVar;
- const used = dep.originModule.isUsed(dep.name);
- const importedModule = dep.importDependency.module;
- const importsExportsUnknown = !importedModule || !Array.isArray(importedModule.providedExports);
-
- const getReexportStatement = this.reexportStatementCreator(dep.originModule, importsExportsUnknown, name);
-
- // we want to rexport something, but the export isn't used
- if(!used) {
- return "/* unused harmony reexport " + dep.name + " */\n";
- }
-
- // we want to reexport the default export from a non-hamory module
- const isNotAHarmonyModule = !(importedModule && (!importedModule.meta || importedModule.meta.harmonyModule));
- if(dep.name && dep.id === "default" && isNotAHarmonyModule) {
- return "/* harmony reexport (default from non-hamory) */ " + getReexportStatement(JSON.stringify(used), null);
- }
-
- // we want to reexport a key as new key
- if(dep.name && dep.id) {
- var idUsed = importedModule && importedModule.isUsed(dep.id);
- return "/* harmony reexport (binding) */ " + getReexportStatement(JSON.stringify(used), JSON.stringify(idUsed));
- }
-
- // we want to reexport the module object as named export
- if(dep.name) {
- return "/* harmony reexport (module object) */ " + getReexportStatement(JSON.stringify(used), "");
- }
-
- const hasProvidedExports = importedModule && Array.isArray(importedModule.providedExports);
-
- const activeFromOtherStarExports = dep._discoverActiveExportsFromOtherStartExports();
-
- // we know which exports are used
- if(Array.isArray(dep.originModule.usedExports)) {
- const items = dep.originModule.usedExports.map(id => {
- if(id === "default") return;
- if(dep.activeExports.has(id)) return;
- if(importedModule.isProvided(id) === false) return;
- if(activeFromOtherStarExports.has(id)) return;
- var exportUsed = dep.originModule.isUsed(id);
- var idUsed = importedModule && importedModule.isUsed(id);
- return [exportUsed, idUsed];
- }).filter(Boolean);
-
- if(items.length === 0) {
- return "/* unused harmony namespace reexport */\n";
- }
-
- return items.map(function(item) {
- return "/* harmony namespace reexport (by used) */ " + getReexportStatement(JSON.stringify(item[0]), JSON.stringify(item[1]));
- }).join("");
- }
-
- // not sure which exports are used, but we know which are provided
- if(dep.originModule.usedExports && importedModule && hasProvidedExports) {
- const items = importedModule.providedExports.map(id => {
- if(id === "default") return;
- if(dep.activeExports.has(id)) return;
- if(activeFromOtherStarExports.has(id)) return;
- var exportUsed = dep.originModule.isUsed(id);
- var idUsed = importedModule && importedModule.isUsed(id);
- return [exportUsed, idUsed];
- }).filter(Boolean);
-
- if(items.length === 0) {
- return "/* empty harmony namespace reexport */\n";
- }
-
- return items.map(function(item) {
- return "/* harmony namespace reexport (by provided) */ " + getReexportStatement(JSON.stringify(item[0]), JSON.stringify(item[1]));
- }).join("");
- }
-
- // not sure which exports are used and provided
- if(dep.originModule.usedExports) {
- const activeExports = Array.from(dep.activeExports).concat(Array.from(activeFromOtherStarExports));
- let content = "/* harmony namespace reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in " + name + ") ";
-
- // Filter out exports which are defined by other exports
- // and filter out default export because it cannot be reexported with *
- if(activeExports.length > 0)
- content += "if(" + JSON.stringify(activeExports.concat("default")) + ".indexOf(__WEBPACK_IMPORT_KEY__) < 0) ";
- else
- content += "if(__WEBPACK_IMPORT_KEY__ !== 'default') ";
- const exportsName = dep.originModule.exportsArgument || "exports";
- return content + `(function(key) { __webpack_require__.d(${exportsName}, key, function() { return ${name}[key]; }) }(__WEBPACK_IMPORT_KEY__));\n`;
- }
-
- return "/* unused harmony reexport namespace */\n";
- }
-
- reexportStatementCreator(module, importsExportsUnknown, name) {
- const exportsName = module.exportsArgument || "exports";
- const getReexportStatement = (key, valueKey) => {
- const conditional = this.getConditional(importsExportsUnknown, valueKey, name);
- const returnValue = this.getReturnValue(valueKey);
- return `${conditional}__webpack_require__.d(${exportsName}, ${key}, function() { return ${name}${returnValue}; });\n`;
- };
- return getReexportStatement;
- }
-
- getConditional(importsExportsUnknown, valueKey, name) {
- if(!importsExportsUnknown || !valueKey) {
- return "";
- }
-
- return `if(__webpack_require__.o(${name}, ${valueKey})) `;
- }
-
- getReturnValue(valueKey) {
- if(valueKey === null) {
- return "_default.a";
- }
-
- return valueKey && "[" + valueKey + "]";
- }
- };
|