使用微软Monaco Editor 编写在线调试工具

前言

微软之前有个项目叫做Monaco Workbench,后来这个项目变成了VS Code,而Monaco Editor就是从这个项目中成长出来的一个web编辑器,所以Monaco Editor和VS Code在编辑代码,交互以及UI上几乎是一摸一样的,有点不同的是,两者的平台不一样,Monaco Editor基于浏览器,而VS Code基于electron,所以功能上VSCode更加健全,并且性能比较强大。本文主要介绍ng-zorro 框架集成Monaco Editor实现HTML 在线调试器。Monaco Editor 不仅能做代码编辑器,同样可以做文本比对。

环境及组件

Monaco Editor 微软 Monaco Editor 编辑器
Ant Design of Angular NG-ZORRO
ngx-monaco-editor monaco-editor angular npm 包

实现

根据 ngx-monaco-editor 文档按angular版本安装指定版本的npm包
注意:版本对应不上会导致资源404错误

  • Angular <= 4: v3.x.x
  • Angular 5: v5.x.x
  • Angular 6: v6.x.x
  • Angular 7: v7.x.x
  • Angular 8: v8.x.x
  • Angular 9: v9.x.x

npm install [email protected] --save

接下来配置全局静态资源
Angular 6 之前版本 添加到.angular-cli.json文件中

{
     
  "options": {
     
    {
     
      "assets": [
        {
      "glob": "**/*", "input": "node_modules/ngx-monaco-editor/assets/monaco", "output": "./assets/monaco/" }
      ],
      ...
    }
    ...
  },
  ...
}

Angular 6 之后版本 添加到.angular.json文件中

{
     
  "apps": [
    {
     
      "assets": [
        {
      "glob": "**/*", "input": "../node_modules/ngx-monaco-editor/assets/monaco", "output": "./assets/monaco/" }
      ],
      ...
    }
    ...
  ],
  ...
}

Angular 模块文件中配置 MonacoEditorModule

import {
      BrowserModule } from '@angular/platform-browser';
import {
      NgModule } from '@angular/core';
import {
      FormsModule } from '@angular/forms';

import {
      AppComponent } from './app.component';
import {
      MonacoEditorModule } from 'ngx-monaco-editor';

@NgModule({
     
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    MonacoEditorModule.forRoot() // use forRoot() in main app module only.
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {
     
}

页面使用tab标签页实现HTML、JS、CSS 多个代码编辑器切换

<nz-tabset>
  <nz-tab nzTitle="HTML">
    <ngx-monaco-editor [options]="htmlEditorOptions" [(ngModel)]="htmlCode">ngx-monaco-editor>
  nz-tab>
  <nz-tab nzTitle="JAVASCRIPT">
    <ngx-monaco-editor [options]="jsEditorOptions" [(ngModel)]="jsCode">ngx-monaco-editor>
  nz-tab>
  <nz-tab nzTitle="CSS">
    <ngx-monaco-editor [options]="cssEditorOptions" [(ngModel)]="cssCode">ngx-monaco-editor>
  nz-tab>
nz-tabset>

我以为这样就可以完美展示三个编辑器了,可现实往往是让人头痛的
使用微软Monaco Editor 编写在线调试工具_第1张图片
在 tabs 中添加多个实例竟然不行,于是我尝试着不放在tabs中实现,结果却是可以的。
初步估计是加载顺序的问题,于是我把每个 ngx-monaco-editor 标签 封装成了组件,修整了一下数据获取逻辑,完整代码如下:

<div nz-row [nzGutter]="16">
  <div nz-col class="gutter-row code-view" [nzSpan]="12">
    <nz-tabset [nzAnimated]="true" [nzTabBarExtraContent]="extraTemplate">
      <nz-tab [nzTitle]="htmlTitleTemplate" (nzDeselect)="onDeselect()">
        <ng-template nz-tab>
          <code-view-eagerly #htmlCodeEagerly [(code)]="htmlCode" [options]="htmlEditorOptions">code-view-eagerly>
        ng-template>
        <ng-template #htmlTitleTemplate> <i nz-icon [nzIconfont]="'iconHTML'">i>HTMLng-template>
      nz-tab>
      <nz-tab [nzTitle]="jsTitleTemplate" (nzDeselect)="onDeselect()">
        <ng-template nz-tab>
          <code-view-eagerly #jsCodeEagerly [(code)]="jsCode" [options]="jsEditorOptions">code-view-eagerly>
        ng-template>
        <ng-template #jsTitleTemplate> <i nz-icon [nzIconfont]="'iconJS'">i>JAVASCRIPTng-template>
      nz-tab>
      
        <ng-template nz-tab>
          <code-view-eagerly #cssCodeEagerly [(code)]="cssCode" [options]="cssEditorOptions">code-view-eagerly>
        ng-template>
        <ng-template #cssTitleTemplate> <i nz-icon [nzIconfont]="'iconCSS'">i>CSSng-template>
      nz-tab>
    nz-tabset>
    <ng-template #extraTemplate>
      <button nz-button nzType="primary" (click)="runAllCodes()">运行代码button>
    ng-template>
  div>
  <div nz-col class="gutter-row" [nzSpan]="12">
    <iframe class="view-panel" id="preview" frameborder="0">iframe>
  div>
div>
import {
      THIS_EXPR } from '@angular/compiler/src/output/output_ast';
import {
      Component, forwardRef, Input, OnInit, Output, ViewChild } from '@angular/core';
import {
      ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';

@Component({
     
  selector: 'app-code-view',
  templateUrl: './code-view.component.html',
  styleUrls: ['./code-view.component.less']
})
export class CodeViewComponent implements OnInit {
     
  //html
  htmlEditorOptions = {
     
    theme: "vs-dark",
    language: "html",
  };
  htmlCode: string = '';

  //javascript
  jsEditorOptions = {
     
    theme: "vs-dark",
    language: "javascript",
  };
  jsCode: string;

  //javascript
  cssEditorOptions = {
     
    theme: "vs-dark",
    language: "css",
  };
  cssCode: string;

  @ViewChild('htmlCodeEagerly') htmlCodeEagerly: CodeViewEagerlyComponent;
  @ViewChild('jsCodeEagerly') jsCodeEagerly: CodeViewEagerlyComponent;
  @ViewChild('cssCodeEagerly') cssCodeEagerly: CodeViewEagerlyComponent;

  ngOnInit() {
     
  }

  onDeselect() {
     
    if(this.htmlCodeEagerly!=undefined)
    {
     
      this.htmlCode = this.htmlCodeEagerly.getCode();
    }
    if(this.jsCodeEagerly!=undefined)
    {
     
      this.jsCode = this.jsCodeEagerly.getCode();
    }
    if(this.cssCodeEagerly!=undefined)
    {
     
      this.cssCode = this.cssCodeEagerly.getCode();
    }
  }

  runAllCodes() {
     
    this.onDeselect();
    console.log(this.htmlCode, this.cssCode, this.jsCode)
    var html = this.htmlCode;
    var css = this.cssCode;
    var js = this.jsCode;

    var code = "\n" +
      "\n" +
      "\n" +
      "  \n" +
      "  Editor\n" +
      "  \n" +
      "\n" +
      "\n";
    code += "\n" + html;

    code +=
      "\n  
                    
                    

你可能感兴趣的:(Angular,angular,Monaco,Editor,ng-zorro,在线调试)