node.js - 使用 Node.js 进行 Angular 4 服务器端渲染(ReferenceError : document is not defined))

标签 node.js angular

我按照教程here进行操作实现服务器端渲染 Angular 4 应用程序。但是,我不知道如何解决 Node.js 中与“文档未定义”相关的问题。我知道 Node.js 没有 DOM,因为它不是“浏览器”。但是,我真的需要在服务器中渲染应用程序以进行搜索引擎优化,但我不知道如何解决这些问题。我无法更改代码,因为它是第三方代码,嗯...有什么建议吗?

/var/www/nodejs/example.com/node_modules/custom-event/index.js:24
'function' === typeof document.createEvent ? function CustomEvent (type, params) {
                  ^
ReferenceError: document is not defined at Object.<anonymous> (/var/www/nodejs/example.com/node_modules/custom-event/index.js:24:23)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Module.require (module.js:513:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/var/www/nodejs/example.com/node_modules/crossvent/src/crossvent.js:3:19)
    at Module._compile (module.js:569:30)

我搜索了很多与“文档未定义”相关的帖子,大多数都只是解释node.js没有DOM,但没有提供任何解决方案。

如果您需要我的server.ts,那么这就是它。

import 'reflect-metadata';
import 'zone.js/dist/zone-node';
import { platformServer, renderModuleFactory } from '@angular/platform-server';
import { enableProdMode } from '@angular/core';
import { AppServerModuleNgFactory } from '../dist/ngfactory/src/app/app.server.module.ngfactory';
import * as express from 'express';
import { readFileSync } from 'fs';
import { join } from 'path';
const PORT = 4000;

enableProdMode();

const app = express();

let template = readFileSync(join(__dirname, '..', 'dist', 'index.html')).toString();

app.engine('html', (_, options, callback) => {
    const opts = { document: template, url: options.req.url };
    renderModuleFactory(AppServerModuleNgFactory, opts)
        .then(html => callback(null, html));
});

app.set('view engine', 'html');
app.set('views', 'src')

app.get('*.*', express.static(join(__dirname, '..', 'dist')));

app.get('*', (req, res) => {
    res.render('index', { req });
});

app.listen(PORT, () => {
    console.log(`listening on http://localhost:${PORT}!`);
});

提前致谢。

最佳答案

NodeJs 不支持窗口、文档、导航器 类型。因此,解决方案是将文件夹复制到另一个目录,例如在 src/server-mocks/ 中,并用 index.js 文件中的 global 替换所有 document 类型,并通过添加以下代码来配置 webpack.server.config.js

const NormalModuleReplacementPlugin = require('webpack/lib/NormalModuleReplacementPlugin');

 new NormalModuleReplacementPlugin(
      /crossvent(\\|\/)src(\\|\/)crossvent.js/,
      path.join(__dirname, 'src/server-mocks/crossvent/src/crossvent.js')    
    ),

关于node.js - 使用 Node.js 进行 Angular 4 服务器端渲染(ReferenceError : document is not defined)),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45581696/

相关文章:

javascript - Firebase 身份验证 "auth/invalid-email"和 "The email address is badly formatted."

angular - 无法在 IE 中将 SVG 下载为 PNG

javascript - 尝试将 json 值与局部变量相乘时出现 NaN

node.js - npm install : fetchPackageMetaData error for material-design-icons@^3. 0.1 意外的文件结尾

Angular 服务装饰器提供了对延迟加载的根本影响

Angular 4 隐藏的 div 无法正常工作

node.js - npm 模块已安装但不可用?

node.js - Node 内存使用率

javascript - 使用 NodeJS FS mkdir 时,包含回调的重要性是什么?

javascript - 如何在 Angular 4 中的同一个 ngFor 中使用两个不同的索引变量