Merge pull request #11117 from vankop/add-export-as-from
add export * as namespace from "module"
This commit is contained in:
commit
e8ed3d8d3b
|
@ -33,16 +33,10 @@ const HarmonyImportDependency = require("./HarmonyImportDependency");
|
|||
|
||||
const idsSymbol = Symbol("HarmonyExportImportedSpecifierDependency.ids");
|
||||
|
||||
/** @type {Map<string, string[]>} */
|
||||
const EMPTY_MAP = new Map();
|
||||
|
||||
/** @type {Set<string>} */
|
||||
const EMPTY_SET = new Set();
|
||||
|
||||
/**
|
||||
* @param {string[][]} referencedExports list of referenced exports, will be added to
|
||||
* @param {string[]} prefix export prefix
|
||||
* @param {ExportInfo} exportInfo the export info
|
||||
* @param {ExportInfo=} exportInfo the export info
|
||||
* @param {boolean} defaultPointsToSelf when true, using default will reference itself
|
||||
* @param {Set<ExportInfo>} alreadyVisited already visited export info (to handle circular reexports)
|
||||
*/
|
||||
|
@ -82,6 +76,21 @@ const processExportInfo = (
|
|||
}
|
||||
};
|
||||
|
||||
class NormalReexportItem {
|
||||
/**
|
||||
* @param {string} name export name
|
||||
* @param {string[]} ids reexported ids from other module
|
||||
* @param {ExportInfo=} exportInfo export info from other module
|
||||
* @param {boolean} checked true, if it should be checked at runtime if this export exists
|
||||
*/
|
||||
constructor(name, ids, exportInfo, checked) {
|
||||
this.name = name;
|
||||
this.ids = ids;
|
||||
this.exportInfo = exportInfo;
|
||||
this.checked = checked;
|
||||
}
|
||||
}
|
||||
|
||||
class ExportMode {
|
||||
/**
|
||||
* @param {ExportModeType} type type of the mode
|
||||
|
@ -89,18 +98,26 @@ class ExportMode {
|
|||
constructor(type) {
|
||||
/** @type {ExportModeType} */
|
||||
this.type = type;
|
||||
|
||||
// for "normal-reexport":
|
||||
/** @type {NormalReexportItem[] | null} */
|
||||
this.items = null;
|
||||
|
||||
// for "reexport-named-default" | "reexport-fake-namespace-object" | "reexport-namespace-object"
|
||||
/** @type {string|null} */
|
||||
this.name = null;
|
||||
/** @type {Map<string, string[]>} */
|
||||
this.map = EMPTY_MAP;
|
||||
/** @type {ExportInfo} */
|
||||
this.partialNamespaceExportInfo = undefined;
|
||||
/** @type {Set<string>|null} */
|
||||
/** @type {ExportInfo | null} */
|
||||
this.partialNamespaceExportInfo = null;
|
||||
|
||||
// for "dynamic-reexport":
|
||||
/** @type {Set<string> | null} */
|
||||
this.ignored = null;
|
||||
/** @type {Set<string>|null} */
|
||||
this.checked = null;
|
||||
/** @type {string|null} */
|
||||
|
||||
// for "missing":
|
||||
/** @type {string | null} */
|
||||
this.userRequest = null;
|
||||
|
||||
// for "reexport-fake-namespace-object":
|
||||
/** @type {number} */
|
||||
this.fakeType = 0;
|
||||
}
|
||||
|
@ -245,12 +262,11 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
break;
|
||||
default:
|
||||
mode = new ExportMode("normal-reexport");
|
||||
mode.map = new Map([[name, ids]]);
|
||||
mode.checked = EMPTY_SET;
|
||||
mode.items = [new NormalReexportItem(name, ids, exportInfo, false)];
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// export { * as name }
|
||||
// export * as name
|
||||
switch (importedExportsType) {
|
||||
case "default-only":
|
||||
mode = new ExportMode("reexport-fake-namespace-object");
|
||||
|
@ -303,16 +319,18 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
return mode;
|
||||
}
|
||||
|
||||
/** @type {Map<string, string[]>} */
|
||||
const map = new Map();
|
||||
for (const exportName of exports) {
|
||||
map.set(exportName, [exportName]);
|
||||
}
|
||||
|
||||
const mode = new ExportMode("normal-reexport");
|
||||
|
||||
mode.map = map;
|
||||
mode.checked = checked;
|
||||
mode.items = Array.from(
|
||||
exports,
|
||||
exportName =>
|
||||
new NormalReexportItem(
|
||||
exportName,
|
||||
[exportName],
|
||||
exportsInfo.getReadOnlyExportInfo(exportName),
|
||||
checked.has(exportName)
|
||||
)
|
||||
);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
@ -419,7 +437,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
processExportInfo(
|
||||
referencedExports,
|
||||
[],
|
||||
mode.partialNamespaceExportInfo
|
||||
/** @type {ExportInfo} */ (mode.partialNamespaceExportInfo)
|
||||
);
|
||||
return referencedExports;
|
||||
}
|
||||
|
@ -433,7 +451,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
processExportInfo(
|
||||
referencedExports,
|
||||
[],
|
||||
mode.partialNamespaceExportInfo,
|
||||
/** @type {ExportInfo} */ (mode.partialNamespaceExportInfo),
|
||||
mode.type === "reexport-fake-namespace-object"
|
||||
);
|
||||
return referencedExports;
|
||||
|
@ -442,8 +460,13 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
case "dynamic-reexport":
|
||||
return Dependency.EXPORTS_OBJECT_REFERENCED;
|
||||
|
||||
case "normal-reexport":
|
||||
return Array.from(mode.map.values());
|
||||
case "normal-reexport": {
|
||||
const referencedExports = [];
|
||||
for (const { ids, exportInfo } of mode.items) {
|
||||
processExportInfo(referencedExports, ids, exportInfo, false);
|
||||
}
|
||||
return referencedExports;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown mode ${mode.type}`);
|
||||
|
@ -502,15 +525,17 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
exports: [],
|
||||
dependencies: [moduleGraph.getModule(this)]
|
||||
};
|
||||
case "normal-reexport":
|
||||
case "normal-reexport": {
|
||||
const from = moduleGraph.getModule(this);
|
||||
return {
|
||||
exports: Array.from(mode.map.keys()).map(name => ({
|
||||
name,
|
||||
from: moduleGraph.getModule(this),
|
||||
export: mode.map.get(name)
|
||||
exports: Array.from(mode.items, item => ({
|
||||
name: item.name,
|
||||
from,
|
||||
export: item.ids
|
||||
})),
|
||||
dependencies: [moduleGraph.getModule(this)]
|
||||
dependencies: [from]
|
||||
};
|
||||
}
|
||||
case "reexport-dynamic-default":
|
||||
case "reexport-undefined":
|
||||
return {
|
||||
|
@ -620,9 +645,12 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
const mode = this.getMode(chunkGraph.moduleGraph);
|
||||
|
||||
hash.update(mode.type);
|
||||
for (const [k, v] of mode.map) {
|
||||
hash.update(k);
|
||||
hash.update(v.join());
|
||||
if (mode.items) {
|
||||
for (const item of mode.items) {
|
||||
hash.update(item.name);
|
||||
hash.update(item.ids.join());
|
||||
if (item.checked) hash.update("checked");
|
||||
}
|
||||
}
|
||||
if (mode.ignored) {
|
||||
hash.update("ignored");
|
||||
|
@ -803,16 +831,16 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
|
|||
break;
|
||||
|
||||
case "normal-reexport":
|
||||
for (const [key, id] of mode.map) {
|
||||
if (mode.checked.has(key)) {
|
||||
for (const { name, ids, checked } of mode.items) {
|
||||
if (checked) {
|
||||
initFragments.push(
|
||||
new InitFragment(
|
||||
"/* harmony reexport (checked) */ " +
|
||||
this.getConditionalReexportStatement(
|
||||
module,
|
||||
key,
|
||||
name,
|
||||
importVar,
|
||||
id,
|
||||
ids,
|
||||
runtimeRequirements
|
||||
),
|
||||
InitFragment.STAGE_HARMONY_IMPORTS,
|
||||
|
@ -824,9 +852,9 @@ HarmonyExportImportedSpecifierDependency.Template = class HarmonyExportImportedS
|
|||
this.getReexportFragment(
|
||||
module,
|
||||
"reexport safe",
|
||||
module.getUsedName(moduleGraph, key),
|
||||
module.getUsedName(moduleGraph, name),
|
||||
importVar,
|
||||
importedModule.getUsedName(moduleGraph, id),
|
||||
importedModule.getUsedName(moduleGraph, ids),
|
||||
runtimeRequirements
|
||||
)
|
||||
);
|
||||
|
|
|
@ -1729,8 +1729,9 @@ class JavascriptParser extends Parser {
|
|||
|
||||
blockPreWalkExportAllDeclaration(statement) {
|
||||
const source = statement.source.value;
|
||||
const name = statement.exported ? statement.exported.name : null;
|
||||
this.hooks.exportImport.call(statement, source);
|
||||
this.hooks.exportImportSpecifier.call(statement, source, null, null, 0);
|
||||
this.hooks.exportImportSpecifier.call(statement, source, null, name, 0);
|
||||
}
|
||||
|
||||
preWalkVariableDeclaration(statement) {
|
||||
|
|
|
@ -214,15 +214,15 @@ class SideEffectsFlagPlugin {
|
|||
const targetModule = moduleGraph.getModule(dep);
|
||||
switch (mode.type) {
|
||||
case "normal-reexport":
|
||||
for (const [key, ids] of mode.map) {
|
||||
for (const { name, ids, checked } of mode.items) {
|
||||
// TODO Support reexporting namespace object
|
||||
if (ids.length > 0) {
|
||||
addStaticReexport(
|
||||
info,
|
||||
key,
|
||||
name,
|
||||
targetModule,
|
||||
ids[0],
|
||||
mode.checked.has(key)
|
||||
checked
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
"description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "0.0.42",
|
||||
"@types/estree": "^0.0.45",
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-module-context": "1.9.0",
|
||||
"@webassemblyjs/wasm-edit": "1.9.0",
|
||||
"@webassemblyjs/wasm-parser": "1.9.0",
|
||||
"acorn": "^7.0.0",
|
||||
"acorn": "^7.3.0",
|
||||
"chrome-trace-event": "^1.0.2",
|
||||
"enhanced-resolve": "5.0.0-beta.7",
|
||||
"eslint-scope": "^5.0.0",
|
||||
|
|
|
@ -2738,7 +2738,7 @@ Entrypoint main = main.js
|
|||
`;
|
||||
|
||||
exports[`StatsTestCases should print correct stats for side-effects-optimization 1`] = `
|
||||
"Hash: d7d1b4f45cd90d4abdb64369e7ea517dce8ffb09
|
||||
"Hash: d7d1b4f45cd90d4abdb6d61ad7aea717eb8e1363
|
||||
Child
|
||||
Hash: d7d1b4f45cd90d4abdb6
|
||||
Time: X ms
|
||||
|
@ -2762,7 +2762,7 @@ Child
|
|||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||
+ 2 hidden modules
|
||||
Child
|
||||
Hash: 4369e7ea517dce8ffb09
|
||||
Hash: d61ad7aea717eb8e1363
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
|
@ -3843,7 +3843,7 @@ chunk default/async-a.js (async-a) 134 bytes <{179}> [rendered]
|
|||
`;
|
||||
|
||||
exports[`StatsTestCases should print correct stats for tree-shaking 1`] = `
|
||||
"Hash: 0653813b0ee99f2a94bd
|
||||
"Hash: cd2fbd230872570f58af
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
import {c} from "./c.js";
|
||||
|
||||
const b2 = 3;
|
||||
const b3 = c;
|
||||
export {c as b1, c as b4, b2, b3}
|
||||
export const usedB1 = __webpack_exports_info__.b1.used;
|
||||
export const usedB2 = __webpack_exports_info__.b2.used;
|
||||
export const usedB3 = __webpack_exports_info__.b3.used;
|
||||
export const usedB4 = __webpack_exports_info__.b4.used;
|
|
@ -0,0 +1 @@
|
|||
export * as c from "./d.js";
|
|
@ -0,0 +1,4 @@
|
|||
export const d1 = 1;
|
||||
export const d2 = 2;
|
||||
export const usedD1 = __webpack_exports_info__.d1.used;
|
||||
export const usedD2 = __webpack_exports_info__.d2.used;
|
|
@ -0,0 +1,4 @@
|
|||
export const e1 = 10;
|
||||
export const e2 = 20;
|
||||
export const usedE1 = __webpack_exports_info__.e1.used;
|
||||
export const usedE2 = __webpack_exports_info__.e2.used;
|
|
@ -0,0 +1 @@
|
|||
export * as e from "./e.js";
|
|
@ -0,0 +1,2 @@
|
|||
export * as f1 from "./e1.js";
|
||||
export * as f2 from "./e.js";
|
|
@ -0,0 +1,3 @@
|
|||
import {f1, f2} from "./f.js";
|
||||
|
||||
export {f1, f2 as g1};
|
|
@ -0,0 +1 @@
|
|||
export * as h from "./g.js";
|
|
@ -1,8 +1,31 @@
|
|||
"use strict";
|
||||
|
||||
import { x, y } from "./a";
|
||||
import {d2, usedD1, usedD2} from "./d.js";
|
||||
import {b1, usedB1, usedB2, usedB3, usedB4} from "./b.js";
|
||||
import {usedE1, usedE2} from "./e.js";
|
||||
import {h} from "./h.js";
|
||||
|
||||
it("namespace export as from commonjs should override named export", function() {
|
||||
expect(x).toBe(1);
|
||||
expect(y).toBe(3);
|
||||
});
|
||||
|
||||
it("named namespace export should work correctly", function () {
|
||||
expect(d2).toBe(2);
|
||||
expect(usedD1).toBe(false);
|
||||
expect(usedD2).toBe(true);
|
||||
|
||||
expect(b1.d2).toBe(2);
|
||||
expect(usedB1).toBe(true);
|
||||
expect(usedB2).toBe(false);
|
||||
expect(usedB3).toBe(false);
|
||||
expect(usedB4).toBe(false);
|
||||
});
|
||||
|
||||
it("complex case should work correctly", () => {
|
||||
expect(h.f1.e.e1).toBe(10);
|
||||
expect(h.g1.e1).toBe(10);
|
||||
expect(usedE1).toBe(true);
|
||||
expect(usedE2).toBe(false);
|
||||
});
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
BinaryExpression,
|
||||
BlockStatement,
|
||||
BreakStatement,
|
||||
ChainExpression,
|
||||
ClassDeclaration,
|
||||
ClassExpression,
|
||||
Comment,
|
||||
|
@ -32,6 +33,7 @@ import {
|
|||
Identifier,
|
||||
IfStatement,
|
||||
ImportDeclaration,
|
||||
ImportExpression,
|
||||
LabeledStatement,
|
||||
LogicalExpression,
|
||||
MemberExpression,
|
||||
|
@ -2521,7 +2523,9 @@ type Expression =
|
|||
| ClassExpression
|
||||
| MetaProperty
|
||||
| Identifier
|
||||
| AwaitExpression;
|
||||
| AwaitExpression
|
||||
| ImportExpression
|
||||
| ChainExpression;
|
||||
type ExternalItem =
|
||||
| string
|
||||
| RegExp
|
||||
|
@ -3412,6 +3416,8 @@ declare abstract class JavascriptParser extends Parser {
|
|||
| MetaProperty
|
||||
| Identifier
|
||||
| AwaitExpression
|
||||
| ImportExpression
|
||||
| ChainExpression
|
||||
| Super;
|
||||
};
|
||||
getFreeInfoFromVariable(
|
||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -622,10 +622,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
||||
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
|
||||
|
||||
"@types/estree@0.0.42":
|
||||
version "0.0.42"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.42.tgz#8d0c1f480339efedb3e46070e22dd63e0430dd11"
|
||||
integrity sha512-K1DPVvnBCPxzD+G51/cxVIoc2X8uUVl1zpJeE6iKcgHMj4+tbat5Xu4TjV7v2QSDbIeAfLi2hIk+u2+s0MlpUQ==
|
||||
"@types/estree@^0.0.45":
|
||||
version "0.0.45"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884"
|
||||
integrity sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g==
|
||||
|
||||
"@types/graceful-fs@^4.1.2":
|
||||
version "4.1.3"
|
||||
|
@ -965,7 +965,7 @@ acorn@^6.0.1:
|
|||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.3.0.tgz#0087509119ffa4fc0a0041d1e93a417e68cb856e"
|
||||
integrity sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==
|
||||
|
||||
acorn@^7.0.0, acorn@^7.1.0:
|
||||
acorn@^7.1.0, acorn@^7.3.0:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.3.1.tgz#85010754db53c3fbaf3b9ea3e083aa5c5d147ffd"
|
||||
integrity sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==
|
||||
|
|
Loading…
Reference in New Issue