前言
我查過網上的教程,大部分都是基於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 在使用這個編輯器過程中,博主前前後後折騰了好久,特別是那個莫名添加路徑和漢化這兩點上,花費了很多的時間。百度過谷歌過都沒有找到解決方案。不過幸好,最終還是做到自己想要的效果了。在此感謝上述涉及的插件模塊的開發者。