The typescript compiler is written by typescript, so it can be run on the browser side. Monaco-editor is an ide editor kernel that can be run on the web side. Therefore, the front-end code development + compilation can be implemented on the browser side without server support.
It is more convenient to develop some simple H5/RN pages, implement SDK business library playground function, encapsulate business logic support special modules such as editor integrated internal login system, and realize one-click release and deployment of uploading resources by calling cloud services.
The vscode architecture diagram is as follows: It is composed of built-in type definition, multi-platform initiator and vscode core layer. The vscode core layer consists of the following parts: -base layer basic layer: provides common basic tools and user interfaces -platform layer platform layer: provides service injection capabilities and basic services -UI layer of workbench layer interface: UI module is implemented by Electron. -editor layer editor layer: monaco-editor Monaco-editor was originally implemented as the editor layer at the core of vscode, and later became independent.
Need to install monaco-editor and monaco-editor-webpack-plugin at the same time
yarn add monaco-editor
yarn add monaco-editor-webpack-plugin -D
Monaco-editor-webpack-plugin needs to be configured to webpack plugins.
Editor is an editor that supports code highlighting, syntax hints / checks, command panels, etc., which is basically the same as the vscode code editor. Create an editor:
// 使用 `monaco.editor.create` 来创建一个编辑器,
const editor = monaco.editor.create(document.querySelector('#root'), {
value: "function hello() {\n\talert('Hello world!');\n}",
language: 'javascript',
})
This only supports editing of one file. If you want to implement tabs of multiple files such as vscode, you need to use model:
// 使用 `monaco.editor.createModel` 来创建一个model
// 每个文件都需要创建一个这样的model
const fileModel = monaco.editor.createModel(
"function hello() {\n\talert('Hello world!');\n}",
undefined, // language. infer from uri ext.
monaco.Uri.file('main.js')
)
// 将model设置到editor
const editor = monaco.editor.create(document.querySelector('#root'), {
model: fileModel,
wordWrap: 'on', // 代码超过屏幕显示自动换行
})
Editor can also switch model (the currently edited file), that is, the tab switch of vscode
// 使用setModel切换当前编辑的文件
editor.setModel(fileModel2)
Here's the setModel docking vscode side explorer file tree click File Edit.
const originalFileModel = monaco.editor.createModel(
"console.log('hello')",
'javascript'
)
const modifiedFileModel = monaco.editor.createModel(
"console.log('hello world')",
'javascript'
)
Then create a diff editor:
const diffEditor = monaco.editor.createDiffEditor(container)
diffEditor.setModel({
original: originalFileModel,
modified: modifiedFileModel,
})
// 创建一个tsx文件
const fileModel = monaco.editor.createModel(
'const App = () => <div>hello</div>',
undefined, // language. infer from uri ext.
monaco.Uri.file('main.tsx')
)
// 获取ts编译器
monaco.languages.typescript.getTypeScriptWorker().then(async tsWorker => {
const client = await tsWorker(fileModel.uri)
// 获取文件编译后的内容
const result = await client.getEmitOutput(fileModel.uri.toString())
const files = result.outputFiles[0]
return files.text
})
const typescriptDefaults = monaco.languages.typescript.typescriptDefaults
typescriptDefaults.setCompilerOptions({
jsx: monaco.languages.typescript.JsxEmit['React'],
target: monaco.languages.typescript.ScriptTarget['ES5'],
module: monaco.languages.typescript.ModuleKind['AMD'],
allowSyntheticDefaultImports: true,
esModuleInterop: true,
allowJs: true,
experimentalDecorators: true,
emitDecoratorMetadata: true,
downlevelIteration: true,
removeComments: true,
lib: ['dom', 'dom.iterable', 'esnext'],
})
const typescriptDefaults = monaco.languages.typescript.typescriptDefaults
typescriptDefaults.addExtraLib(`declare module "react" { }`, 'react.d.ts')
The amd specification allows you to load module resources from http, such as using requirejs to load axios:
require.config({
paths: {
axios: 'https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js',
},
})
require(['axios'], axios => {
console.log(axios.get)
})
Using monaco-editor to configure tsconfig, you can compile the ts code into the amd module, and then configure the module to load the amd/umd resource http path. The premise is that the npm package you need to use has released the umd version.