【问题标题】:Angular 11 SSR serve problem with error window is not defined未定义错误窗口的 Angular 11 SSR 服务问题
【发布时间】:2021-09-07 08:17:21
【问题描述】:

当我尝试使用 Angular 生成构建和服务 SSR 项目时,出现此错误

C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:72623

var requestFn = window.requestAnimationFrame||getPrefixed('RequestAnimationFrame') || timeoutDefer;

ReferenceError: window is not defined
at C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:72623:19
at C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:72404:11
at Object.4R65 (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:72406:2)
at __webpack_require__ (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:26:30)
at Module.ZeVW (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:223603:65)
at __webpack_require__ (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:26:30)
at Module.PCNd (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:178377:126)
at __webpack_require__ (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:26:30)
at Module.ZAI4 (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:221439:79)
at __webpack_require__ (C:\Projects\cloud_market_ssr\client\dist\market\server\main.js:26:30)

error 命令失败,退出代码为 1。 info 访问https://yarnpkg.com/en/docs/cli/run 获取有关此命令的文档。

进程以退出代码 1 结束

这是我安装的软件包,它们完美地工作

{
  "name": "market",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build --prod",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "dev:ssr": "ng run market:serve-ssr",
    "serve:ssr": "node dist/market/server/main.js",
    "build:ssr": "npm run build && ng run market:server:production",
    "full:ssr": "npm run build:ssr && npm run dev:ssr && npm run serve:ssr",
    "prerender": "ng run market:prerender"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^11.2.13",
    "@angular/cdk": "^11.2.12",
    "@angular/common": "^11.2.13",
    "@angular/compiler": "^11.2.13",
    "@angular/core": "^11.2.13",
    "@angular/flex-layout": "^11.0.0-beta.33",
    "@angular/forms": "^11.2.13",
    "@angular/material": "^11.2.12",
    "@angular/platform-browser": "^11.2.13",
    "@angular/platform-browser-dynamic": "^11.2.13",
    "@angular/platform-server": "^11.2.13",
    "@angular/pwa": "^0.1102.12",
    "@angular/router": "^11.2.13",
    "@angular/service-worker": "^11.2.13",
    "@nguniversal/express-engine": "^11.2.1",
    "@nicky-lenaers/ngx-scroll-to": "^9.0.0",
    "core-js": "^2.5.4",
    "cors": "^2.8.5",
    "domino": "^2.1.6",
    "echarts": "^4.2.0-rc.2",
    "echarts-gl": "^1.1.1",
    "edit-json-file": "^1.6.0",
    "express": "^4.15.2",
    "font-awesome": "^4.7.0",
    "hammerjs": "^2.0.8",
    "jalali-moment": "^3.2.1",
    "jquery": "^3.4.1",
    "leaflet": "^1.7.1",
    "leaflet-arc": "^1.0.2",
    "localforage": "^1.5.0",
    "localstorage-polyfill": "^1.0.1",
    "mock-browser": "^0.92.14",
    "moment-jalaali": "~0.9.2",
    "ngforage": "^6.0.0",
    "ngx-image-compress": "^11.0.3",
    "ngx-image-zoom": "^0.6.0",
    "ngx-owl-carousel-o": "^5.0.0",
    "ngx-pagination": "^5.1.0",
    "ngx-slick-carousel": "~0.5.1",
    "rxjs": "^6.5.3",
    "sass": "^1.32.6",
    "slick-carousel": "~1.8.1",
    "webpack-node-externals": "^3.0.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.1002.0",
    "@angular/cli": "^11.2.12",
    "@angular/compiler-cli": "^11.2.13",
    "@angular/language-service": "^11.2.13",
    "@nguniversal/builders": "^10.1.0",
    "@types/express": "^4.17.0",
    "@types/jasmine": "~3.7.2",
    "@types/jasminewd2": "~2.0.9",
    "@types/node": "~14.14.44",
    "codelyzer": "~6.0.2",
    "eslint": "~7.26.0",
    "jasmine-core": "~3.7.1",
    "jasmine-spec-reporter": "~7.0.0",
    "karma": "~6.3.2",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "~3.0.3",
    "karma-jasmine": "~4.0.1",
    "karma-jasmine-html-reporter": "^1.6.0",
    "protractor": "^7.0.0",
    "ts-node": "~9.1.1",
    "typescript": "~4.0.6"
  }
}

这是我的 server.ts

import 'zone.js/dist/zone-node';
import * as express from 'express';

import { ngExpressEngine } from '@nguniversal/express-engine';
import { join } from 'path';

///Handle Error local storage & document & window not defined
const MockBrowser = require('mock-browser').mocks.MockBrowser;
const mock = new MockBrowser();

const cors = require('cors');
const exp = require('express');

const application = exp();application.use(cors());

const domino = require("domino");
const fs = require("fs");
const path = require("path");
const templateA = fs
  .readFileSync(path.join("dist/browser", "index.html"))
  .toString();
const win = domino.createWindow(templateA);
win.Object = Object;
win.Math = Math;


import 'localstorage-polyfill';
global['localStorage'] = localStorage;


global["window"] =  mock.getWindow();
global["document"] = mock.getDocument();
global["branch"] = null;
global["object"] = win.object;
global['navigator'] = mock.getNavigator();

Object.defineProperty(document.body.style, 'transform', {
  value: () => {
    return {
      enumerable: true,
      configurable: true
    };
  },
});

//////////////////////////////////////

import { APP_BASE_HREF } from '@angular/common';
import { AppServerModule } from './src/main.server';
import { existsSync } from 'fs';

// 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/client/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 || 5050;

  // 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();
}
const nodeExternals = require('webpack-node-externals');

module.exports = {
  externals: [nodeExternals()],
  // etc configs here
}

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

【问题讨论】:

    标签: javascript angular server-side-rendering angular11


    【解决方案1】:

    您可能正在使用一些需要在其中呈现窗口的库或组件,例如图表。

    检查您的代码库,看看是否有任何东西可以使用该窗口并且不需要在服务器端呈现。

    一旦你找到它,使用 Angular 的平台 id 注入器来检查你是在浏览器还是服务器上,如果它在服务器上,不要渲染所述组件。

    【讨论】:

    • 我面临同样的问题,但我的问题是窗口错误来自库...有没有办法排除 SSR 中的某些库?我的意思是编译ssr什么的……
    猜你喜欢
    • 1970-01-01
    • 2020-09-13
    • 2019-11-07
    • 1970-01-01
    • 1970-01-01
    • 2019-01-26
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多