Angular 17独立应用集成CKEditor 5报错:window is not defined
Angular 17独立应用集成CKEditor 5报错:window is not defined
使用Angular 17.1.2版本的独立应用,按官方步骤集成CKEditor 5时触发如下错误:
[vite] Internal server error: window is not defined at r (d:/Study/Nam3_HK3/DoAn/bookmanagement/fiction-management-fe/node_modules/@ckeditor/ckeditor5-build-classic/build/ckeditor.js:1:12102) at __require2 (D:/Study/Nam3_HK3/DoAn/bookmanagement/fiction-management-fe/.angular/vite-root/fiction-management-fe/chunk-ZLOYPDTO.mjs:51:50) at eval (d:/Study/Nam3_HK3/DoAn/bookmanagement/fiction-management-fe/src/app/component/admin-chapter-feature/admin-chapter-feature.component.ts:8:32) at async instantiateModule (file:///D:/Study/Nam3_HK3/DoAn/bookmanagement/fiction-management-fe/node_modules/vite/dist/node/chunks/dep-9A4-l-43.js:50861:9) (x3)
相关代码
组件代码
import { CommonModule} from '@angular/common'; import { Component, OnInit } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { CKEditorModule } from '@ckeditor/ckeditor5-angular'; import { ChangeEvent } from '@ckeditor/ckeditor5-angular/ckeditor.component'; @Component({ selector: 'app-admin-chapter-feature', standalone: true, imports: [ FormsModule, MatFormFieldModule, MatInputModule, CKEditorModule, CommonModule, ], templateUrl: './admin-chapter-feature.component.html', styleUrl: './admin-chapter-feature.component.css', }) export class AdminChapterFeatureComponent implements OnInit { public Editor: any; ngOnInit(): void { // 动态导入CKEditor构建包 import('@ckeditor/ckeditor5-build-classic').then(module => { this.Editor = module.default; }); } public onReady(editor: any) { console.log("CKEditor5 Angular Component is ready to use!", editor); } public onChange({ editor }: ChangeEvent) { const data = editor.getData(); console.log(data); } }
模板代码
<h2>CHAPTER MANAGEMENT</h2> <div class="wrapper-chapter"> <form class="example-form"> <mat-form-field class="example-full-width"> <mat-label>Chapter name</mat-label> <input matInput placeholder="" /> </mat-form-field> <mat-form-field class="example-full-width"> <mat-label>Chapter content</mat-label> <textarea matInput placeholder=""></textarea> </mat-form-field> <!-- 添加*ngIf确保Editor加载完成后再渲染 --> <ckeditor *ngIf="Editor" [editor]="Editor" data="<p>Hello from CKEditor5!</p>" (ready)="onReady($event)" (change)="onChange($event)" > </ckeditor> </form> </div>
typings.d.ts文件
declare module '@ckeditor/ckeditor5-build-classic' { const ClassicEditorBuild: any; export = ClassicEditorBuild; }
package.json依赖
"@ckeditor/ckeditor5-angular": "^7.0.1", "@ckeditor/ckeditor5-build-classic": "^41.2.1", "@ckeditor/ckeditor5-core": "^41.2.1", "@ckeditor/ckeditor5-engine": "^41.2.1", "@ckeditor/ckeditor5-utils": "^41.2.1", "@ckeditor/ckeditor5-watchdog": "^41.2.1",
解决方案
1. 动态导入CKEditor构建包
将原静态导入改为组件初始化时动态导入,确保代码仅在浏览器环境执行(Node环境不会触发此导入,避免访问window报错)。同时在模板中添加*ngIf="Editor",防止在Editor未加载完成时渲染组件。
2. 配置Vite排除SSR处理(若启用SSR)
如果项目启用了服务端渲染(SSR),在vite.config.ts中添加如下配置,告诉Vite不要将CKEditor相关包转为外部依赖,避免在Node环境处理:
import { defineConfig } from 'vite'; import angular from '@angular-devkit/build-angular/src/vite/index'; export default defineConfig({ plugins: [angular()], ssr: { noExternal: ['@ckeditor/ckeditor5-build-classic', '@ckeditor/ckeditor5-angular'] } });
3. 可选:移除自定义类型声明
CKEditor 5的官方build包已自带类型定义,可尝试删除typings.d.ts文件,避免类型冲突。
问题原因
Angular 17默认使用Vite构建工具,且可能启用了服务端预渲染(SSR)或在构建阶段尝试在Node环境下解析代码。而CKEditor 5的build版本依赖浏览器的window对象,在Node环境加载时直接访问window会触发错误。动态导入可延迟CKEditor的加载时机到浏览器环境,从而规避此问题。
内容的提问来源于stack exchange,提问作者seetinhboiz
相关产品推荐
相关产品推荐

