Bootstrap Angular 预渲染:有条件地使用JS会导致“文档未定义”

qlckcl4x  于 2023-04-18  发布在  Bootstrap
关注(0)|答案(1)|浏览(124)

我正在使用Angular 15,并试图为SEO目的预渲染网站。我知道预渲染时,documentwindow等工具不可用,因为代码不在浏览器上运行。
我使用了一些JS库来直接操作DOM,为了支持预渲染,我这样做了:

import Typed from 'typed.js';

export class ExampleComponent implements OnInit {
  
  typed?: Typed;

  constructor(
    @Inject(PLATFORM_ID) private platformId: any
  ) { }

  ngOnInit(): void {
     if (isPlatformBrowser(this.platformId)) {
      this.typed = new Typed('#searchdomain', {
          strings: ["example", "anoter" ""],
          typeSpeed: 80,
          contentType: "text"
        });
    }   
  }

正如您所看到的,Typed仅在应用程序在浏览器上运行时才示例化。
现在我尝试用Bootstrap 5做同样的事情,但失败了。

import * as Bootstrap from 'bootstrap/dist/js/bootstrap.esm.min.js';

export class ExampleComponent implements OnInit {
  
  private bsModalInstance?: Bootstrap.Modal;
  @ViewChild('bsmodal', {read: ElementRef, static: false}) modalRef?: ElementRef;

  constructor(
    @Inject(PLATFORM_ID) private platformId: any
  ) { }

  ngOnInit(): void {
     if (isPlatformBrowser(this.platformId)) {
       this.bsModalInstance = new Bootstrap.Modal(this.modalRef?.nativeElement);
     }  
  }

npm run prerender的输出:

⠴ Prerendering 2 route(s) to -path-\-proj-\dist\-proj-\browser...
Unhandled Promise rejection: document is not defined ; Zone: <root> ; Task: Promise.then ; Value: ReferenceError: document is not defined
    at enableDismissTrigger (-path-\-proj-\dist\-proj-\server\main.js:1:3878580)
    at -path-\-proj-\dist\-proj-\server\main.js:1:3879522
    at -path-\-proj-\dist\-proj-\server\main.js:1:3977330
    at Object.<anonymous> (-path-\-proj-\dist\-proj-\server\main.js:1:3977562)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:12)
    at Module.require (internal/modules/cjs/loader.js:974:19)
    at require (internal/modules/cjs/helpers.js:101:18) ReferenceError: document is not defined
    at enableDismissTrigger (-path-\-proj-\dist\-proj-\server\main.js:1:3878580)
    at -path-\-proj-\dist\-proj-\server\main.js:1:3879522
    at -path-\-proj-\dist\-proj-\server\main.js:1:3977330
    at Object.<anonymous> (-path-\-proj-\dist\-proj-\server\main.js:1:3977562)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:12)
    at Module.require (internal/modules/cjs/loader.js:974:19)
    at require (internal/modules/cjs/helpers.js:101:18)
✖ Prerendering routes to -path-\-proj-\dist\-proj-\browser failed.
document is not defined

为什么当Bootstrap的Bootstrap.Modal甚至没有示例化时它会失败?
有没有什么方法可以进行更多的调试,这样我就可以找到调用document.的确切文件?

**更新:**我决定在组件的构造函数上添加一个console.log(),但它从未显示。我相信 Bootstrap 在导入时会立即访问document,甚至在Bootstrap.Modal调用之前。

谢谢大家。

zujrkrfu

zujrkrfu1#

这确实是Bootstrap在导入时访问windowsdocument和其他一些对象所导致的问题。这已经在https://github.com/twbs/bootstrap/pull/34989上进行了讨论,其中一部分问题得到了解决,但不是全部。
我决定对仓库进行分叉,并对jo-ssr-friendly分支添加进一步的修复,同时将其重新定位到最新的稳定版本。
如果将来有人遇到这个问题,所有这些修复都可以直接从我的fork安装:

npm install "https://github.com/TCB13/bootstrap.git#jo-ssr-friendly" --save

相关问题