@mf-toolkit/shared-inspector 0.1.1 → 0.3.0

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 CHANGED
@@ -5,7 +5,7 @@
5
5
  [![license](https://img.shields.io/badge/license-MIT-blue)](https://github.com/zvitaly7/mf-toolkit/blob/main/LICENSE)
6
6
  [![node](https://img.shields.io/badge/node-%E2%89%A518-339933?logo=node.js)](https://nodejs.org)
7
7
 
8
- > ⚠️ **Work in progress.** This package is fully tested (179 tests) and published to npm (`0.1.1`). The API is stable but may receive minor changes before the official stable release.
8
+ > ⚠️ **Work in progress.** This package is fully tested (252 tests) and published to npm. The API is stable but may receive minor changes before the official stable release.
9
9
 
10
10
  Build-time analyser for Module Federation `shared` dependencies. Two-phase architecture: **collect facts → analyse facts**.
11
11
 
@@ -78,6 +78,8 @@ const report = await inspect({
78
78
 
79
79
  ### Webpack plugin
80
80
 
81
+ `sharedConfig` is optional — the plugin auto-extracts it from `ModuleFederationPlugin` when not provided:
82
+
81
83
  ```typescript
82
84
  import { MfSharedInspectorPlugin } from '@mf-toolkit/shared-inspector/webpack';
83
85
 
@@ -88,20 +90,25 @@ module.exports = {
88
90
  shared: { react: { singleton: true }, mobx: { singleton: true } },
89
91
  }),
90
92
 
93
+ // sharedConfig not needed — auto-extracted from ModuleFederationPlugin above
91
94
  new MfSharedInspectorPlugin({
92
95
  sourceDirs: ['./src'],
93
- sharedConfig: {
94
- react: { singleton: true, requiredVersion: '^19.0.0' },
95
- mobx: { singleton: true },
96
- },
97
- tsconfigPath: './tsconfig.json', // resolve @alias/* imports
98
96
  warn: true,
99
- writeManifest: true, // writes project-manifest.json for CI
97
+ writeManifest: true, // writes project-manifest.json for CI aggregation
100
98
  }),
101
99
  ],
102
100
  };
103
101
  ```
104
102
 
103
+ Pass `sharedConfig` explicitly to override auto-extraction:
104
+
105
+ ```typescript
106
+ new MfSharedInspectorPlugin({
107
+ sourceDirs: ['./src'],
108
+ sharedConfig: { react: { singleton: true, requiredVersion: '^18.0.0' } },
109
+ })
110
+ ```
111
+
105
112
  ## Analysis depth
106
113
 
107
114
  | Depth | What it finds | Speed |
@@ -197,7 +204,32 @@ jobs:
197
204
  path: project-manifest.json
198
205
  ```
199
206
 
200
- `analyzeFederation()` (v0.2) will accept N manifests and detect cross-MF issues: ghost sharing, host gaps, version conflicts.
207
+ Each MF manifest can then be aggregated for cross-team analysis:
208
+
209
+ ```typescript
210
+ import { analyzeFederation, formatFederationReport } from '@mf-toolkit/shared-inspector';
211
+
212
+ const report = analyzeFederation([checkoutManifest, catalogManifest, cartManifest]);
213
+ console.log(formatFederationReport(report));
214
+ ```
215
+
216
+ ```
217
+ [MfSharedInspector] federation analysis (3 MFs)
218
+
219
+ Version conflicts (singleton negotiation will fail):
220
+ ⚠ react — checkout: ^17.0.0, catalog: ^18.0.0
221
+
222
+ Singleton mismatches (add singleton: true to all MFs):
223
+ ⚠ mobx — singleton in [checkout], not singleton in [catalog, cart]
224
+
225
+ Host gaps (add to shared — each MF bundles its own copy):
226
+ → axios — used by [checkout, catalog], not in shared
227
+
228
+ Ghost shares (remove from shared — no other MF benefits):
229
+ ✗ lodash — shared only by cart, unused by all other MFs
230
+
231
+ Total: 3 MFs, 1 version conflicts, 1 singleton mismatches, 1 host gaps, 1 ghost shares
232
+ ```
201
233
 
202
234
  ## API reference
203
235
 
@@ -224,8 +256,22 @@ jobs:
224
256
  | `additionalCandidates` | `string[]` | `[]` | Extend built-in candidates list |
225
257
  | `additionalSingletonRisks` | `string[]` | `[]` | Extend built-in singleton-risk list |
226
258
 
259
+ ### `analyzeFederation(manifests, options?)`
260
+
261
+ Accepts N `ProjectManifest` objects (one per microfrontend) and returns a `FederationReport`.
262
+
263
+ | Option | Type | Default | Description |
264
+ |--------|------|---------|-------------|
265
+ | `alwaysShared` | `string[]` | `['react','react-dom']` | Exclude from ghost/gap detection |
266
+
267
+ ### `formatFederationReport(report)`
268
+
269
+ Formats a `FederationReport` as a human-readable terminal string.
270
+
227
271
  ## Detection categories
228
272
 
273
+ ### Per-project (`analyzeProject`)
274
+
229
275
  | Category | Type | Description |
230
276
  |----------|------|-------------|
231
277
  | `mismatched` | Deterministic | `requiredVersion` doesn't satisfy installed version |
@@ -236,12 +282,20 @@ jobs:
236
282
 
237
283
  *Within the visibility of the chosen depth.*
238
284
 
285
+ ### Cross-MF (`analyzeFederation`)
286
+
287
+ | Category | Type | Description |
288
+ |----------|------|-------------|
289
+ | `versionConflicts` | Deterministic | `requiredVersion` ranges across MFs have no overlap |
290
+ | `singletonMismatches` | Deterministic | `singleton: true` in some MFs, absent in others |
291
+ | `hostGaps` | Heuristic | Package used by 2+ MFs but not declared in `shared` by anyone |
292
+ | `ghostShares` | Heuristic | Package in `shared` of one MF, unused/unshared by all others |
293
+
239
294
  ## Known limitations
240
295
 
241
296
  - **TypeScript path aliases without `tsconfigPath`**: aliased imports are treated as external package names. Pass `tsconfigPath` to resolve them correctly.
242
297
  - **Dynamic imports with variables** (`import(moduleName)`): not analysed — requires runtime information.
243
298
  - **Exact tsconfig alias patterns** (non-wildcard, e.g. `"@root": ["."]`): not supported, only `"@alias/*"` wildcard form.
244
- - **`analyzeFederation()`** (cross-MF analysis): v0.2.
245
299
 
246
300
  ## Demo
247
301
 
@@ -0,0 +1,9 @@
1
+ import type { ProjectManifest, FederationAnalysisOptions, FederationReport } from '../types.js';
2
+ /**
3
+ * Cross-MF analysis: accepts N project manifests and detects federation-level issues
4
+ * that are invisible when analysing each MF in isolation.
5
+ *
6
+ * Pure function — no I/O, no side effects.
7
+ */
8
+ export declare function analyzeFederation(manifests: ProjectManifest[], options?: FederationAnalysisOptions): FederationReport;
9
+ //# sourceMappingURL=analyze-federation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-federation.d.ts","sourceRoot":"","sources":["../../src/analyzer/analyze-federation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,yBAAyB,EACzB,gBAAgB,EAKjB,MAAM,aAAa,CAAC;AAmBrB;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,eAAe,EAAE,EAC5B,OAAO,CAAC,EAAE,yBAAyB,GAClC,gBAAgB,CAwJlB"}
@@ -0,0 +1,157 @@
1
+ import semver from 'semver';
2
+ const DEFAULT_ALWAYS_SHARED = ['react', 'react-dom'];
3
+ /**
4
+ * Returns true when two semver ranges have at least one version in common.
5
+ * Strategy: the max of the two minimums must satisfy both ranges.
6
+ * e.g. ^18.0.0 and ^18.2.0 → max(18.0.0, 18.2.0) = 18.2.0 → satisfies both → compatible.
7
+ * e.g. ^17.0.0 and ^18.0.0 → max(17.0.0, 18.0.0) = 18.0.0 → fails ^17 → conflict.
8
+ */
9
+ function rangesOverlap(a, b) {
10
+ if (!semver.validRange(a) || !semver.validRange(b))
11
+ return true; // unknown → assume ok
12
+ const minA = semver.minVersion(a);
13
+ const minB = semver.minVersion(b);
14
+ if (!minA || !minB)
15
+ return true;
16
+ const candidate = semver.gt(minA, minB) ? minA : minB;
17
+ return semver.satisfies(candidate, a) && semver.satisfies(candidate, b);
18
+ }
19
+ /**
20
+ * Cross-MF analysis: accepts N project manifests and detects federation-level issues
21
+ * that are invisible when analysing each MF in isolation.
22
+ *
23
+ * Pure function — no I/O, no side effects.
24
+ */
25
+ export function analyzeFederation(manifests, options) {
26
+ if (manifests.length === 0) {
27
+ return {
28
+ ghostShares: [], hostGaps: [], versionConflicts: [], singletonMismatches: [],
29
+ summary: { totalManifests: 0, ghostSharesCount: 0, hostGapsCount: 0, versionConflictsCount: 0, singletonMismatchesCount: 0 },
30
+ };
31
+ }
32
+ const alwaysShared = new Set(options?.alwaysShared ?? DEFAULT_ALWAYS_SHARED);
33
+ // ── Index manifests ────────────────────────────────────────────────────────
34
+ /** All packages declared in shared config per MF: pkg → Set<mfName> */
35
+ const sharedByPkg = new Map();
36
+ /** All packages observed in source per MF: pkg → Set<mfName> */
37
+ const usedByPkg = new Map();
38
+ /** requiredVersion per MF per pkg: pkg → Map<mfName, version> */
39
+ const versionsByPkg = new Map();
40
+ /**
41
+ * singleton flag per MF per pkg — only for MFs that explicitly set singleton.
42
+ * pkg → Map<mfName, boolean>
43
+ */
44
+ const explicitSingletonByPkg = new Map();
45
+ for (const manifest of manifests) {
46
+ const mfName = manifest.project.name;
47
+ for (const [pkg, cfg] of Object.entries(manifest.shared.declared)) {
48
+ if (!sharedByPkg.has(pkg))
49
+ sharedByPkg.set(pkg, new Set());
50
+ sharedByPkg.get(pkg).add(mfName);
51
+ if (cfg.requiredVersion) {
52
+ if (!versionsByPkg.has(pkg))
53
+ versionsByPkg.set(pkg, new Map());
54
+ versionsByPkg.get(pkg).set(mfName, cfg.requiredVersion);
55
+ }
56
+ if (cfg.singleton !== undefined) {
57
+ if (!explicitSingletonByPkg.has(pkg))
58
+ explicitSingletonByPkg.set(pkg, new Map());
59
+ explicitSingletonByPkg.get(pkg).set(mfName, cfg.singleton);
60
+ }
61
+ }
62
+ for (const pkg of manifest.usage.resolvedPackages) {
63
+ if (!usedByPkg.has(pkg))
64
+ usedByPkg.set(pkg, new Set());
65
+ usedByPkg.get(pkg).add(mfName);
66
+ }
67
+ }
68
+ // ── Ghost shares ───────────────────────────────────────────────────────────
69
+ // Package shared by exactly one MF with no other MF sharing or benefiting from it.
70
+ // Requires at least 2 manifests — with one MF there's nothing to compare.
71
+ const ghostShares = [];
72
+ if (manifests.length > 1) {
73
+ for (const [pkg, sharedByMfs] of sharedByPkg) {
74
+ if (alwaysShared.has(pkg))
75
+ continue;
76
+ if (sharedByMfs.size !== 1)
77
+ continue; // shared by multiple → not a ghost
78
+ const soloMf = [...sharedByMfs][0];
79
+ const usedByMfs = usedByPkg.get(pkg) ?? new Set();
80
+ // Other MFs that use the pkg but don't declare it in shared
81
+ const usedUnsharedBy = [...usedByMfs].filter((mf) => mf !== soloMf && !sharedByPkg.get(pkg)?.has(mf));
82
+ const otherMfsUseIt = [...usedByMfs].some((mf) => mf !== soloMf);
83
+ if (!otherMfsUseIt) {
84
+ // No other MF uses it at all — pure ghost share
85
+ ghostShares.push({ package: pkg, sharedBy: soloMf, usedUnsharedBy: [] });
86
+ }
87
+ else if (usedUnsharedBy.length > 0) {
88
+ // Other MFs use it but haven't declared it in shared
89
+ ghostShares.push({ package: pkg, sharedBy: soloMf, usedUnsharedBy });
90
+ }
91
+ }
92
+ }
93
+ // ── Host gaps ──────────────────────────────────────────────────────────────
94
+ // Package used by 2+ MFs but not declared in shared by anyone.
95
+ const hostGaps = [];
96
+ for (const [pkg, usedByMfs] of usedByPkg) {
97
+ if (usedByMfs.size < 2)
98
+ continue;
99
+ if (alwaysShared.has(pkg))
100
+ continue;
101
+ const sharedByMfs = sharedByPkg.get(pkg);
102
+ if (sharedByMfs && sharedByMfs.size > 0)
103
+ continue;
104
+ hostGaps.push({ package: pkg, missingIn: [...usedByMfs] });
105
+ }
106
+ // ── Version conflicts ──────────────────────────────────────────────────────
107
+ // Package where requiredVersion ranges across MFs have no overlap.
108
+ const versionConflicts = [];
109
+ for (const [pkg, mfVersions] of versionsByPkg) {
110
+ if (mfVersions.size < 2)
111
+ continue;
112
+ const ranges = [...mfVersions.values()];
113
+ const validRanges = ranges.filter((r) => semver.validRange(r));
114
+ if (validRanges.length < 2)
115
+ continue;
116
+ // Check all pairs of ranges for overlap — any non-overlapping pair is a conflict
117
+ let hasConflict = false;
118
+ outer: for (let i = 0; i < validRanges.length; i++) {
119
+ for (let j = i + 1; j < validRanges.length; j++) {
120
+ if (!rangesOverlap(validRanges[i], validRanges[j])) {
121
+ hasConflict = true;
122
+ break outer;
123
+ }
124
+ }
125
+ }
126
+ if (hasConflict) {
127
+ versionConflicts.push({ package: pkg, versions: Object.fromEntries(mfVersions) });
128
+ }
129
+ }
130
+ // ── Singleton mismatches ───────────────────────────────────────────────────
131
+ // Package where some MFs declare singleton: true and others don't (false or absent).
132
+ const singletonMismatches = [];
133
+ for (const [pkg, sharedByMfs] of sharedByPkg) {
134
+ if (sharedByMfs.size < 2)
135
+ continue;
136
+ const explicitMap = explicitSingletonByPkg.get(pkg) ?? new Map();
137
+ const singletonIn = [...sharedByMfs].filter((mf) => explicitMap.get(mf) === true);
138
+ const nonSingletonIn = [...sharedByMfs].filter((mf) => explicitMap.get(mf) !== true);
139
+ if (singletonIn.length > 0 && nonSingletonIn.length > 0) {
140
+ singletonMismatches.push({ package: pkg, singletonIn, nonSingletonIn });
141
+ }
142
+ }
143
+ return {
144
+ ghostShares,
145
+ hostGaps,
146
+ versionConflicts,
147
+ singletonMismatches,
148
+ summary: {
149
+ totalManifests: manifests.length,
150
+ ghostSharesCount: ghostShares.length,
151
+ hostGapsCount: hostGaps.length,
152
+ versionConflictsCount: versionConflicts.length,
153
+ singletonMismatchesCount: singletonMismatches.length,
154
+ },
155
+ };
156
+ }
157
+ //# sourceMappingURL=analyze-federation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze-federation.js","sourceRoot":"","sources":["../../src/analyzer/analyze-federation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { SharedDepConfig } from '../types.js';
2
+ /**
3
+ * Tries to extract the `shared` config from a ModuleFederationPlugin instance
4
+ * found in `compiler.options.plugins`.
5
+ *
6
+ * Returns `null` when:
7
+ * - No ModuleFederationPlugin is found
8
+ * - The plugin exists but has no `shared` option
9
+ * - The plugin uses an unknown internal storage format
10
+ *
11
+ * This intentionally uses `any` to remain independent of webpack/rspack types.
12
+ */
13
+ export declare function extractSharedFromCompiler(compiler: any): Record<string, SharedDepConfig> | null;
14
+ //# sourceMappingURL=extract-mfp-shared.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-mfp-shared.d.ts","sourceRoot":"","sources":["../../src/collector/extract-mfp-shared.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAWnD;;;;;;;;;;GAUG;AAEH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,IAAI,CAoB/F"}
@@ -0,0 +1,40 @@
1
+ import { parseSharedConfig } from './parse-shared-config.js';
2
+ /**
3
+ * Known constructor names for Module Federation plugins across bundlers.
4
+ * Checked by name to avoid a hard runtime dependency on webpack/rspack.
5
+ */
6
+ const MFP_CONSTRUCTOR_NAMES = new Set([
7
+ 'ModuleFederationPlugin', // webpack 5
8
+ 'ModuleFederationPluginV2', // some community forks
9
+ ]);
10
+ /**
11
+ * Tries to extract the `shared` config from a ModuleFederationPlugin instance
12
+ * found in `compiler.options.plugins`.
13
+ *
14
+ * Returns `null` when:
15
+ * - No ModuleFederationPlugin is found
16
+ * - The plugin exists but has no `shared` option
17
+ * - The plugin uses an unknown internal storage format
18
+ *
19
+ * This intentionally uses `any` to remain independent of webpack/rspack types.
20
+ */
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
+ export function extractSharedFromCompiler(compiler) {
23
+ const plugins = compiler?.options?.plugins;
24
+ if (!Array.isArray(plugins))
25
+ return null;
26
+ const mfPlugin = plugins.find(
27
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
+ (p) => p != null && MFP_CONSTRUCTOR_NAMES.has(p.constructor?.name));
29
+ if (!mfPlugin)
30
+ return null;
31
+ // webpack 5 stores options as `this._options` (private but stable across 5.x)
32
+ // Fall back to `this.options` used by some community variants
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ const raw = mfPlugin._options?.shared ?? mfPlugin.options?.shared;
35
+ if (raw == null)
36
+ return null;
37
+ const parsed = parseSharedConfig(raw);
38
+ return Object.keys(parsed).length > 0 ? parsed : null;
39
+ }
40
+ //# sourceMappingURL=extract-mfp-shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-mfp-shared.js","sourceRoot":"","sources":["../../src/collector/extract-mfp-shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG7D;;;GAGG;AACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,wBAAwB,EAAQ,YAAY;IAC5C,0BAA0B,EAAM,uBAAuB;CACxD,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,8DAA8D;AAC9D,MAAM,UAAU,yBAAyB,CAAC,QAAa;IACrD,MAAM,OAAO,GAAc,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC;IACtD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI;IAC3B,8DAA8D;IAC9D,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CACxE,CAAC;IAEF,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAE3B,8EAA8E;IAC9E,8DAA8D;IAC9D,8DAA8D;IAC9D,MAAM,GAAG,GAAI,QAAgB,CAAC,QAAQ,EAAE,MAAM,IAAK,QAAgB,CAAC,OAAO,EAAE,MAAM,CAAC;IAEpF,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAE7B,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACtC,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AACxD,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  export { buildProjectManifest } from './collector/build-project-manifest.js';
2
2
  export { analyzeProject } from './analyzer/analyze-project.js';
3
+ export { analyzeFederation } from './analyzer/analyze-federation.js';
3
4
  export { inspect } from './inspect.js';
4
5
  export { formatReport } from './reporter/format-report.js';
6
+ export { formatFederationReport } from './reporter/format-federation-report.js';
5
7
  export { writeReport, writeManifest } from './reporter/write-report.js';
6
- export type { ProjectManifest, ProjectReport, CollectorOptions, AnalysisOptions, SharedDepConfig, PackageOccurrence, UnusedEntry, CandidateEntry, MismatchedEntry, SingletonRiskEntry, } from './types.js';
8
+ export type { ProjectManifest, ProjectReport, CollectorOptions, AnalysisOptions, SharedDepConfig, PackageOccurrence, UnusedEntry, CandidateEntry, MismatchedEntry, SingletonRiskEntry, EagerRiskEntry, FederationAnalysisOptions, FederationReport, GhostShareEntry, HostGapEntry, VersionConflictEntry, SingletonMismatchEntry, } from './types.js';
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAG/D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAGxE,YAAY,EACV,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,eAAe,EACf,kBAAkB,GACnB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAGrE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAGxE,YAAY,EACV,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,yBAAyB,EACzB,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  // ─── Two-phase API ────────────────────────────────────────────────────────────
2
2
  export { buildProjectManifest } from './collector/build-project-manifest.js';
3
3
  export { analyzeProject } from './analyzer/analyze-project.js';
4
+ export { analyzeFederation } from './analyzer/analyze-federation.js';
4
5
  // ─── Shortcut API ─────────────────────────────────────────────────────────────
5
6
  export { inspect } from './inspect.js';
6
7
  // ─── Reporter ─────────────────────────────────────────────────────────────────
7
8
  export { formatReport } from './reporter/format-report.js';
9
+ export { formatFederationReport } from './reporter/format-federation-report.js';
8
10
  export { writeReport, writeManifest } from './reporter/write-report.js';
9
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,iFAAiF;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,iFAAiF;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAErE,iFAAiF;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,iFAAiF;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"webpack.d.ts","sourceRoot":"","sources":["../../src/plugins/webpack.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AASxD,UAAU,kBAAkB;IAC1B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,QAAQ,EAAE,KAAK,EAAE,CAAC;CACnB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,KAAK,EAAE;QACL,YAAY,EAAE;YACZ,UAAU,CACR,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,WAAW,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,GACrD,IAAI,CAAC;SACT,CAAC;KACH,CAAC;CACH;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,OAAO,CAAuB;gBAE1B,OAAO,EAAE,oBAAoB;IAIzC,KAAK,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;CAyFvC"}
1
+ {"version":3,"file":"webpack.d.ts","sourceRoot":"","sources":["../../src/plugins/webpack.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAUxD,UAAU,kBAAkB;IAC1B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,QAAQ,EAAE,KAAK,EAAE,CAAC;CACnB;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE;QACP,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,KAAK,EAAE;QACL,YAAY,EAAE;YACZ,UAAU,CACR,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,WAAW,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,GACrD,IAAI,CAAC;SACT,CAAC;KACH,CAAC;CACH;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,OAAO,CAAuB;gBAE1B,OAAO,EAAE,oBAAoB;IAIzC,KAAK,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;CA2GvC"}
@@ -3,6 +3,7 @@ import { buildProjectManifest } from '../collector/build-project-manifest.js';
3
3
  import { analyzeProject } from '../analyzer/analyze-project.js';
4
4
  import { formatReport } from '../reporter/format-report.js';
5
5
  import { writeManifest } from '../reporter/write-report.js';
6
+ import { extractSharedFromCompiler } from '../collector/extract-mfp-shared.js';
6
7
  // ─────────────────────────────────────────────────────────────────────────────
7
8
  const PLUGIN_NAME = 'MfSharedInspectorPlugin';
8
9
  /**
@@ -29,7 +30,7 @@ export class MfSharedInspectorPlugin {
29
30
  }
30
31
  apply(compiler) {
31
32
  compiler.hooks.afterCompile.tapPromise(PLUGIN_NAME, async (compilation) => {
32
- const { sourceDirs, depth = 'local-graph', sharedConfig, kind, packageJsonPath, extensions, ignore, parser, analysis, warn = true, failOn, writeManifest: shouldWriteManifest = false, outputDir = '.', } = this.options;
33
+ const { sourceDirs, depth = 'local-graph', sharedConfig: explicitSharedConfig, kind, packageJsonPath, extensions, ignore, tsconfigPath, workspacePackages, parser, analysis, warn = true, failOn, writeManifest: shouldWriteManifest = false, outputDir = '.', } = this.options;
33
34
  // Resolve name from webpack compiler, fallback to context dir name
34
35
  const name = compiler.options.name ?? basename(compiler.context);
35
36
  // Resolve paths relative to compiler.context when not absolute
@@ -41,6 +42,14 @@ export class MfSharedInspectorPlugin {
41
42
  ? outputDir
42
43
  : join(compiler.context, outputDir);
43
44
  try {
45
+ // Use explicit sharedConfig if provided, otherwise auto-extract from
46
+ // ModuleFederationPlugin found in compiler.options.plugins
47
+ const sharedConfig = explicitSharedConfig ?? extractSharedFromCompiler(compiler) ?? {};
48
+ const autoExtracted = !explicitSharedConfig && Object.keys(sharedConfig).length > 0;
49
+ if (autoExtracted && warn) {
50
+ console.log(`[${PLUGIN_NAME}] sharedConfig auto-extracted from ModuleFederationPlugin ` +
51
+ `(${Object.keys(sharedConfig).length} packages)`);
52
+ }
44
53
  const manifest = await buildProjectManifest({
45
54
  name,
46
55
  sourceDirs: resolvedSourceDirs,
@@ -50,13 +59,16 @@ export class MfSharedInspectorPlugin {
50
59
  packageJsonPath: resolvedPkgJson,
51
60
  extensions,
52
61
  ignore,
62
+ tsconfigPath,
63
+ workspacePackages,
53
64
  parser,
54
65
  });
55
66
  const report = analyzeProject(manifest, analysis);
56
67
  const hasFindings = report.mismatched.length > 0 ||
57
68
  report.unused.length > 0 ||
58
69
  report.candidates.length > 0 ||
59
- report.singletonRisks.length > 0;
70
+ report.singletonRisks.length > 0 ||
71
+ report.eagerRisks.length > 0;
60
72
  if (warn && hasFindings) {
61
73
  console.warn(formatReport(report, {
62
74
  name: manifest.project.name,
@@ -89,7 +101,8 @@ function shouldFailBuild(failOn, report) {
89
101
  case 'any': return (report.mismatched.length > 0 ||
90
102
  report.unused.length > 0 ||
91
103
  report.candidates.length > 0 ||
92
- report.singletonRisks.length > 0);
104
+ report.singletonRisks.length > 0 ||
105
+ report.eagerRisks.length > 0);
93
106
  }
94
107
  }
95
108
  //# sourceMappingURL=webpack.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"webpack.js","sourceRoot":"","sources":["../../src/plugins/webpack.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webpack.js","sourceRoot":"","sources":["../../src/plugins/webpack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAyB/E,gFAAgF;AAEhF,MAAM,WAAW,GAAG,yBAAyB,CAAC;AAE9C;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,uBAAuB;IAC1B,OAAO,CAAuB;IAEtC,YAAY,OAA6B;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,QAAyB;QAC7B,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,CACpC,WAAW,EACX,KAAK,EAAE,WAA+B,EAAE,EAAE;YACxC,MAAM,EACJ,UAAU,EACV,KAAK,GAAG,aAAa,EACrB,YAAY,EAAE,oBAAoB,EAClC,IAAI,EACJ,eAAe,EACf,UAAU,EACV,MAAM,EACN,YAAY,EACZ,iBAAiB,EACjB,MAAM,EACN,QAAQ,EACR,IAAI,GAAG,IAAI,EACX,MAAM,EACN,aAAa,EAAE,mBAAmB,GAAG,KAAK,EAC1C,SAAS,GAAG,GAAG,GAChB,GAAG,IAAI,CAAC,OAAO,CAAC;YAEjB,mEAAmE;YACnE,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAEjE,+DAA+D;YAC/D,MAAM,eAAe,GAAG,eAAe;gBACrC,CAAC,CAAC,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;gBAC3F,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;YAE3C,MAAM,kBAAkB,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAChD,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CACpD,CAAC;YAEF,MAAM,iBAAiB,GAAG,UAAU,CAAC,SAAS,CAAC;gBAC7C,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAEtC,IAAI,CAAC;gBACH,qEAAqE;gBACrE,2DAA2D;gBAC3D,MAAM,YAAY,GAChB,oBAAoB,IAAI,yBAAyB,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAEpE,MAAM,aAAa,GAAG,CAAC,oBAAoB,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;gBACpF,IAAI,aAAa,IAAI,IAAI,EAAE,CAAC;oBAC1B,OAAO,CAAC,GAAG,CACT,IAAI,WAAW,4DAA4D;wBAC3E,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,YAAY,CACjD,CAAC;gBACJ,CAAC;gBAED,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC;oBAC1C,IAAI;oBACJ,UAAU,EAAE,kBAAkB;oBAC9B,KAAK;oBACL,YAAY;oBACZ,IAAI;oBACJ,eAAe,EAAE,eAAe;oBAChC,UAAU;oBACV,MAAM;oBACN,YAAY;oBACZ,iBAAiB;oBACjB,MAAM;iBACP,CAAC,CAAC;gBAEH,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBAElD,MAAM,WAAW,GACf,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;oBAC5B,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;oBACxB,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;oBAC5B,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;oBAChC,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;gBAE/B,IAAI,IAAI,IAAI,WAAW,EAAE,CAAC;oBACxB,OAAO,CAAC,IAAI,CACV,YAAY,CAAC,MAAM,EAAE;wBACnB,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI;wBAC3B,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK;wBAC5B,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY;qBAC3C,CAAC,CACH,CAAC;gBACJ,CAAC;gBAED,IAAI,mBAAmB,EAAE,CAAC;oBACxB,MAAM,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,iBAAiB,EAAE,uBAAuB,CAAC,CAAC,CAAC;gBAClF,CAAC;gBAED,IAAI,MAAM,IAAI,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;oBAC9C,MAAM,GAAG,GACP,IAAI,WAAW,4BAA4B,MAAM,MAAM;wBACvD,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,cAAc,MAAM,CAAC,MAAM,CAAC,MAAM,WAAW;wBACxE,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,gBAAgB,MAAM,CAAC,cAAc,CAAC,MAAM,mBAAmB,CAAC;oBAC7F,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC1C,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,iEAAiE;gBACjE,WAAW,CAAC,QAAQ,CAAC,IAAI,CACvB,IAAI,KAAK,CACP,IAAI,WAAW,sBAAsB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACxF,CACF,CAAC;YACJ,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;CACF;AAED,iFAAiF;AAEjF,SAAS,eAAe,CACtB,MAAqC,EACrC,MAA6H;IAE7H,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,UAAU,CAAC,CAAC,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;QACrD,KAAK,QAAQ,CAAC,CAAG,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QACjD,KAAK,KAAK,CAAC,CAAM,OAAO,CACtB,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;YAC5B,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;YACxB,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;YAC5B,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;YAChC,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAC7B,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { FederationReport } from '../types.js';
2
+ /**
3
+ * Formats a FederationReport as a human-readable terminal string.
4
+ *
5
+ * Section order (by severity):
6
+ * 1. Version conflicts — deterministic, most dangerous (silent broken singleton)
7
+ * 2. Singleton mismatches — deterministic, runtime risk
8
+ * 3. Host gaps — heuristic, bundle duplication
9
+ * 4. Ghost shares — heuristic, dead coupling
10
+ * 5. Summary line
11
+ */
12
+ export declare function formatFederationReport(report: FederationReport): string;
13
+ //# sourceMappingURL=format-federation-report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-federation-report.d.ts","sourceRoot":"","sources":["../../src/reporter/format-federation-report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAgFvE"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Formats a FederationReport as a human-readable terminal string.
3
+ *
4
+ * Section order (by severity):
5
+ * 1. Version conflicts — deterministic, most dangerous (silent broken singleton)
6
+ * 2. Singleton mismatches — deterministic, runtime risk
7
+ * 3. Host gaps — heuristic, bundle duplication
8
+ * 4. Ghost shares — heuristic, dead coupling
9
+ * 5. Summary line
10
+ */
11
+ export function formatFederationReport(report) {
12
+ const lines = [];
13
+ const { ghostShares, hostGaps, versionConflicts, singletonMismatches, summary } = report;
14
+ // ── Header ─────────────────────────────────────────────────────────────────
15
+ lines.push('', `[MfSharedInspector] federation analysis (${summary.totalManifests} MFs)`, '');
16
+ const hasFindings = versionConflicts.length > 0 ||
17
+ singletonMismatches.length > 0 ||
18
+ hostGaps.length > 0 ||
19
+ ghostShares.length > 0;
20
+ if (!hasFindings) {
21
+ lines.push(' No federation-level issues found.');
22
+ lines.push('');
23
+ lines.push(` Total: ${summary.totalManifests} MFs analysed, everything looks consistent.`);
24
+ lines.push('');
25
+ return lines.join('\n');
26
+ }
27
+ // ── 1. Version conflicts ───────────────────────────────────────────────────
28
+ if (versionConflicts.length > 0) {
29
+ lines.push(' Version conflicts (singleton negotiation will fail):');
30
+ for (const c of versionConflicts) {
31
+ const versions = Object.entries(c.versions)
32
+ .map(([mf, v]) => `${mf}: ${v}`)
33
+ .join(', ');
34
+ lines.push(` ⚠ ${c.package} — ${versions}`);
35
+ }
36
+ lines.push('');
37
+ }
38
+ // ── 2. Singleton mismatches ────────────────────────────────────────────────
39
+ if (singletonMismatches.length > 0) {
40
+ lines.push(' Singleton mismatches (add singleton: true to all MFs):');
41
+ for (const s of singletonMismatches) {
42
+ lines.push(` ⚠ ${s.package} — singleton in [${s.singletonIn.join(', ')}], not singleton in [${s.nonSingletonIn.join(', ')}]`);
43
+ }
44
+ lines.push('');
45
+ }
46
+ // ── 3. Host gaps ───────────────────────────────────────────────────────────
47
+ if (hostGaps.length > 0) {
48
+ lines.push(' Host gaps (add to shared — each MF bundles its own copy):');
49
+ for (const g of hostGaps) {
50
+ lines.push(` → ${g.package} — used by [${g.missingIn.join(', ')}], not in shared`);
51
+ }
52
+ lines.push('');
53
+ }
54
+ // ── 4. Ghost shares ────────────────────────────────────────────────────────
55
+ if (ghostShares.length > 0) {
56
+ lines.push(' Ghost shares (remove from shared — no other MF benefits):');
57
+ for (const g of ghostShares) {
58
+ if (g.usedUnsharedBy.length > 0) {
59
+ lines.push(` ✗ ${g.package} — shared only by ${g.sharedBy}, ` +
60
+ `used unshared by [${g.usedUnsharedBy.join(', ')}]`);
61
+ }
62
+ else {
63
+ lines.push(` ✗ ${g.package} — shared only by ${g.sharedBy}, unused by all other MFs`);
64
+ }
65
+ }
66
+ lines.push('');
67
+ }
68
+ // ── 5. Summary ─────────────────────────────────────────────────────────────
69
+ lines.push(` Total: ${summary.totalManifests} MFs, ` +
70
+ `${summary.versionConflictsCount} version conflicts, ` +
71
+ `${summary.singletonMismatchesCount} singleton mismatches, ` +
72
+ `${summary.hostGapsCount} host gaps, ` +
73
+ `${summary.ghostSharesCount} ghost shares`);
74
+ lines.push('');
75
+ return lines.join('\n');
76
+ }
77
+ //# sourceMappingURL=format-federation-report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-federation-report.js","sourceRoot":"","sources":["../../src/reporter/format-federation-report.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -164,6 +164,83 @@ export interface ProjectReport {
164
164
  eagerRisksCount: number;
165
165
  };
166
166
  }
167
+ export interface FederationAnalysisOptions {
168
+ /**
169
+ * Packages that are always expected to be shared across all MFs.
170
+ * Used to strengthen ghost-sharing detection.
171
+ * @default ['react', 'react-dom']
172
+ */
173
+ alwaysShared?: string[];
174
+ }
175
+ /**
176
+ * Package shared by one MF but absent from shared config in all other MFs.
177
+ * Creates one-sided coupling with no federation benefit.
178
+ */
179
+ export interface GhostShareEntry {
180
+ package: string;
181
+ /** MF that declares this package in shared config */
182
+ sharedBy: string;
183
+ /** MFs that also use the package but don't declare it in shared */
184
+ usedUnsharedBy: string[];
185
+ }
186
+ /**
187
+ * Package used by one or more remotes but not declared in shared by any MF.
188
+ * Each MF bundles its own copy — potential duplication.
189
+ */
190
+ export interface HostGapEntry {
191
+ package: string;
192
+ /** MFs that use the package without any shared declaration */
193
+ missingIn: string[];
194
+ }
195
+ /**
196
+ * Package where different MFs declare incompatible requiredVersion ranges.
197
+ * Module Federation singleton resolution will fail silently.
198
+ */
199
+ export interface VersionConflictEntry {
200
+ package: string;
201
+ /** Map of MF name → requiredVersion declared in that MF's shared config */
202
+ versions: Record<string, string>;
203
+ }
204
+ /**
205
+ * Package where some MFs declare singleton: true and others don't.
206
+ * Inconsistent singleton flags cause unpredictable MF negotiation.
207
+ */
208
+ export interface SingletonMismatchEntry {
209
+ package: string;
210
+ /** MFs that declare singleton: true */
211
+ singletonIn: string[];
212
+ /** MFs that declare the package in shared but without singleton: true */
213
+ nonSingletonIn: string[];
214
+ }
215
+ export interface FederationReport {
216
+ /**
217
+ * Packages in shared config of one MF that no other MF shares or uses.
218
+ * Safe to remove from shared — only creates artificial coupling.
219
+ */
220
+ ghostShares: GhostShareEntry[];
221
+ /**
222
+ * Packages used across MFs but not declared in shared by anyone.
223
+ * Each MF pays the full bundle cost independently.
224
+ */
225
+ hostGaps: HostGapEntry[];
226
+ /**
227
+ * Packages with conflicting requiredVersion across MFs.
228
+ * MF singleton negotiation will pick one version and silently break others.
229
+ */
230
+ versionConflicts: VersionConflictEntry[];
231
+ /**
232
+ * Packages where singleton flag is inconsistent across MFs.
233
+ * Risk of duplicate instances in production.
234
+ */
235
+ singletonMismatches: SingletonMismatchEntry[];
236
+ summary: {
237
+ totalManifests: number;
238
+ ghostSharesCount: number;
239
+ hostGapsCount: number;
240
+ versionConflictsCount: number;
241
+ singletonMismatchesCount: number;
242
+ };
243
+ }
167
244
  export interface WebpackPluginOptions extends Omit<CollectorOptions, 'name'> {
168
245
  /** Policy options for the analyzer */
169
246
  analysis?: AnalysisOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mf-toolkit/shared-inspector",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "Build-time shared dependency analyzer for Module Federation.",
5
5
  "author": "Vitaly Zheltko",
6
6
  "license": "MIT",