You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 16:53:09