Skip to content

[RFC] Monaco Editor Upgrade and CodeEditor Component Changes #9642

Open
@ananzh

Description

@ananzh

Summary

This RFC proposes upgrading the monaco-editor dependency from version 0.17.0 to 0.52.0 in OpenSearch Dashboards. This upgrade will be done in two phases: first to version 0.30.1, and then to version 0.52.0. The upgrade includes significant API changes that affect the CodeEditor component, which is directly accessible to plugins. This RFC outlines the changes, their impact, and provides guidance for plugin developers to adapt to these changes.

Background

OpenSearch Dashboards uses monaco-editor as the foundation for its code editing capabilities. The CodeEditor component, which wraps monaco-editor, is exported from the opensearch_dashboards_react plugin and is used by various plugins throughout the platform. The current version of monaco-editor (0.17.0) is outdated and lacks features and security updates available in newer versions.

The CodeEditor component is directly accessible to plugins via:

import { CodeEditor } from '../../../../../../opensearch_dashboards_react/public';

This means any plugin can import and use the CodeEditor component in the same way. Plugins are encouraged to use our reusable React components rather than creating their own CodeEditor or directly wrapping monaco-editor.

Motivation

  1. Security Updates: Newer versions of monaco-editor include security fixes that address vulnerabilities in the current version.
  2. Feature Enhancements: Newer versions provide improved functionality, performance, and developer experience.
  3. Maintainability: Keeping dependencies up-to-date reduces technical debt and makes future upgrades easier.
  4. Consistency: Ensuring all plugins use the same version of monaco-editor through our CodeEditor component provides a consistent experience.
  5. Improved Suggestion Widget: The newer versions offer better autocompletion capabilities with a more robust suggestion widget.

Proposal

1. Phased Upgrade Approach

We propose a two-phase approach to upgrading monaco-editor:

Phase 1: Upgrade to monaco-editor 0.30.1

This phase includes:

  • Updating the monaco-editor version in package.json from ~0.17.0 to ^0.30.1
  • Adapting to API changes in monaco-editor 0.30.1
  • Updating the CodeEditor component to maintain compatibility with plugins

Phase 2: Upgrade to monaco-editor 0.52.0

This phase includes:

  • Updating the monaco-editor version from ^0.30.1 to ^0.52.0
  • Adapting to further API changes in monaco-editor 0.52.0
  • Ensuring the CodeEditor component remains compatible with plugins

2. Key Changes in monaco-editor 0.30.1

Package Updates

  • Updated monaco-editor version in package.json from ~0.17.0 to ^0.30.1
  • Added new dependencies in packages/osd-monaco/package.json:
    file-loader: ^6.2.0
    style-loader: ^1.1.3
    

Monaco API Compatibility Changes

  • Updated import paths to match new Monaco structure
  • Added CSS import for Monaco editor icons:
    import 'monaco-editor/esm/vs/base/browser/ui/codicons/codicon/codicon.css';
    • In Monaco 0.17.0, icons were implemented using image sprites and CSS classes bundled directly into the editor's core CSS
    • In Monaco 0.30.1, the editor switched to using the "Codicon" icon system, a custom font-based icon library
  • Updated method calls (e.g., from model.getModeId() to model.getLanguageId())
  • Added webpack configuration for handling CSS and font files
  • Added aliases for Monaco 0.30.1 paths in webpack configuration

Test Environment Setup

  • Created a new Monaco mock file for Jest tests to handle Monaco editor initialization differences
  • Updated Jest configuration to handle Monaco editor in tests
  • Added window.matchMedia mock for tests

UI and Styling Updates

  • Updated CSS for suggestion widget
  • Implemented a custom status bar for the suggestion widget, later replaced with Monaco's built-in status bar
  • Updated editor options:
    • Replaced wordBasedSuggestions: false with suggest: { showWords: false }
    • Added additional suggestion configuration options:
      suggest: {
        snippetsPreventQuickSuggestions: false,
        filterGraceful: false,
        showWords: false,
        showStatusBar: true, // Enable the built-in status bar
      }

API Updates

  • Updated function signatures for completion providers:
    • Added context and token parameters to provideCompletionItems:
      // Old signature
      provideCompletionItems: (model, position) => { ... }
      
      // New signature
      provideCompletionItems: (model, position, context, token) => { ... }
    • Updated return types for signature help providers
    • Added cancellation token handling

3. Key Changes in monaco-editor 0.52.0

CodeEditor Component Changes

  • Updated the react-monaco-editor component API:
    • Explicitly passing properties like defaultValue, overrideServices
    • Added default values for width and options to maintain compatibility with existing snapshot tests

Worker Implementation Changes

  • Redesigned worker architecture:
    • Implemented simplified worker implementations with basic message handlers
    • Updated how language services are loaded (now on-demand)
    • The worker architecture was significantly redesigned, requiring placeholders that establish the required worker interface

MonacoEnvironment Configuration Changes

  • Changed the getWorker function signature:
    • From: (module: string, languageId: string)
    • To: (workerId: string, label: string)
  • Added a fallback worker for robustness when monaco-editor requests a worker for a language or service without a specific implementation

Import Path Changes

  • Updated import paths to include /browser/ in their structure, reflecting monaco-editor's internal reorganization

4. Impact on Plugins

For plugins that use the CodeEditor component from OpenSearch Dashboards:

  • No changes required: Plugins using the CodeEditor component as provided by OpenSearch Dashboards should continue to work without modifications.
  • Benefits: Plugins will automatically benefit from the improved features and security updates in the newer monaco-editor versions.

For plugins that directly use monaco-editor or extend the CodeEditor component:

  • API Adaptations: Plugins may need to update their code to adapt to the new monaco-editor API.
    • Update completion provider signatures to include context and token parameters
    • Update import paths to include /browser/ where necessary
    • Update method calls (e.g., from getModeId() to getLanguageId())
  • Worker Configuration: Custom workers will need to be updated to match the new worker architecture.
  • Suggestion Widget Configuration: If plugins customize the suggestion widget, they'll need to update to the new configuration options.

5. Monaco Editor API Considerations

The monaco-editor library uses a 0.x.y versioning scheme (currently at 0.52.0), which according to Semantic Versioning principles indicates that its API is not considered stable and may change at any time without a major version bump. Microsoft has intentionally maintained this versioning despite monaco-editor being a mature and widely-used library.

Currently, the CodeEditor component's Props interface directly exposes monaco-editor types:

export interface Props {
  // ...
  options?: monaco.editor.IEditorConstructionOptions;
  suggestionProvider?: monaco.languages.CompletionItemProvider;
  signatureProvider?: monaco.languages.SignatureHelpProvider;
  hoverProvider?: monaco.languages.HoverProvider;
  languageConfiguration?: monaco.languages.LanguageConfiguration;
  editorDidMount?: (editor: monaco.editor.IStandaloneCodeEditor) => void;
  // ...
}

This means that monaco-editor's APIs are part of the CodeEditor's public contract. However, given monaco-editor's versioning scheme, we should not consider these APIs as part of our stable public contract.

Short-term Approach

For this upgrade, we will:

  1. Document API Changes: Provide detailed documentation of the API changes between monaco-editor 0.17.0 and 0.52.0.
  2. Maintain Compatibility: Ensure that the CodeEditor component continues to work with existing plugin code where possible.
  3. Provide Migration Guidance: Offer clear guidance for plugin developers who need to adapt to the new monaco-editor API.

Long-term Approach

In future releases, we plan to:

  1. Create a Stable Abstraction Layer: Develop OpenSearch Dashboards-specific interfaces that wrap monaco-editor types.
  2. Refactor the CodeEditor Component: Update the Props interface to use these new OpenSearch Dashboards-specific types.
  3. Maintain Backward Compatibility: Ensure a smooth transition for plugin developers.

This approach will allow us to upgrade monaco-editor without breaking the public API contract, while still providing all the functionality that plugin developers need.

6. Implementation Plan

  1. Phase 1 Implementation: Upgrade to monaco-editor 0.30.1

    • Update package.json dependencies
    • Implement necessary changes to adapt to the new API
    • Update the CodeEditor component
    • Update tests and ensure compatibility
  2. Phase 2 Implementation: Upgrade to monaco-editor 0.52.0

    • Update package.json dependencies
    • Implement necessary changes to adapt to the new API
    • Update the CodeEditor component
    • Update tests and ensure compatibility
  3. Documentation: Update documentation to reflect the changes and provide guidance for plugin developers.

  4. Communication: Inform the community and plugin developers about the changes and provide support during the transition.

Feedback Required

We are seeking feedback on:

  1. The phased approach to upgrading monaco-editor
  2. The impact on plugins and any concerns about backward compatibility
  3. Additional considerations for ensuring a smooth transition
  4. Any specific use cases or requirements that should be addressed during the upgrade

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions