如何提取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
相关产品推荐
相关产品推荐

