首页 > 解决方案 > ReferenceError:导航器未在 angular-universal-pwa 中定义

问题描述

错误图像 我正在尝试一起实现 angular Universal 和 pwa。我参考了以下链接: https ://medium.com/digital-diplomacy/how-to-enable-server-side-rendering-and-pwa-for-your-angular-app-2831b16fa99b

after executing command: npm run serve:ssr
getting the below error.

\server\main.js

    

var userLangAttribute = navigator.language || navigator.userLanguage || navigator.browserLanguage;                                                                                                                                         ^                                                                                                                                                                                                                                                                                                                                                                                                             

ReferenceError: navigator is not defined                                                                                                                                                                               


package.json

{
  "name": "my-hilarious-app",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "dev:ssr": "ng run my-hilarious-app:serve-ssr",
    "serve:ssr": "node dist/my-hilarious-app/server/main.js",
    "build:ssr": "ng build --prod && ng run my-hilarious-app:server:production",
    "prerender": "ng run my-hilarious-app:prerender"
  },
  "private": true,
  "dependencies": {
    "@agm/core": "^1.0.0-beta.5",
    "@angular/animations": "~11.2.5",
    "@angular/cdk": "^11.2.4",
    "@angular/common": "~11.2.5",
    "@angular/compiler": "~11.2.5",
    "@angular/core": "~11.2.5",
    "@angular/fire": "^6.0.5",
    "@angular/forms": "~11.2.5",
    "@angular/material": "^11.2.4",
    "@angular/platform-browser": "~11.2.5",
    "@angular/platform-browser-dynamic": "~11.2.5",
    "@angular/platform-server": "~11.2.5",
    "@angular/router": "~11.2.5",
    "@angular/service-worker": "~11.2.5",
    "@fortawesome/fontawesome-free": "^5.15.2",
    "@ng-bootstrap/ng-bootstrap": "^9.0.2",
    "@ngrx/effects": "^11.0.1",
    "@ngrx/store": "^11.0.1",
    "@nguniversal/express-engine": "^11.2.1",
    "@types/googlemaps": "^3.36.0",
    "angularx-social-login": "^3.5.4",
    "bootstrap3": "^3.3.5",
    "core-js": "^3.9.1",
    "crypto-js": "^3.1.9-1",
    "express": "^4.17.1",
    "firebase": "^8.3.0",
    "font-awesome": "^4.7.0",
    "globalthis": "^1.0.2",
    "hammerjs": "^2.0.8",
    "jquery": "^3.6.0",
    "ngx-cookie-service": "^11.0.2",
    "ngx-owl-carousel-o": "^5.0.0",
    "ngx-toastr": "^13.2.0",
    "ngx-xml2json": "^1.0.2",
    "rxjs": "~6.6.6",
    "smart-app-banner": "^2.0.0",
    "tslib": "^2.1.0",
    "webpack-dev-server": ">=3.11.2",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1102.4",
    "@angular/cli": "~11.2.4",
    "@angular/compiler-cli": "~11.2.5",
    "@nguniversal/builders": "^11.2.1",
    "@types/express": "^4.17.11",
    "@types/jasmine": "~3.6.6",
    "@types/node": "^14.14.33",
    "codelyzer": "^6.0.1",
    "jasmine-core": "~3.6.0",
    "jasmine-spec-reporter": "~6.0.0",
    "karma": "~6.2.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-jasmine": "~4.0.1",
    "karma-jasmine-html-reporter": "^1.5.4",
    "protractor": "~7.0.0",
    "ts-node": "~9.1.1",
    "tslint": "~6.1.3",
    "typescript": "~4.1.5"
  }
}


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';
const domino = require('domino');

const fs = require('fs');

const path = require('path');

const template = fs.readFileSync(path.join('.', 'dist/my-hilarious-app/browser', 'index.html')).toString();

const win = domino.createWindow(template);
// tslint:disable-next-line:no-string-literal

global['window'] = win;

// tslint:disable-next-line:no-string-literal

global['document'] = win.document;

// tslint:disable-next-line:no-string-literal

global['DOMTokenList'] = win.DOMTokenList;

// tslint:disable-next-line:no-string-literal
global['Node'] = win.Node;

// tslint:disable-next-line:no-string-literal

global['Text'] = win.Text;

// tslint:disable-next-line:no-string-literal

global['HTMLElement'] = win.HTMLElement;

// tslint:disable-next-line:no-string-literal

global['navigator'] = win.navigator; 
// 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/my-hilarious-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/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';


  [1]: https://i.stack.imgur.com/P7vyi.png


  [1]: https://i.stack.imgur.com/ZiulH.png

上面的文件是我的 server.ts 和 package.json。由于 main.js 是只读文件,我们无法对其进行任何更改。我能够运行命令:ng build --prod && ng run my-hilarious-app:server :生产。但是在此之后,当我运行此命令时:ng run my-hilarious-app:serve-ssr。我遇到了问题。谢谢!

标签: javascriptnode.jsangular

解决方案


我得到了解决方案。我发现第三方插件的 smart-app-banner 给出了错误。所以我用 ngx smart banner 替换了那个智能应用横幅代码。我安装并实现了 ngx smart banner。并且能够顺利运行它。


推荐阅读