Thanks to visit codestin.com
Credit goes to github.com

Skip to content

NX rspack executor shows 0 bytes in stats when i18n localization is enabled #32277

@m4riok

Description

@m4riok

Current Behavior

Build statistics show 0 bytes for all files:

└──( nx build testapp

> nx run testapp:build

> rspack build --node-env=production

✔ Browser application bundle generation complete.

Initial chunk files | Names         | Raw size
                    | styles        |  0 bytes |
                    | polyfills     |  0 bytes |
                    | runtime       |  0 bytes |
                    | main          |  0 bytes |

                    | Initial total |  0 bytes

Build at: 2025-08-09T15:50:45.900Z - Hash: fb52a48b5c6c4606 - Time: 6478ms

Expected Behavior

Build statistics should show actual file sizes, similar to how Angular's esbuild integration works:

Initial chunk files | Names      | Raw size
main.js            | main       | 1.36 MB
polyfills.js       | polyfills  | 125 bytes
runtime.js         | runtime    | 2.5 KB
styles.css         | styles     | 1.2 KB

                   | Initial total | 1.39 MB

GitHub Repo

No response

Steps to Reproduce

  1. Create an Angular application in NX workspace with rspack
  2. Configure i18n with multiple locales in project.json:
    "i18n": {
      "sourceLocale": "en-US",
      "locales": {
        "el": {
          "translation": "apps/testapp/src/locale/messages.el.xlf"
        }
      }
    }
  3. Configure rspack with localization in rspack.config.ts:
    export default createConfig({
      // ... other config
    }, {
      production: {
        options: {
          localize: true,
          // ... other options
        }
      }
    });
  4. Run nx build testapp

Nx Report

NX   Report complete - copy this into the issue template

Node           : 22.16.0
OS             : linux-x64
Native Target  : x86_64-linux
npm            : 11.5.2

nx (global)            : 21.3.10
nx                     : 21.3.11
@nx/js                 : 21.3.11
@nx/jest               : 21.3.11
@nx/eslint             : 21.3.11
@nx/workspace          : 21.3.11
@nx/angular            : 21.3.11
@nx/devkit             : 21.3.11
@nx/eslint-plugin      : 21.3.11
@nx/module-federation  : 21.3.11
@nx/playwright         : 21.3.11
@nx/rspack             : 21.3.11
@nx/web                : 21.3.11
@nx/webpack            : 21.3.11
typescript             : 5.8.3
---------------------------------------
Registered Plugins:
@nx/angular/plugin
@nx/eslint/plugin
@nx/jest/plugin
@nx/playwright/plugin
@nx/rspack/plugin
---------------------------------------
Community plugins:
angular-eslint        : 20.1.1
---------------------------------------
Cache Usage: 567.72 KB / 100.69 GB

Failure Logs

Package Manager Version

No response

Operating System

  • macOS
  • Linux
  • Windows
  • Other (Please specify)

Additional Information

  • The build itself works perfectly - files are generated in the correct locale subdirectories
  • This only affects the console output statistics, not the actual build artifacts
  • The issue is specific to multi-locale i18n builds; single locale builds may not be affected

Root Cause

In i18n builds, assets have locale prefixes (e.g., el/main.js) but chunk.files arrays are empty. The original filtering logic chunk.files?.includes(asset.name) always returns false, causing no assets to be matched to chunks for size calculation.

Solution

Enhanced asset matching logic in the stats reporting that:

  1. First tries exact match with chunk.files (preserves existing behavior)
  2. Normalizes asset names by removing locale prefixes and hashes
  3. Falls back to matching by chunk.names when chunk.files is empty (i18n builds)

Diff

diff --git a/packages/angular-rspack/src/lib/utils/stats.js b/packages/angular-rspack/src/lib/utils/stats.js
index abc123..def456 100644
--- a/packages/angular-rspack/src/lib/utils/stats.js
+++ b/packages/angular-rspack/src/lib/utils/stats.js
@@ -86,7 +86,21 @@ function statsToString(stats, json, statsConfig, budgetFailures) {
         if (!isFirstRun && !chunk.rendered) {
             continue;
         }
-        const assets = json.assets?.filter((asset) => chunk.files?.includes(asset.name));
+        const assets = json.assets?.filter((asset) => {
+            // First try exact match with files array
+            if (chunk.files?.includes(asset.name)) return true;
+            
+            // For i18n builds, normalize asset name by removing locale prefix and hash
+            let normalizedAssetName = asset.name.replace(/^[a-z]{2}(-[A-Z]{2})?\//, '');
+            // Remove hash from filename (e.g., main.abc123.js -> main.js)
+            normalizedAssetName = normalizedAssetName.replace(/\.[a-f0-9]{8}(\.[^.]+)$/, '$1');
+            
+            // Try matching with files array
+            if (chunk.files?.includes(normalizedAssetName)) return true;
+            
+            // If files is empty, try matching by chunk names - for i18n builds
+            if (!chunk.files?.length && chunk.names?.length) {
+                const baseFileName = normalizedAssetName.replace(/\.[^.]+$/, ''); // Remove extension
+                return chunk.names.includes(baseFileName);
+            }
+            
+            return false;
+        });
         let rawSize = 0;
         let estimatedTransferSize;
         if (assets) {

File Location

/node_modules/@nx/angular-rspack/dist/lib/utils/stats.js (around line 89)

Result

After applying this fix, build stats correctly show file sizes:

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions