@esmx/core 3.0.0-rc.69 → 3.0.0-rc.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -7
- package/README.zh-CN.md +10 -7
- package/dist/cli/cli.mjs +9 -4
- package/dist/core.mjs +3 -3
- package/dist/utils/import-map.d.ts +12 -9
- package/dist/utils/import-map.mjs +56 -6
- package/dist/utils/import-map.test.mjs +214 -68
- package/package.json +9 -9
- package/src/cli/cli.ts +11 -5
- package/src/core.ts +3 -3
- package/src/utils/import-map.test.ts +228 -70
- package/src/utils/import-map.ts +73 -11
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
</a>
|
|
21
21
|
</div>
|
|
22
22
|
|
|
23
|
-
<p>A high-performance microfrontend framework supporting Vue, React, Preact, Solid, and Svelte with SSR and Module
|
|
23
|
+
<p>A high-performance microfrontend framework supporting Vue, React, Preact, Solid, and Svelte with SSR and Module Linking capabilities</p>
|
|
24
24
|
|
|
25
25
|
<p>
|
|
26
26
|
English | <a href="https://github.com/esmnext/esmx/blob/master/packages/core/README.zh-CN.md">中文</a>
|
|
@@ -38,16 +38,19 @@
|
|
|
38
38
|
## 📦 Installation
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
+
# npm
|
|
41
42
|
npm install @esmx/core
|
|
42
|
-
```
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
# pnpm
|
|
45
|
+
pnpm add @esmx/core
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
# yarn
|
|
48
|
+
yarn add @esmx/core
|
|
48
49
|
```
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
## 🚀 Quick Start
|
|
52
|
+
|
|
53
|
+
See Quick Start guide: https://esmx.dev/guide/start/getting-started.html
|
|
51
54
|
|
|
52
55
|
## 📚 Documentation
|
|
53
56
|
|
|
@@ -55,4 +58,4 @@ Visit the [official documentation](https://esmx.dev) for detailed usage guides a
|
|
|
55
58
|
|
|
56
59
|
## 📄 License
|
|
57
60
|
|
|
58
|
-
MIT © [Esmx Team](https://github.com/esmnext/esmx)
|
|
61
|
+
MIT © [Esmx Team](https://github.com/esmnext/esmx)
|
package/README.zh-CN.md
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
</a>
|
|
21
21
|
</div>
|
|
22
22
|
|
|
23
|
-
<p>支持 Vue、React、Preact、Solid、Svelte 的高性能微前端框架,具备 SSR
|
|
23
|
+
<p>支持 Vue、React、Preact、Solid、Svelte 的高性能微前端框架,具备 SSR 和模块链接能力</p>
|
|
24
24
|
|
|
25
25
|
<p>
|
|
26
26
|
<a href="https://github.com/esmnext/esmx/blob/master/packages/core/README.md">English</a> | 中文
|
|
@@ -38,16 +38,19 @@
|
|
|
38
38
|
## 📦 安装
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
+
# npm
|
|
41
42
|
npm install @esmx/core
|
|
42
|
-
```
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
# pnpm
|
|
45
|
+
pnpm add @esmx/core
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
# yarn
|
|
48
|
+
yarn add @esmx/core
|
|
48
49
|
```
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
## 🚀 快速开始
|
|
52
|
+
|
|
53
|
+
查看快速开始指南:https://esmx.dev/zh-CN/guide/start/getting-started.html
|
|
51
54
|
|
|
52
55
|
## 📚 文档
|
|
53
56
|
|
|
@@ -55,4 +58,4 @@ npm install @esmx/core
|
|
|
55
58
|
|
|
56
59
|
## 📄 许可证
|
|
57
60
|
|
|
58
|
-
MIT © [Esmx Team](https://github.com/esmnext/esmx)
|
|
61
|
+
MIT © [Esmx Team](https://github.com/esmnext/esmx)
|
package/dist/cli/cli.mjs
CHANGED
|
@@ -10,12 +10,17 @@ async function getSrcOptions() {
|
|
|
10
10
|
}
|
|
11
11
|
async function getDistOptions() {
|
|
12
12
|
try {
|
|
13
|
-
|
|
13
|
+
const m = await import(resolveImportPath(process.cwd(), "./dist/node/src/entry.node.mjs"));
|
|
14
|
+
return m.default;
|
|
14
15
|
} catch (e) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
console.error(
|
|
17
|
+
styleText(
|
|
18
|
+
"red",
|
|
19
|
+
"Failed to load dist entry: dist/node/src/entry.node.mjs"
|
|
20
|
+
)
|
|
18
21
|
);
|
|
22
|
+
console.error(styleText("yellow", "Run `esmx build` and try again."));
|
|
23
|
+
process.exit(17);
|
|
19
24
|
}
|
|
20
25
|
}
|
|
21
26
|
export async function cli(command) {
|
package/dist/core.mjs
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
parsePackConfig
|
|
15
15
|
} from "./pack-config.mjs";
|
|
16
16
|
import { createCache } from "./utils/cache.mjs";
|
|
17
|
-
import {
|
|
17
|
+
import { createClientImportMap, createImportMap } from "./utils/import-map.mjs";
|
|
18
18
|
import { resolvePath } from "./utils/resolve-path.mjs";
|
|
19
19
|
import { getImportPreloadInfo as getStaticImportPaths } from "./utils/static-import-lexer.mjs";
|
|
20
20
|
export var COMMAND = /* @__PURE__ */ ((COMMAND2) => {
|
|
@@ -677,7 +677,7 @@ export class Esmx {
|
|
|
677
677
|
let json = {};
|
|
678
678
|
switch (env) {
|
|
679
679
|
case "client": {
|
|
680
|
-
json =
|
|
680
|
+
json = createClientImportMap({
|
|
681
681
|
manifests,
|
|
682
682
|
getScope(name, scope) {
|
|
683
683
|
return `/${name}${scope}`;
|
|
@@ -689,7 +689,7 @@ export class Esmx {
|
|
|
689
689
|
break;
|
|
690
690
|
}
|
|
691
691
|
case "server":
|
|
692
|
-
json =
|
|
692
|
+
json = createImportMap({
|
|
693
693
|
manifests,
|
|
694
694
|
getScope: (name, scope) => {
|
|
695
695
|
const linkPath = moduleConfig.links[name].server;
|
|
@@ -14,21 +14,22 @@ export interface GetImportMapOptions {
|
|
|
14
14
|
getScope: (name: string, scope: string) => string;
|
|
15
15
|
getFile: (name: string, file: string) => string;
|
|
16
16
|
}
|
|
17
|
-
export declare function
|
|
18
|
-
export declare function
|
|
17
|
+
export declare function createImportsMap(manifests: readonly ImportMapManifest[], getFile: (name: string, file: string) => string): SpecifierMap;
|
|
18
|
+
export declare function createScopesMap(imports: SpecifierMap, manifests: readonly ImportMapManifest[], getScope: (name: string, scope: string) => string): ScopesMap;
|
|
19
19
|
/**
|
|
20
|
-
* Fixes
|
|
20
|
+
* Fixes the nested scope resolution issue in import maps across all browsers.
|
|
21
21
|
*
|
|
22
|
-
*
|
|
22
|
+
* Import Maps have a cross-browser issue where nested scopes are not resolved correctly.
|
|
23
23
|
* For example, when you have both "/shared-modules/" and "/shared-modules/vue2/" scopes,
|
|
24
|
-
*
|
|
24
|
+
* browsers fail to properly apply the more specific nested scope.
|
|
25
25
|
*
|
|
26
|
-
* This function works around the
|
|
26
|
+
* This function works around the issue by:
|
|
27
27
|
* 1. Sorting scopes by path depth (shallow paths first, deeper paths last)
|
|
28
28
|
* 2. Manually applying scopes to matching imports in the correct order
|
|
29
|
+
* 3. Converting pattern-based scopes to concrete path scopes
|
|
29
30
|
*
|
|
30
31
|
* @example
|
|
31
|
-
* Problematic import map that fails in
|
|
32
|
+
* Problematic import map that fails in browsers:
|
|
32
33
|
* ```json
|
|
33
34
|
* {
|
|
34
35
|
* "scopes": {
|
|
@@ -45,5 +46,7 @@ export declare function buildScopesMap(imports: SpecifierMap, manifests: readonl
|
|
|
45
46
|
* @see https://github.com/guybedford/es-module-shims/issues/529
|
|
46
47
|
* @see https://issues.chromium.org/issues/453147451
|
|
47
48
|
*/
|
|
48
|
-
export declare function
|
|
49
|
-
export declare function
|
|
49
|
+
export declare function fixImportMapNestedScopes(importMap: Required<ImportMap>): Required<ImportMap>;
|
|
50
|
+
export declare function compressImportMap(importMap: Required<ImportMap>): ImportMap;
|
|
51
|
+
export declare function createImportMap({ manifests, getFile, getScope }: GetImportMapOptions): Required<ImportMap>;
|
|
52
|
+
export declare function createClientImportMap(options: GetImportMapOptions): ImportMap;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { pathWithoutIndex } from "./path-without-index.mjs";
|
|
2
|
-
export function
|
|
2
|
+
export function createImportsMap(manifests, getFile) {
|
|
3
3
|
const imports = {};
|
|
4
4
|
manifests.forEach((manifest) => {
|
|
5
5
|
Object.entries(manifest.exports).forEach(([, exportItem]) => {
|
|
@@ -10,7 +10,7 @@ export function buildImportsMap(manifests, getFile) {
|
|
|
10
10
|
pathWithoutIndex(imports);
|
|
11
11
|
return imports;
|
|
12
12
|
}
|
|
13
|
-
export function
|
|
13
|
+
export function createScopesMap(imports, manifests, getScope) {
|
|
14
14
|
const scopes = {};
|
|
15
15
|
manifests.forEach((manifest) => {
|
|
16
16
|
if (!manifest.scopes) {
|
|
@@ -30,7 +30,7 @@ export function buildScopesMap(imports, manifests, getScope) {
|
|
|
30
30
|
});
|
|
31
31
|
return scopes;
|
|
32
32
|
}
|
|
33
|
-
export function
|
|
33
|
+
export function fixImportMapNestedScopes(importMap) {
|
|
34
34
|
Object.entries(importMap.scopes).sort(([pathA], [pathB]) => {
|
|
35
35
|
const depthA = pathA.split("/").length;
|
|
36
36
|
const depthB = pathB.split("/").length;
|
|
@@ -48,15 +48,65 @@ export function fixNestedScopesResolution(importMap) {
|
|
|
48
48
|
});
|
|
49
49
|
return importMap;
|
|
50
50
|
}
|
|
51
|
-
export function
|
|
51
|
+
export function compressImportMap(importMap) {
|
|
52
|
+
const compressed = {
|
|
53
|
+
imports: { ...importMap.imports },
|
|
54
|
+
scopes: {}
|
|
55
|
+
};
|
|
56
|
+
const counts = {};
|
|
57
|
+
Object.values(importMap.scopes).forEach((scopeMappings) => {
|
|
58
|
+
Object.entries(scopeMappings).forEach(([specifier, target]) => {
|
|
59
|
+
if (Object.hasOwn(importMap.imports, specifier)) return;
|
|
60
|
+
counts[specifier] ??= {};
|
|
61
|
+
counts[specifier][target] = (counts[specifier][target] ?? 0) + 1;
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
Object.entries(counts).forEach(([specifier, targetCounts]) => {
|
|
65
|
+
const entries = Object.entries(targetCounts);
|
|
66
|
+
let best = null;
|
|
67
|
+
let secondBestCount = 0;
|
|
68
|
+
for (const [t, c] of entries) {
|
|
69
|
+
if (!best || c > best[1]) {
|
|
70
|
+
secondBestCount = best ? Math.max(secondBestCount, best[1]) : secondBestCount;
|
|
71
|
+
best = [t, c];
|
|
72
|
+
} else {
|
|
73
|
+
secondBestCount = Math.max(secondBestCount, c);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (best && best[1] > secondBestCount) {
|
|
77
|
+
compressed.imports[specifier] = best[0];
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
Object.entries(importMap.scopes).forEach(([scopePath, scopeMappings]) => {
|
|
81
|
+
const filtered = {};
|
|
82
|
+
Object.entries(scopeMappings).forEach(([specifier, target]) => {
|
|
83
|
+
const globalTarget = compressed.imports[specifier];
|
|
84
|
+
if (globalTarget === target) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
filtered[specifier] = target;
|
|
88
|
+
});
|
|
89
|
+
if (Object.keys(filtered).length > 0) {
|
|
90
|
+
compressed.scopes[scopePath] = filtered;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
const hasScopes = Object.keys(compressed.scopes).length > 0;
|
|
94
|
+
return hasScopes ? compressed : { imports: compressed.imports };
|
|
95
|
+
}
|
|
96
|
+
export function createImportMap({
|
|
52
97
|
manifests,
|
|
53
98
|
getFile,
|
|
54
99
|
getScope
|
|
55
100
|
}) {
|
|
56
|
-
const imports =
|
|
57
|
-
const scopes =
|
|
101
|
+
const imports = createImportsMap(manifests, getFile);
|
|
102
|
+
const scopes = createScopesMap(imports, manifests, getScope);
|
|
58
103
|
return {
|
|
59
104
|
imports,
|
|
60
105
|
scopes
|
|
61
106
|
};
|
|
62
107
|
}
|
|
108
|
+
export function createClientImportMap(options) {
|
|
109
|
+
const base = createImportMap(options);
|
|
110
|
+
const fixed = fixImportMapNestedScopes(base);
|
|
111
|
+
return compressImportMap(fixed);
|
|
112
|
+
}
|