@mf-toolkit/shared-inspector 0.2.0 → 0.3.1
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 +31 -8
- package/dist/collector/extract-mfp-shared.d.ts +14 -0
- package/dist/collector/extract-mfp-shared.d.ts.map +1 -0
- package/dist/collector/extract-mfp-shared.js +40 -0
- package/dist/collector/extract-mfp-shared.js.map +1 -0
- package/dist/plugins/webpack.d.ts.map +1 -1
- package/dist/plugins/webpack.js +10 -1
- package/dist/plugins/webpack.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
# `@mf-toolkit/shared-inspector`
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@mf-toolkit/shared-inspector)
|
|
4
|
-
[](https://github.com/zvitaly7/mf-toolkit)
|
|
5
4
|
[](https://github.com/zvitaly7/mf-toolkit/blob/main/LICENSE)
|
|
6
5
|
[](https://nodejs.org)
|
|
7
6
|
|
|
8
|
-
>
|
|
7
|
+
> **v0.3.0** — published to npm. 252 tests. API is stable; minor changes possible before v1.0.
|
|
9
8
|
|
|
10
9
|
Build-time analyser for Module Federation `shared` dependencies. Two-phase architecture: **collect facts → analyse facts**.
|
|
11
10
|
|
|
@@ -78,6 +77,8 @@ const report = await inspect({
|
|
|
78
77
|
|
|
79
78
|
### Webpack plugin
|
|
80
79
|
|
|
80
|
+
`sharedConfig` is optional — the plugin auto-extracts it from `ModuleFederationPlugin` when not provided:
|
|
81
|
+
|
|
81
82
|
```typescript
|
|
82
83
|
import { MfSharedInspectorPlugin } from '@mf-toolkit/shared-inspector/webpack';
|
|
83
84
|
|
|
@@ -88,20 +89,25 @@ module.exports = {
|
|
|
88
89
|
shared: { react: { singleton: true }, mobx: { singleton: true } },
|
|
89
90
|
}),
|
|
90
91
|
|
|
92
|
+
// sharedConfig not needed — auto-extracted from ModuleFederationPlugin above
|
|
91
93
|
new MfSharedInspectorPlugin({
|
|
92
94
|
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
95
|
warn: true,
|
|
99
|
-
writeManifest: true,
|
|
96
|
+
writeManifest: true, // writes project-manifest.json for CI aggregation
|
|
100
97
|
}),
|
|
101
98
|
],
|
|
102
99
|
};
|
|
103
100
|
```
|
|
104
101
|
|
|
102
|
+
Pass `sharedConfig` explicitly to override auto-extraction:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
new MfSharedInspectorPlugin({
|
|
106
|
+
sourceDirs: ['./src'],
|
|
107
|
+
sharedConfig: { react: { singleton: true, requiredVersion: '^18.0.0' } },
|
|
108
|
+
})
|
|
109
|
+
```
|
|
110
|
+
|
|
105
111
|
## Analysis depth
|
|
106
112
|
|
|
107
113
|
| Depth | What it finds | Speed |
|
|
@@ -261,6 +267,22 @@ Accepts N `ProjectManifest` objects (one per microfrontend) and returns a `Feder
|
|
|
261
267
|
|
|
262
268
|
Formats a `FederationReport` as a human-readable terminal string.
|
|
263
269
|
|
|
270
|
+
### `MfSharedInspectorPlugin` options
|
|
271
|
+
|
|
272
|
+
Extends all `buildProjectManifest` options (except `name`, auto-resolved from compiler) plus:
|
|
273
|
+
|
|
274
|
+
| Option | Type | Default | Description |
|
|
275
|
+
|--------|------|---------|-------------|
|
|
276
|
+
| `sourceDirs` | `string[]` | — | Directories to scan |
|
|
277
|
+
| `sharedConfig` | `Record<string, SharedDepConfig>` | auto-extracted | Override auto-extraction from `ModuleFederationPlugin` |
|
|
278
|
+
| `tsconfigPath` | `string` | `undefined` | tsconfig.json for path alias resolution |
|
|
279
|
+
| `workspacePackages` | `string[]` | `[]` | Local monorepo packages to exclude |
|
|
280
|
+
| `warn` | `boolean` | `true` | Print findings to console |
|
|
281
|
+
| `failOn` | `'mismatch' \| 'unused' \| 'any'` | `undefined` | Fail the build when findings match |
|
|
282
|
+
| `writeManifest` | `boolean` | `false` | Write `project-manifest.json` to `outputDir` |
|
|
283
|
+
| `outputDir` | `string` | `'.'` | Directory for manifest output |
|
|
284
|
+
| `analysis` | `AnalysisOptions` | `{}` | Options forwarded to `analyzeProject` |
|
|
285
|
+
|
|
264
286
|
## Detection categories
|
|
265
287
|
|
|
266
288
|
### Per-project (`analyzeProject`)
|
|
@@ -289,6 +311,7 @@ Formats a `FederationReport` as a human-readable terminal string.
|
|
|
289
311
|
- **TypeScript path aliases without `tsconfigPath`**: aliased imports are treated as external package names. Pass `tsconfigPath` to resolve them correctly.
|
|
290
312
|
- **Dynamic imports with variables** (`import(moduleName)`): not analysed — requires runtime information.
|
|
291
313
|
- **Exact tsconfig alias patterns** (non-wildcard, e.g. `"@root": ["."]`): not supported, only `"@alias/*"` wildcard form.
|
|
314
|
+
- **Subclassed `ModuleFederationPlugin`**: auto-extraction matches by constructor name. A custom subclass (`class MyMFP extends ModuleFederationPlugin`) won't be detected — pass `sharedConfig` explicitly in that case.
|
|
292
315
|
|
|
293
316
|
## Demo
|
|
294
317
|
|
|
@@ -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"}
|
|
@@ -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;
|
|
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"}
|
package/dist/plugins/webpack.js
CHANGED
|
@@ -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, tsconfigPath, workspacePackages, 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,
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
1
|
+
{"version":3,"file":"webpack.js","sourceRoot":"","sources":["../../src/plugins/webpack.ts"],"names":[],"mappings":"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"}
|