Angular18中ngx-monaco-editor-v2集成monaco-yaml的问题咨询
解决Angular 18 + ngx-monaco-editor-v2 集成 monaco-yaml 的WebWorker配置问题
一、前置依赖安装
确保安装版本兼容的依赖,monaco-yaml需与ngx-monaco-editor-v2依赖的monaco-editor版本匹配(可查看两者npm文档确认版本适配关系):
npm install monaco-yaml --save
二、调整angular.json资源配置
补充monaco-yaml的完整资源配置,仅复制单个worker文件可能导致依赖缺失:
"assets": [ // 保留原有monaco-editor配置 { "glob": "**/*", "input": "node_modules/monaco-editor", "output": "/assets/monaco/" }, // 新增monaco-yaml资源配置 { "glob": "**/*.js", "input": "node_modules/monaco-yaml/lib/esm", "output": "/assets/monaco-yaml/" } ]
三、提前配置MonacoEnvironment(核心修复点)
MonacoEnvironment必须在Monaco加载前设置,不能放在onMonacoLoad回调内。建议在main.ts中初始化:
import { bootstrapApplication } from '@angular/platform-browser'; import { appConfig } from './app/app.config'; import { AppComponent } from './app/app.component'; // 必须在Angular应用启动前设置 (window as any).MonacoEnvironment = { getWorker(moduleId: string, label: string) { return new Worker( label === 'yaml' ? '/assets/monaco-yaml/yaml.worker.js' : '/assets/monaco/esm/vs/editor/editor.worker.js', { type: 'module' } ); } }; bootstrapApplication(AppComponent, appConfig) .catch((err) => console.error(err));
四、在onMonacoLoad中初始化monaco-yaml
修改app.config.ts,导入配置函数并设置YAML Schema:
import { ApplicationConfig, importProvidersFrom, provideZoneChangeDetection, } from '@angular/core'; import { provideRouter } from '@angular/router'; import { routes } from './app.routes'; import { provideAnimationsAsync } from '@angular/platform-browser/animations/async'; import { MonacoEditorModule } from 'ngx-monaco-editor-v2'; import ParserConfSchema from 'bom-cdm/schemas/parserconf.json'; // 导入monaco-yaml配置工具 import { configureMonacoYaml } from 'monaco-yaml'; const onMonacoLoad = () => { const monaco = (window as any).monaco; // 保留原有JSON Schema配置(如需同时支持JSON编辑) monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ validate: true, schemas: [ { uri: 'http://myserver/foo-schema.json', fileMatch: ['*'], schema: ParserConfSchema, }, ], }); // 配置monaco-yaml configureMonacoYaml(monaco, { enableSchemaRequest: false, // 使用本地Schema,无需远程请求 schemas: [ { fileMatch: ['*'], uri: 'http://myserver/foo-schema.json', schema: ParserConfSchema, }, ], // 可选:添加格式化、验证等额外配置 format: { enable: true }, }); }; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideAnimationsAsync(), importProvidersFrom( MonacoEditorModule.forRoot({ onMonacoLoad: onMonacoLoad, }) ), ], };
五、修改组件支持YAML编辑
更新conf-editor.component.ts的编辑器语言配置:
export class ConfEditorComponent { // 将语言切换为yaml,如需动态切换JSON/YAML可绑定变量 editorOptions = { theme: 'vs-dark', language: 'yaml', automaticLayout: true }; constructor( public dialogRef: MatDialogRef<ConfEditorComponent>, @Inject(MAT_DIALOG_DATA) public data: { name: string; code: string; } ) {} }
六、常见错误排查
- Worker加载404:检查angular.json中assets的
input/output路径是否正确,通过浏览器Network标签确认请求路径是否匹配实际输出文件位置。 - Module解析失败:确保Worker创建时指定
type: 'module',monaco-yaml的worker为ES模块格式,必须声明该类型。 - Zone.js干扰:若Worker仍出现异常,可将创建逻辑包裹在
NgZone.runOutsideAngular中,避免Angular变更检测影响Worker运行:
import { NgZone } from '@angular/core'; // 在main.ts中获取NgZone实例后使用 (window as any).MonacoEnvironment = { getWorker(moduleId: string, label: string) { return NgZone.runOutsideAngular(() => { return new Worker( label === 'yaml' ? '/assets/monaco-yaml/yaml.worker.js' : '/assets/monaco/esm/vs/editor/editor.worker.js', { type: 'module' } ); }); } };
内容的提问来源于stack exchange,提问作者Victor
相关产品推荐
相关产品推荐

