@fluentui/react-icons-font-subsetting-webpack-plugin 2.0.320 → 2.0.322

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.
Files changed (2) hide show
  1. package/lib/index.js +51 -7
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -65,17 +65,13 @@ class FluentUIReactIconsFontSubsettingPlugin {
65
65
  const packageToUsedFontExports = new Map();
66
66
  for (const m of compilation.modules) {
67
67
  if (isFluentUIReactFontChunk(m)) {
68
- const usedModuleExports = compilation.moduleGraph.getUsedExports(m, undefined);
69
- // Either all exports are used or there's no info on used exports
70
- if (usedModuleExports === null || typeof usedModuleExports === 'boolean') {
71
- // In development mode (or when optimization.usedExports is disabled),
72
- // getUsedExports() returns `true` (all exports used) or `null` (no info).
73
- // Subsetting requires knowing exactly which exports are used.
68
+ const icons = resolveUsedIconExports(m, compilation.moduleGraph);
69
+ if (icons === null) {
74
70
  continue;
75
71
  }
76
72
  const pkgLibPath = (0, path_1.resolve)((0, path_1.dirname)(m.resource), '../..');
77
73
  const usedPkgExports = packageToUsedFontExports.get(pkgLibPath) ?? new Set();
78
- for (const icon of usedModuleExports) {
74
+ for (const icon of icons) {
79
75
  usedPkgExports.add(icon);
80
76
  }
81
77
  packageToUsedFontExports.set(pkgLibPath, usedPkgExports);
@@ -121,6 +117,54 @@ function getTargetFormat(assetName) {
121
117
  return 'sfnt';
122
118
  }
123
119
  }
120
+ /**
121
+ * Resolves the set of icon export names that are actually consumed from a font chunk module.
122
+ *
123
+ * Uses Webpack's `moduleGraph.getUsedExports()` which returns one of four shapes:
124
+ *
125
+ * | Return value | Meaning | Action |
126
+ * | --------------- | ------------------------------------------------------------------ | ------------------------------------------ |
127
+ * | `null` | `optimization.usedExports` is disabled — no usage info available | Skip (cannot determine which glyphs to keep)|
128
+ * | `false` | Module has zero consumers — nothing is imported from it | Skip (nothing to subset) |
129
+ * | `true` | All exports are consumed (e.g. `import * as ns from '...'`) | Fall back to `getProvidedExports()` ¹ |
130
+ * | `Set<string>` | Exact set of named exports that are consumed | Use directly for subsetting |
131
+ *
132
+ * ¹ When all exports are marked as used we can still subset: `getProvidedExports()` tells us
133
+ * which exports this specific module **declares** (not the entire font), so we subset the font
134
+ * to exactly the glyphs this module provides.
135
+ *
136
+ * This is **critical for atomic font imports** (e.g. `import * as XboxConsoleGroup from
137
+ * '@fluentui/react-icons/fonts/xbox-console'`) — each atomic module only provides a small icon
138
+ * group, so `getProvidedExports()` returns just those few icons, enabling proper subsetting even
139
+ * with namespace imports. Without this, namespace imports would skip subsetting entirely and ship
140
+ * the full unsubsetted font.
141
+ *
142
+ * Returns `null` when subsetting cannot be performed, so the caller can skip the module.
143
+ */
144
+ function resolveUsedIconExports(m, moduleGraph) {
145
+ const usedModuleExports = moduleGraph.getUsedExports(m, undefined);
146
+ if (usedModuleExports === null) {
147
+ // No info on used exports (optimization.usedExports is disabled) - subsetting requires knowing exactly which exports are used.
148
+ return null;
149
+ }
150
+ if (usedModuleExports === false) {
151
+ // No exports are used from this module - nothing to subset.
152
+ return null;
153
+ }
154
+ if (usedModuleExports === true) {
155
+ // All exports are used (e.g. `import * as ns from '...'` or similar namespace import).
156
+ // Retrieve statically-provided exports from the module graph so we can subset to exactly
157
+ // the glyphs this module declares (rather than the full font or nothing).
158
+ const providedExports = moduleGraph.getProvidedExports(m);
159
+ if (providedExports === null || providedExports === true) {
160
+ // Provided exports not statically known (optimization.providedExports disabled) - skip.
161
+ return null;
162
+ }
163
+ return providedExports;
164
+ }
165
+ // usedModuleExports is a Set<string> with the exact named exports that are used.
166
+ return Array.from(usedModuleExports);
167
+ }
124
168
  function isNormalModule(m) {
125
169
  return m instanceof webpack.NormalModule;
126
170
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluentui/react-icons-font-subsetting-webpack-plugin",
3
- "version": "2.0.320",
3
+ "version": "2.0.322",
4
4
  "description": "Webpack plugin to subset the icon fonts used by @fluentui/react-icons based on which icons are used.",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {