Skip to content

bug: Plenty of Ionic Server Angular Universal Issuers, SSR, Capacitor Preferences getItem error, window is not defined, self is not defined, cannot redefine property constructor #26849

@MilotH2

Description

@MilotH2

Prerequisites

Ionic Framework Version

  • v4.x
  • v5.x
  • v6.x
  • v7.x
  • Nightly

Current Behavior

I have issues building Ionic server with Angular Universal SSR, running npm run build:ssr and then npm run serve:ssr or npm run dev:ssr
I get plenty of errors such as:
window is not defined
self is not defined (after fixing window is not defined)
cannot redefine property constructor
this issue: #24782 (even though i get this error, the ion-menu works first time but when refreshing it does not work)
Capacitor Preferences getItem error (I think so)

Expected Behavior

Should not get these kind of errors when running npm run serve:ssr or npm run dev:ssr and should be able to run the app properly.

Steps to Reproduce

  1. Clone repo
  2. run npm install
  3. run ionic build --prod
  4. run build:ssr
  5. run serve:ssr or dev:ssr
  6. open link given on cli like localhost:4000
  7. see errors appearing
  8. you can uncomment and re add // (global['self'] as any) = win; to reproduce the other errors. from server.ts
  9. I added a RAR file where this is working, strangely. and this Repository is the changes I did after that and it is not working. This takes me to the same path where i create a component and change tabs and more.

Code Reproduction URL

https://github.com/MilotH2/fixing-ssr-ionic-server

Ionic Info

Ionic:

Ionic CLI : 6.20.3 (C:\ProgramData\nvm\v18.12.1\node_modules@ionic\cli)
Ionic Framework : @ionic/angular 6.5.0
@angular-devkit/build-angular : 15.1.2
@angular-devkit/schematics : 15.1.2
@angular/cli : 15.1.2
@ionic/angular-toolkit : 7.0.0

Capacitor:

Capacitor CLI : 4.6.2
@capacitor/android : 4.6.2
@capacitor/core : 4.6.2
@capacitor/ios : 4.6.2

Utility:

cordova-res : not installed globally
native-run : 1.7.1

System:

NodeJS : v18.12.1 (C:\Program Files\nodejs\node.exe)
npm : 8.19.2
OS : Windows 10

Additional Information

I have tried but unsuccessfully, it would be really helpful to fix this issue given some examples. This is just a simple project with not much data in it and still not working.

you can try with server.ts code also to reproduce different errors:

`
import 'zone.js/node';
import { enableProdMode } from '@angular/core';
import { APP_BASE_HREF, DOCUMENT, isPlatformServer } from '@angular/common';
import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';

import { existsSync, readFileSync } from 'fs';
import { renderModule, platformDynamicServer } from '@angular/platform-server';
import { enableDebugTools, TransferState } from '@angular/platform-browser';
import { AppModule } from './src/app/app.module';
import { environment } from './src/environments/environment';

import { AppServerModule } from './src/main.server';

import { createWindow } from 'domino';
const scripts = readFileSync('dist/app/browser/index.html').toString();
const window = createWindow(scripts) as any;
(global as any).window = window;
(global as any).document = window.document;
(global as any).Event = window.Event;
(global as any).KeyboardEvent = window.KeyboardEvent;
(global as any).MouseEvent = window.MouseEvent;

enableProdMode();

// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), 'dist/app/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html'))
? 'index.original.html'
: 'index';

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/main/modules/express-engine)
server.engine(
'html',
ngExpressEngine({
bootstrap: AppServerModule,
})
);

server.set('view engine', 'html');
server.set('views', distFolder);

// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get(
'.',
express.static(distFolder, {
maxAge: '1y',
})
);

// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render(indexHtml, {
req,
providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }],
});
});

return server;
}

function run(): void {
const port = process.env['PORT'] || 4000;

// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(Node Express server listening on http://localhost:${port});
});
}

// Webpack will replace 'require' with 'webpack_require'
// 'non_webpack_require' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const non_webpack_require: NodeRequire;
const mainModule = non_webpack_require.main;
const moduleFilename = (mainModule && mainModule.filename) || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}

export * from './src/main.server';

`

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions