简体   繁体   English

ngx-extended-pdf-viewer with angular 通用(预渲染)

[英]ngx-extended-pdf-viewer with angular universal (prerender)

I have used ngx-extended-pdf-viewer in my Angular app to show a PDF catalog (The PDF catalog is on a locally folder).我在我的 Angular 应用程序中使用了 ngx-extended-pdf-viewer 来显示 PDF 目录(PDF 目录位于本地文件夹中)。 It works fine locally but when I try to prerender the app, I am getting this error: ERROR while prerendering它在本地运行良好,但是当我尝试预渲染应用程序时,我收到此错误:预渲染时出现错误

Here is the log file error:这是日志文件错误:

0 info it worked if it ends with ok
1 verbose cli [
1 verbose cli   'C:\\Program Files\\nodejs\\node.exe',
1 verbose cli   'C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js',
1 verbose cli   'run',
1 verbose cli   'prerender'
1 verbose cli ]
2 info using npm@6.14.8
3 info using node@v12.19.0
4 verbose run-script [ 'prerender' ]
5 info lifecycle capcondo-angular@0.0.0~prerender: capcondo-angular@0.0.0
6 verbose lifecycle capcondo-angular@0.0.0~prerender: unsafe-perm in lifecycle true
7 verbose lifecycle capcondo-angular@0.0.0~prerender: PATH: C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\node-gyp-bin;D:\travail\Capcondo-angular\node_modules\.bin;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\usr\bin;C:\Users\ALA EDDINE\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\WINDOWS\System32\OpenSSH;C:\Program Files\nodejs;C:\Program Files\Git\cmd;C:\Program Files\dotnet;C:\Users\ALA EDDINE\AppData\Local\Microsoft\WindowsApps;C:\Users\ALA EDDINE\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\ALA EDDINE\AppData\Roaming\npm;C:\Program Files\heroku\bin
8 verbose lifecycle capcondo-angular@0.0.0~prerender: CWD: D:\travail\Capcondo-angular
9 silly lifecycle capcondo-angular@0.0.0~prerender: Args: [ '/d /s /c', 'ng run Capcondo-angular:prerender' ]
10 silly lifecycle capcondo-angular@0.0.0~prerender: Returned: code: 1  signal: null
11 info lifecycle capcondo-angular@0.0.0~prerender: Failed to exec prerender script
12 verbose stack Error: capcondo-angular@0.0.0 prerender: `ng run Capcondo-angular:prerender`
12 verbose stack Exit status 1
12 verbose stack     at EventEmitter.<anonymous> (C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\index.js:332:16)
12 verbose stack     at EventEmitter.emit (events.js:314:20)
12 verbose stack     at ChildProcess.<anonymous> (C:\Program Files\nodejs\node_modules\npm\node_modules\npm-lifecycle\lib\spawn.js:55:14)
12 verbose stack     at ChildProcess.emit (events.js:314:20)
12 verbose stack     at maybeClose (internal/child_process.js:1021:16)
12 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)
13 verbose pkgid capcondo-angular@0.0.0
14 verbose cwd D:\travail\Capcondo-angular
15 verbose Windows_NT 10.0.19042
16 verbose argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "run" "prerender"
17 verbose node v12.19.0
18 verbose npm  v6.14.8
19 error code ELIFECYCLE
20 error errno 1
21 error capcondo-angular@0.0.0 prerender: `ng run Capcondo-angular:prerender`
21 error Exit status 1
22 error Failed at the capcondo-angular@0.0.0 prerender script.
22 error This is probably not a problem with npm. There is likely additional logging output above.
23 verbose exit [ 1, true ]

Here is my server.ts file:这是我的 server.ts 文件:

(global as any).WebSocket = require('ws');
(global as any).XMLHttpRequest = require('xhr2');

const domino = require('domino');
const fs = require('fs');
const path = require('path');
const distFolder = join(process.cwd(), 'dist/Capcondo-angular/browser');
const template = fs.readFileSync(path.join(distFolder, 'index.html')).toString();
const win = domino.createWindow(template.toString());
global['window'] = win;
global['document'] = win.document;
global['self'] = win
global['IDBIndex'] = win.IDBIndex
global['document'] = win.document
global['navigator'] = win.navigator
global['getComputedStyle'] = win.getComputedStyle;

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';

// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
  const server = express();
  let distFolder = join(process.cwd(), 'browser');
  if (!existsSync(distFolder)) {
    distFolder = join(process.cwd(), 'dist/Capcondo-angular/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';

I have already imported "NgxExtendedPdfViewerModule" in the app.module.ts and "NgxExtendedPdfViewerServerModule" in the app.server.module.ts.我已经在 app.module.ts 中导入了“NgxExtendedPdfViewerModule”,在 app.server.module.ts 中导入了“NgxExtendedPdfViewerServerModule”。

Thank you in advance for your support!预先感谢您对我们的支持!

Looks like you have use document global object directly in your code, which would break the universal and pre-rendering.看起来您在代码中直接使用了文档全局 object,这会破坏通用和预渲染。 You have 2 options:您有 2 个选项:

  1. using if(isPlatformBrowser(this.platformId)) check and put the code that uses browser's document object in it.使用if(isPlatformBrowser(this.platformId))检查并将使用浏览器文档 object 的代码放入其中。
  2. use dependency injection for mocking the document object.对 mocking 文档 object 使用依赖注入。 Angular has a built-in token for document which you can import from: @angular/common Then inject it like this: Angular 有一个内置的文档令牌,您可以从中导入: @angular/common然后像这样注入它:
@Inject(DOCUMENT) private readonly documentRef: Document

Then where you are using document object, simply replace it with: this.documentRef然后在您使用文档 object 的地方,只需将其替换为: this.documentRef

I prefer the second approach我更喜欢第二种方法

For more information read these articles:有关更多信息,请阅读以下文章:
Global objects in Angular Angular 中的全局对象
Angular Universal: real app problems Angular 通用:真实应用问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM