Skip to content

"Identifier 'ngServerMode' has already been declared" when prerender is true #795

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
1 of 2 tasks
hal1984 opened this issue Mar 15, 2025 · 5 comments
Open
1 of 2 tasks

Comments

@hal1984
Copy link

hal1984 commented Mar 15, 2025

With what library do you have an issue?

native-federation

Reproduction of the bug/regression with instructions

https://github.com/hal1984/native-federation-19/tree/ngServerMode

  1. Clone repo
  2. npm install
  3. npm run build:mfe1 or npm run build:shell

The build crash with the following output:

npm run build:mfe1

> [email protected] build:mfe1
> ng build mfe1

 INFO  Building federation artefacts
Browser bundles      
Initial chunk files   | Names            |  Raw size | Estimated transfer size
polyfills-7JMRL5KN.js | polyfills        |  72.02 kB |                23.27 kB
main-ECDM4YT5.js      | main             |   2.50 kB |                 1.01 kB
chunk-2VMXMS7J.js     | -                | 661 bytes |               661 bytes
styles-5INURTSO.css   | styles           |   0 bytes |                 0 bytes

                      | Initial total    |  75.18 kB |                24.95 kB

Lazy chunk files      | Names            |  Raw size | Estimated transfer size
chunk-ETZQPVKB.js     | bootstrap        | 955 bytes |               955 bytes


Server bundles       
Initial chunk files   | Names            |  Raw size
polyfills.server.mjs  | polyfills.server |  31.05 kB |                        
server.mjs            | server           |  16.20 kB |                        
chunk-2XAXBCZJ.mjs    | -                |   1.44 kB |                        
chunk-3QHYWY55.mjs    | -                |   1.31 kB |                        
main.server.mjs       | main.server      | 603 bytes |                        

Lazy chunk files      | Names            |  Raw size
chunk-MWNT6HXB.mjs    | bootstrap-server | 877.14 kB |                        

Prerendered 0 static routes.
Application bundle generation failed. [1.731 seconds]

✘ [ERROR] An error occurred while extracting routes.

SyntaxError: Identifier 'ngServerMode' has already been declared
    at compileSourceTextModule (node:internal/modules/esm/utils:338:16)
    at ModuleLoader.moduleStrategy (node:internal/modules/esm/translators:102:18)
    at #translate (node:internal/modules/esm/loader:468:12)
    at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:515:27)


An unhandled exception occurred: server is not started
See "/private/var/folders/67/hnw5gdhs6_x2j21kn2h8kll40000gn/T/ng-0ZBphv/angular-errors.log" for further details.
npm run build:shell 

> [email protected] build:shell
> ng build shell

 INFO  Building federation artefacts
Browser bundles      
Initial chunk files   | Names            |  Raw size | Estimated transfer size
polyfills-7JMRL5KN.js | polyfills        |  72.02 kB |                23.27 kB
chunk-OBBLAJGF.js     | -                |   4.31 kB |                 1.58 kB
main-FMDHO5MO.js      | main             | 164 bytes |               164 bytes
styles-5INURTSO.css   | styles           |   0 bytes |                 0 bytes

                      | Initial total    |  76.49 kB |                25.02 kB

Lazy chunk files      | Names            |  Raw size | Estimated transfer size
chunk-FTDKJ2JJ.js     | bootstrap        |   1.40 kB |               546 bytes


Server bundles       
Initial chunk files   | Names            |  Raw size
polyfills.server.mjs  | polyfills.server |  31.05 kB |                        
server.mjs            | server           |  14.40 kB |                        
chunk-YV667WEZ.mjs    | -                |   4.82 kB |                        
chunk-TSZOCMSY.mjs    | -                |   1.83 kB |                        
main.server.mjs       | main.server      | 603 bytes |                        

Lazy chunk files      | Names            |  Raw size
chunk-XSQPPJAP.mjs    | bootstrap-server | 877.14 kB |                        

Prerendered 0 static routes.
Application bundle generation failed. [1.820 seconds]

✘ [ERROR] An error occurred while extracting routes.

SyntaxError: Identifier 'ngServerMode' has already been declared
    at compileSourceTextModule (node:internal/modules/esm/utils:338:16)
    at ModuleLoader.moduleStrategy (node:internal/modules/esm/translators:102:18)
    at #translate (node:internal/modules/esm/loader:468:12)
    at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:515:27)


An unhandled exception occurred: server is not started
See "/private/var/folders/67/hnw5gdhs6_x2j21kn2h8kll40000gn/T/ng-o223tB/angular-errors.log" for further details.

Expected behavior

Build succeeds

Versions of Native/Module Federation, Angular, Node, Browser, and operating system

Native Federation: 19.0.16
Angular: 19.2.2
Node: 22.14.0
Browser: Chrome
Operating systems: macOS Sequoia

Other information

For MFE1 the new Server Routing have been used.
https://angular.dev/guide/hybrid-rendering.

For shell the default SSR with "prerender": "true" have been used. Both appear to fail with the same error.

I would be willing to submit a PR to fix this issue

  • Yes
  • No
@hal1984
Copy link
Author

hal1984 commented Mar 15, 2025

I managed to fix the issue for the default SSR with prerender: true changing in the following file:

https://github.com/angular-architects/module-federation-plugin/blob/main/libs/native-federation/src/utils/angular-esbuild-adapter.ts

the method function setNgServerMode() to:


function setNgServerMode() {
  const fileToPatch = 'node_modules/@angular/core/fesm2022/core.mjs';
  const lineToAdd = `var ngServerMode = (typeof window === 'undefined') ? true : false;`;
  try {
      if (fs.existsSync(fileToPatch)) {
          let content = fs.readFileSync(fileToPatch, 'utf-8');
          // Check if const ngServerMode exists and replace it
          if (content.includes('const ngServerMode')) {
              content = content.replace(/const ngServerMode.*/, lineToAdd);
          }
          // If not found, add it at the beginning
          else if (!content.includes(lineToAdd)) {
              content = lineToAdd + '\n' + content;
          }
          fs.writeFileSync(fileToPatch, content);
      }
  }
  catch (e) {
      console.error('Error patching file ', fileToPatch, '\nIs it write-protected?');
  }
}

@hal1984
Copy link
Author

hal1984 commented Mar 15, 2025

I have created a PR to fix the issue about prerendering with the default SSR:

#796

When using the new angularAppEngine / Server Routing stills the builds fails, but I think that is a different issue:

Application bundle generation failed. [3.204 seconds]

✘ [ERROR] An error occurred while extracting routes.

Error: Angular app engine manifest is not set. Please ensure you are using the '@angular/build:application' builder to build your server application.

but with the default SSR now runs ok:

npm run build:shell 

> [email protected] build:shell
> ng build shell

 INFO  Building federation artefacts
Browser bundles      
Initial chunk files   | Names            |  Raw size | Estimated transfer size
polyfills-7JMRL5KN.js | polyfills        |  72.02 kB |                23.27 kB
chunk-OBBLAJGF.js     | -                |   4.31 kB |                 1.58 kB
main-FMDHO5MO.js      | main             | 164 bytes |               164 bytes
styles-5INURTSO.css   | styles           |   0 bytes |                 0 bytes

                      | Initial total    |  76.49 kB |                25.02 kB

Lazy chunk files      | Names            |  Raw size | Estimated transfer size
chunk-FTDKJ2JJ.js     | bootstrap        |   1.40 kB |               546 bytes


Server bundles       
Initial chunk files   | Names            |  Raw size
polyfills.server.mjs  | polyfills.server |  31.05 kB |                        
server.mjs            | server           |  14.40 kB |                        
chunk-YV667WEZ.mjs    | -                |   4.82 kB |                        
chunk-TSZOCMSY.mjs    | -                |   1.83 kB |                        
main.server.mjs       | main.server      | 603 bytes |                        

Lazy chunk files      | Names            |  Raw size
chunk-XSQPPJAP.mjs    | bootstrap-server | 877.14 kB |                        

Prerendered 3 static routes.
Application bundle generation complete. [4.384 seconds]

Output location: /Users/jorge/Desktop/native-federation-19/dist/shell

@manfredsteyer
Copy link
Contributor

Thanks. But did prerender work after that change? IMHO pretender is not supported currently by NF

@hal1984
Copy link
Author

hal1984 commented Mar 19, 2025

Thanks. But did prerender work after that change? IMHO pretender is not supported currently by NF

Prerendering works, but only with the fallback option in the loadRemoteModule function within the route array; otherwise, it fails with an "Unknown remote " error. The remotes aren't loaded yet because initNodeFederation has not been called by that point. As a result, the prerendered HTML files do not contain any remote code, only the fallback one.

I tried calling it earlier, before the prerendering process starts rendering the routes, during the bootstrap process in main.server.ts. However, it fails because dist/browser has not been compiled yet.

At least, that's what I have been able to test.

@joyb-works
Copy link

I have created a fresh nx project with a host and remote for angular based on your guidelines still there is an error. the shell builds fine but the remote fails

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants