Reputation: 69
I have created an Angular SSR app, there I have installed NgApexchartsModule module, after this when I try to run the below command I am facing this issue:
command: ng run abc:serve-ssr
ReferenceError: window is not defined
at Object.ujAs (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:230211:345871)
at __webpack_require__ (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:20:30)
at Module.CV0D (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:91098:68)
at __webpack_require__ (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:20:30)
at Module.ZAI4 (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:127394:72)
at __webpack_require__ (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:20:30)
at Module.24aS (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:55649:69)
at __webpack_require__ (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:20:30)
at Module.K011 (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:102532:80)
at __webpack_require__ (D:\EXPERIMENTAL\SSR\abc\dist\abc\server\main.js:20:30)
A server error has occurred.
node exited with 1 code.
connect ECONNREFUSED 127.0.0.1:59450
Configuration:
app.module.ts
imports: [
BrowserModule,
BrowserAnimationsModule,
MaterialModuleComponents,
NgbModule,
NgxGaugeModule,
HttpClientModule,
NgxMatIntlTelInputModule,
Ng2SearchPipeModule,
NgxSpinnerModule,
**NgApexchartsModule**,
NgpImagePickerModule,
NgxFileDragDropModule,
MatDatetimepickerModule,
MatNativeDatetimeModule,
NgxSkeletonLoaderModule.forRoot(),
JoyrideModule.forRoot(),
BrowserModule.withServerTransition({ appId: 'serverApp' })
],
Server.ts
import 'zone.js/dist/zone-node';
import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';
import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '@angular/common';
import { existsSync } from 'fs';
import {enableProdMode} from '@angular/core';
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/abc/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
const domino = require('domino');
const win = domino.createWindow(indexHtml);
// mock
global['window'] = win;
global['document'] = win.document;
global['navigator'] = win.navigator;
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/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';
app.server.module.ts
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
@NgModule({
imports: [
AppModule,
ServerModule,
],
bootstrap: [AppComponent],
})
export class AppServerModule {}
I tried with window element also which I have motioned in the above code but still facing the same issue. Thanks in advance.
Upvotes: 0
Views: 2552
Reputation: 3778
Your problem is you're using SSR .. and in the server window doesn't EXIST ... so you can basically check for which environment you're in (client or server)
you can do it like this:
Check with a directive on the HTML where you put your apex chart if you're in browser or server
the directive:
import {Directive, Inject, OnInit, PLATFORM_ID, TemplateRef, ViewContainerRef} from '@angular/core';
import {isPlatformServer} from '@angular/common';
@Directive({
selector: '[SSR]'
})
export class SSRDirective implements OnInit {
constructor(
private viewContainer: ViewContainerRef,
private templateRef: TemplateRef<any>,
@Inject(PLATFORM_ID) private platformId
) { }
ngOnInit() {
if (isPlatformServer(this.platformId)) {
this.viewContainer.clear();
} else {
this.viewContainer.createEmbeddedView(this.templateRef);
}
}
}
And you can use like this:
<apextag [bidings]
*SSR>
</apextag>
Upvotes: 1