webpack-federation-stats-plugin 1.0.3-beta.0 → 1.1.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.
@@ -3,20 +3,19 @@ const PLUGIN_NAME = "FederationStatsPlugin"
3
3
  const EXTENSION_REGEX = /\.[^/.]+$/
4
4
 
5
5
  class FederationStatsPlugin {
6
- constructor(options = {fileName: "federation-stats.json"}) {
7
- if (!options.fileName) throw new Error("fileName option is required.")
8
- this._options = options
6
+ constructor(options = {}) {
7
+ this._options = {fileName: "federation-stats.json", ...options}
9
8
  }
10
9
 
11
10
  apply(compiler) {
12
- const federationPlugin = compiler.options.plugins.find((plugin) => plugin.constructor.name === "ModuleFederationPlugin")
11
+ const federationPlugin = compiler.options.plugins && compiler.options.plugins.find((plugin) => plugin.constructor.name === "ModuleFederationPlugin")
13
12
 
14
- if (!federationPlugin) {
15
- throw new Error("No ModuleFederationPlugin found.")
16
- }
13
+ if (!federationPlugin) throw new Error("No ModuleFederationPlugin found.")
17
14
 
18
15
  const appName = federationPlugin._options.name
19
- const exposedFiles = new Map(Object.entries(federationPlugin._options.exposes || {}).map(([k, v]) => [v, k]))
16
+
17
+ // get exposed modules from the ModuleFederationPlugin
18
+ const exposedFiles = new Map(Object.entries(federationPlugin._options.exposes || {}).map(([k, v]) => (typeof v === "object" ? [v.import, k] : [v, k])))
20
19
 
21
20
  compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
22
21
  compilation.hooks.processAssets.tapPromise(
@@ -25,51 +24,59 @@ class FederationStatsPlugin {
25
24
  stage: compilation.constructor.PROCESS_ASSETS_STAGE_REPORT,
26
25
  },
27
26
  async () => {
28
- const stats = compilation.getStats().toJson()
29
- const modules = stats.modules.filter((module) => {
30
- const moduleName = module.name.replace(EXTENSION_REGEX, "")
31
- return exposedFiles.has(moduleName)
32
- })
27
+ const stats = compilation.getStats().toJson({})
28
+ // find mf modules
29
+ const mfModules = stats.modules.filter((module) => module.issuerName === "container entry" && exposedFiles.has(module.name.replace(EXTENSION_REGEX, "")))
33
30
 
34
31
  const chunksReducer = (chunksArr, current) => {
35
32
  current.siblings.forEach((s) => {
36
33
  const chunk = stats.chunks.find((c) => c.id === s)
37
- if (chunk) {
38
- chunk.files.forEach((f) => chunksArr.push(f))
39
- }
34
+ chunk.files.forEach((f) => chunksArr.push(f))
40
35
  })
41
36
  current.files.forEach((f) => chunksArr.push(f))
42
37
  return chunksArr
43
38
  }
44
39
 
45
- const chunks = modules.reduce((acc, module) => {
46
- const moduleName = module.name.replace(EXTENSION_REGEX, "")
47
- let exposedAs = exposedFiles.get(moduleName)
48
- if (exposedAs.startsWith("./")) {
49
- exposedAs = exposedAs.substring(2)
50
- }
51
-
52
- const moduleChunks = module.chunks
40
+ const chunks = mfModules.map((module) => {
41
+ const exposedAs = exposedFiles.get(module.name.replace(EXTENSION_REGEX, ""))
42
+ const chunks = module.chunks
53
43
  .map((chunkId) => stats.chunks.find((chunk) => chunk.id === chunkId))
54
- .filter((chunk) => chunk && chunk.runtime.includes(appName))
44
+ .filter((chunk) => chunk.runtime.includes(appName))
55
45
  .reduce(chunksReducer, [])
46
+ return {
47
+ module: exposedAs,
48
+ chunks: chunks,
49
+ id: module.id,
50
+ }
51
+ })
56
52
 
57
- acc[exposedAs] = [...new Set(moduleChunks)]
58
- return acc
59
- }, {})
53
+ const exposes = chunks.reduce((result, current) => Object.assign(result, {[current.module.replace("./", "")]: current.chunks}), {})
54
+ const name = (federationPlugin._options.library && federationPlugin._options.library.name) || federationPlugin._options.name
60
55
 
61
56
  const statsResult = {
62
- name: appName,
63
- exposes: chunks,
64
- publicUrl: this._options.publicUrl || "",
57
+ name,
58
+ exposes,
59
+ }
60
+
61
+ const publicUrl = this._options.publicUrl
62
+ if (publicUrl) {
63
+ statsResult.publicUrl = publicUrl
65
64
  }
66
65
 
67
66
  const fileName = this._options.fileName
68
- compilation.emitAsset(fileName, {
69
- source: () => Buffer.from(JSON.stringify(statsResult, null, 2), "utf-8"),
70
- size: () => Buffer.byteLength(JSON.stringify(statsResult, null, 2)),
71
- })
72
- },
67
+ const statsBuffer = Buffer.from(JSON.stringify(statsResult), "utf-8")
68
+ const mfStats = {
69
+ source: () => statsBuffer,
70
+ size: () => statsBuffer.length,
71
+ }
72
+
73
+ const asset = compilation.getAsset(fileName)
74
+ if (asset) {
75
+ compilation.updateAsset(fileName, mfStats)
76
+ } else {
77
+ compilation.emitAsset(fileName, mfStats)
78
+ }
79
+ }
73
80
  )
74
81
  })
75
82
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webpack-federation-stats-plugin",
3
- "version": "1.0.3-beta.0",
3
+ "version": "1.1.0",
4
4
  "types": "index.d.ts",
5
5
  "description": "export module federation stats",
6
6
  "main": "FederationStatsPlugin.js",