Angular SSR环境下如何条件导入@ckeditor/ckeditor5-angular解决window未定义错误
Angular Universal SSR 环境下 CKEditor5 条件导入解决方案
问题根源
@ckeditor/ckeditor5-build-classic 依赖浏览器全局对象 window、navigator,服务端渲染阶段不存在这类浏览器专属API,因此顶层直接导入会抛出window is undefined报错。
实现方案
使用ES动态导入语法import(),仅在确认是浏览器环境后异步加载CKEditor构建包,具体实现如下:
第一步:组件基础导入
仅导入Angular核心API,不要在代码顶层导入CKEditor:
import { Component, Inject, PLATFORM_ID, OnInit } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; // 禁止此处导入 @ckeditor/ckeditor5-build-classic
第二步:组件逻辑实现
@Component({ selector: 'app-ckeditor-demo', template: ` <!-- 仅浏览器环境且Editor加载完成后渲染组件 --> <ckeditor *ngIf="isBrowser && ClassicEditor" [editor]="ClassicEditor" [(ngModel)]="editorContent" [config]="editorConfig" ></ckeditor> ` }) export class CkeditorDemoComponent implements OnInit { // 标记当前是否为浏览器环境 isBrowser: boolean; // CKEditor实例占位,初始赋值为null ClassicEditor: any = null; // 编辑器内容 editorContent = ''; // 编辑器配置可自行定义 editorConfig = {}; constructor(@Inject(PLATFORM_ID) platformId: Object) { this.isBrowser = isPlatformBrowser(platformId); } ngOnInit() { if (this.isBrowser) { // 浏览器环境下动态导入CKEditor import('@ckeditor/ckeditor5-build-classic').then(importResult => { // 取默认导出的ClassicEditor实例赋值 this.ClassicEditor = importResult.default; }) } } }
注意事项
- 动态导入返回Promise对象,需在回调中取导出的模块内容,官方经典构建的默认导出就是
ClassicEditor,因此取.default属性 - 模板中必须加
*ngIf判断,避免服务端渲染阶段渲染CKEditor组件导致报错 - 如果使用自定义构建的CKEditor包,只需要把
import()中的路径替换为你自定义构建的包路径即可 - 若需要处理加载状态,可以新增一个
loading变量,导入前设为true,导入完成后设为false,模板中对应展示加载提示即可
内容的提问来源于stack exchange,提问作者fahad
相关产品推荐
相关产品推荐

