在webpack中使用monaco-editor

前言

我查過網上的教程,大部分都是基於vue或者react框架,很少有教程是基於純粹的webpack來的,這篇文章記錄我在webpack上使用monaco-editor的過程,以補充網上在這方面資料的缺失。本文章會根據我的開發隨時進行更新。

使用

monaco的使用介紹,網上有很多,大家可以參考這篇文章進行大概的瞭解。

點擊跳轉

自己總結的使用過程

1、安裝。

npm install monaco-editor -save

2、在頁面中使用

在HTML中創建一個容器,然後使用下面的代碼進行初始化就可以得到一個在線編輯器了,但是現在這個編輯器也只是編輯器,什麼輔助功能都沒有,比如代碼提示、右鍵菜單等等。

import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
const monacoInstance=monaco.editor.create(document.getElementById("monaco"),{
            value:`console.log("hello,world")`,
            language:"javascript"
})

效果圖:

3、開啓輔助功能

如何開啓輔助功能,一種是我們根據自己的需要把輔助的文件引入到頁面中,方法參考【使用】章節裏提供的地址,另外一種就是用webpack來實現。

安裝monaco-editor-webpack-plugin這個模塊。

npm install monaco-editor-webpack-plugin

在webpack.config.js中進行配置,MonacoWebpackPlugin可以接受language和features來配置輔助功能,具體配置參數可以查看npm官網即可。

const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
module.exports = {
    ...
    plugins: [
        new MonacoWebpackPlugin()
      ]
}

效果圖如下:

不過這裏有幾點注意的,這是博主在使用過程中發現的一些情況:

1)、如果你得webpack項目使用了HtmlWebpackPlugin來實現多頁面配置,那麼通過monaco-editor-webpack-plugin生成的一些文件的引用路徑將會受到HtmlWebpackPlugin這個配置的影響。例如我使用如下代碼動態配置HTML模板的信息,其中filename不僅可以從命名文件還可以設置其路徑,假設我將filename改爲`pages/${name}.html`,將HTML文件放在pages這個路徑下,那麼monaco-editor-webpack-plugin生成的所有文件在引用的時候都會加上pages這個路徑,原因未知,博主排查了好久都不清楚爲啥,所以只能放在根目錄下。如果有知道的歡迎指出。

var getHtmlConfig = function(name,chunks){
    return {
        template:`./src/app/pages/${name}.html`,
        filename:`${name}.html`,
        inject:true, // 將js資源插入到body元素底部
        hash:false,
        chunks:[name, 'runtime','libs', 'commons']
    }
}

2)、monaco-editor-webpack-plugin參數中filename僅更改worker文件的名字,而無法更改其他生成的JS文件名稱。

3)、MonacoWebpackPlugin的language參數的配置會影響右鍵菜單。經測試:如果language中如果沒有引入typescript,右鍵菜單和控制面板部分功能將消失。

4、如何設置菜單中文顯示效果

這個功能折騰了樓主好久時間。網上也沒有系統的相關資料。不過能在一些文章中零星的看到有人使用下面的代碼進行配置。

 require.config({
        'vs/nls': {
            availableLanguages: {
                '*': 'zh-cn'
            }
        }
    });

可是當你把這段代碼複製到自己的代碼中又發現完全無法執行。那怎麼辦?

這裏需要涉及到另外兩個模塊。monaco-editor-esm-webpack-plugin和monaco-editor-nls。其中monaco-editor-esm-webpack-plugin和上面的monaco-editor-webpack-plugin這個不一樣,前者需要依賴後者,也就是說你要使用前者,就必須先安裝後者。先安裝兩個模塊。

npm install --save monaco-editor-nls
npm install --save-dev monaco-editor-esm-webpack-plugin

改寫webpack.config.js,需要注意的是rules裏也需要添加MonacoWebpackPlugin.loader

// 去除monaco-editor-webpack-plugin,改爲monaco-editor-esm-webpack-plugin

const MonacoWebpackPlugin = require('monaco-editor-esm-webpack-plugin');
module.exports = {
    module: {
        rules: [
            {
				test: /\.js/,
				enforce: 'pre',
				include: /node_modules[\\\/]monaco-editor[\\\/]esm/,
				use: MonacoWebpackPlugin.loader
			},
        ]
    }
    plugins: [
        new MonacoWebpackPlugin()
    ]
}

然後在頁面的JS中添加如下代碼,這些代碼必須添加在引入'monaco-editor/esm/vs/editor/editor.api.js';之前

import { setLocaleData } from 'monaco-editor-nls';
import zh_CN from 'monaco-editor-nls/locale/zh-hans';

setLocaleData(zh_CN);

接着重新編輯文件,你會發現編譯控制檯提示報錯,在monaco-editor/esm/vs/editor/contrib下缺少goToDefinition文件夾。其實還缺少了一個referenceSearch。如何解決?首先說明一下,這兩個文件夾其實並沒有缺少,只是在[email protected]版本以上,微軟把這些文件統一放到了gotoSymbol這個文件夾,你可以把monaco-editor安裝爲0.18.1這個版本就可以使用,不過還是得進行一些插件源代碼修改。如果我一定要安裝@0.20.0怎麼辦,那只需要修改\node_modules\monaco-editor-esm-webpack-plugin\node_modules\monaco-editor-webpack-plugin\features.js這個文件即可。

// 刪除一下代碼
  goToDefinitionCommands: {
    entry: 'vs/editor/contrib/goToDefinition/goToDefinitionCommands',
    worker: undefined,
  },
  goToDefinitionMouse: {
    entry: 'vs/editor/contrib/goToDefinition/goToDefinitionMouse',
    worker: undefined,
  },
    referenceSearch: {
    entry: [
      'vs/editor/contrib/referenceSearch/referenceSearch',
      'vs/editor/standalone/browser/referenceSearch/standaloneReferenceSearch',
    ],
    worker: undefined,
  }

// 新增以下代碼
gotoSymbol:{
	entry: 'vs/editor/contrib/gotoSymbol/goToCommands',
	  worker: undefined
  }

按照上述操作修改後就可以正常編譯了。可是編譯後,你打開項目你會發現菜單什麼還是英文的。這又是啥子情況,明明都按照要求更改了。這個問題我也不清楚是爲啥,不過按照下面的改法就行。在一開始我們引入editor.api.js的時候是使用import進行引入的,只要把它改爲require引入就行。

const monaco = require('monaco-editor/esm/vs/editor/editor.api');
// import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';

const monacoInstance = monaco.editor.create(document.getElementById("monaco"),{
	value: `console.log(123)`,
	contextmenu: true,
	language: 'javascript',
	theme: 'vs-dark'
})

到此菜單漢化就完成了,重新打包運行後效果如下:

 

5、編輯器功能

 1)、動態賦值

monacoInstance = monaco.editor.create(document.getElementById("monaco"),{
		value: ``,
		contextmenu: true,
		language: 'javascript',
		theme: 'vs-dark'
	})
monacoInstance.setValue(res);

2)、動態修改語言

monaco.editor.setModelLanguage(monacoInstance.getModel(), 'html');
monaco.editor.setModelLanguage(monacoInstance.getModel(), 'javascript');

後記:2020年4月23日15:22:48  在使用這個編輯器過程中,博主前前後後折騰了好久,特別是那個莫名添加路徑和漢化這兩點上,花費了很多的時間。百度過谷歌過都沒有找到解決方案。不過幸好,最終還是做到自己想要的效果了。在此感謝上述涉及的插件模塊的開發者。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章