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

如何提取Monaco库的代码格式化功能实现多语言代码格式化?

提取Monaco内置代码格式化功能(无需编辑器实例)

我需要格式化多种语言的代码,目前使用HTML、CSS、JS三个不同的大型库来实现,为减少冗余代码,希望借助已在使用的Monaco库内置的代码格式化功能,实现如下函数:

function getFormattedCode(code, mimeType/fileExtension) { ... }

但目前的实现存在诸多问题,需要较长延迟,还会不必要地修改编辑器的实际HTML结构,现有代码如下:

const editor = monaco.editor.create(document.getElementById("container"));

function format(code, fileName) {
    return new Promise(resolve => {
        const model = monaco.editor.createModel(
            code,
            undefined,
            monaco.Uri.file(fileName),
        );

        editor.setModel(model);
        setTimeout(() => {
            editor.getAction("editor.action.formatDocument").run();
            
            setTimeout(() => resolve(model.getValue()), 500);
        }, 100);
    });
}

!async function () {
    alert(await format("x=1", ".js"));
}();

解决方案

可以直接利用Monaco的模型API和内置格式化器,无需创建实际编辑器实例,避免DOM操作和延迟等待。核心是通过创建独立模型,调用其format方法获取编辑操作并应用,最终提取格式化后的代码。

完整实现代码:

async function getFormattedCode(code, identifier) {
    // 根据扩展名或MIME类型确定语言ID
    let language;
    // 优先尝试通过文件名(扩展名)获取语言
    const uri = monaco.Uri.file(identifier);
    language = monaco.editor.getModelLanguage(uri);
    // 如果扩展名匹配失败,尝试通过MIME类型获取
    if (!language) {
        language = monaco.languages.getLanguageIdByMimeType(identifier);
    }

    if (!language) {
        throw new Error(`不支持的语言:${identifier}`);
    }

    // 创建独立模型,无需关联任何编辑器实例
    const model = monaco.editor.createModel(code, language);

    try {
        // 获取全文档范围的格式化编辑指令
        const fullRange = {
            startLineNumber: 1,
            startColumn: 1,
            endLineNumber: model.getLineCount(),
            endColumn: model.getLineMaxColumn(model.getLineCount())
        };
        // 调用内置格式化器获取编辑操作
        const edits = await model.format(fullRange, {});

        // 将编辑操作应用到模型
        model.pushEditOperations([], edits, () => {});

        // 返回格式化后的代码
        return model.getValue();
    } finally {
        // 销毁模型,释放内存
        model.dispose();
    }
}

// 使用示例
(async () => {
    try {
        // 示例1:JavaScript代码,用扩展名指定语言
        const jsFormatted = await getFormattedCode("x=1;const y =2", ".js");
        console.log(jsFormatted);

        // 示例2:CSS代码,用MIME类型指定语言
        const cssFormatted = await getFormattedCode("body{margin:0;padding:0}", "text/css");
        console.log(cssFormatted);
    } catch (err) {
        console.error(err);
    }
})();

优势说明

  • 完全脱离编辑器实例,不会修改任何DOM结构
  • 基于Promise异步处理,无硬编码延迟,性能更稳定
  • 支持所有Monaco内置支持的语言(HTML、CSS、JS、TS、JSON等)
  • 可通过format方法的第二个参数传入自定义格式化选项(如缩进大小、是否保留换行等),适配不同需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 03:55:29