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

如何在AngularJS网站中实现MonacoEditor的懒加载?

AngularJS中懒加载Monaco Editor的实现方案

我来给你分享一个在AngularJS项目中懒加载Monaco Editor的靠谱方案,亲测在老项目中稳定可行~

1. 先移除静态加载的资源

首先把你原来在index.html里直接引入的Monaco相关样式和脚本全部删掉,我们要改成动态按需加载:

移除这些代码:

<link rel="stylesheet" data-name="vs/editor/editor.main" href="/monaco-editor/min/vs/editor/editor.main.css" />
<script src="/monaco-editor/min/vs/loader.js"></script>
<script src="/monaco-editor/min/vs/editor/editor.main.nls.js"></script>
<script src="/monaco-editor/min/vs/editor/editor.main.js"></script>
<script> require.config({ paths: { 'vs': '/monaco-editor/m... </script>

2. 创建单例懒加载服务

AngularJS的服务是单例的,非常适合用来处理资源加载逻辑,避免重复请求。我们创建一个monacoLoader服务来统一管理Monaco的加载:

angular.module('yourApp') // 替换成你的实际应用模块名
.factory('monacoLoader', ['$q', '$document', '$window', function($q, $document, $window) {
  var loadDeferred = $q.defer();
  var isMonacoLoaded = false;

  // 辅助函数:加载样式文件
  function loadStyleSheet(url) {
    const link = $document[0].createElement('link');
    link.rel = 'stylesheet';
    link.href = url;
    $document[0].head.appendChild(link);
  }

  // 核心加载逻辑
  this.load = function() {
    // 如果已经加载过,直接返回已resolved的Promise
    if (isMonacoLoaded) {
      return $q.resolve();
    }

    // 1. 先加载编辑器样式
    loadStyleSheet('/monaco-editor/min/vs/editor/editor.main.css');

    // 2. 加载Monaco的loader脚本
    const loaderScript = $document[0].createElement('script');
    loaderScript.type = 'text/javascript';
    loaderScript.src = '/monaco-editor/min/vs/loader.js';
    
    loaderScript.onload = function() {
      // 3. 配置require路径(这里要和你的Monaco文件路径匹配)
      $window.require.config({
        paths: {
          'vs': '/monaco-editor/min/vs'
        }
      });

      // 4. 通过require加载Monaco主文件(会自动依赖加载editor.main.nls.js)
      $window.require(['vs/editor/editor.main'], function() {
        isMonacoLoaded = true;
        loadDeferred.resolve();
      }, function(error) {
        loadDeferred.reject(`加载Monaco失败:${error}`);
      });
    };

    loaderScript.onerror = function() {
      loadDeferred.reject('加载Monaco loader脚本失败');
    };

    $document[0].body.appendChild(loaderScript);

    return loadDeferred.promise;
  };

  return this;
}]);

3. 用指令封装编辑器组件

接下来创建一个可复用的monacoEditor指令,当指令所在的DOM元素被渲染时,才触发Monaco的加载和初始化:

angular.module('yourApp')
.directive('monacoEditor', ['monacoLoader', function(monacoLoader) {
  return {
    restrict: 'E',
    scope: {
      // 双向绑定编辑器内容
      content: '=',
      // 可选:指定编辑语言,比如javascript、html等
      language: '@?'
    },
    link: function(scope, element) {
      // 设置编辑器容器的基础样式(必须要有宽高)
      element.css({
        width: '100%',
        height: '500px',
        border: '1px solid #eee'
      });

      // 调用加载服务,等待Monaco就绪
      monacoLoader.load().then(function() {
        // 初始化Monaco编辑器
        const editor = monaco.editor.create(element[0], {
          value: scope.content || '',
          language: scope.language || 'javascript',
          theme: 'vs-light' // 可选:指定主题,比如vs-dark
        });

        // 同步scope内容到编辑器
        scope.$watch('content', function(newVal) {
          if (newVal !== editor.getValue()) {
            editor.setValue(newVal);
          }
        });

        // 同步编辑器内容到scope
        editor.onDidChangeModelContent(function() {
          scope.$apply(function() {
            scope.content = editor.getValue();
          });
        });

        // 页面销毁时清理编辑器,避免内存泄漏
        scope.$on('$destroy', function() {
          editor.dispose();
        });
      }).catch(function(error) {
        console.error(error);
        element.html('<p style="padding: 20px; color: #dc3545;">代码编辑器加载失败,请稍后重试</p>');
      });
    }
  };
}]);

4. 在页面中使用编辑器

现在你可以在需要的地方直接使用这个指令,只有当这个DOM元素被渲染时,Monaco才会开始加载:

<!-- 在你的视图模板中 -->
<monaco-editor content="vm.editorContent" language="html"></monaco-editor>

一些注意事项

  • 路径匹配:确保代码中的/monaco-editor/min/vs路径和你项目中Monaco Editor的实际文件路径一致。
  • 容器样式:编辑器容器必须设置宽高,否则Monaco无法正常渲染。
  • 重复加载防护:服务中的isMonacoLoaded标记确保Monaco资源只会被加载一次,即使多个地方调用load()方法。
  • 错误处理:代码中加入了错误捕获逻辑,加载失败时会给用户友好提示。

内容的提问来源于stack exchange,提问作者SoftTimur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:20:57