一个代码在线编辑预览工具,类似codepen
。
在线示例:https://wanglin2.github.io/code-run-online/。
手把手教你实现在Monaco Editor中使用VSCode主题
-
支持多种预处理语言
-
支持多种布局随意切换
-
支持添加额外的
css
、js
资源 -
内置多种常用模板
-
支持导出
zip
-
支持代码格式化
-
美观强大的控制台
-
支持
vue
单文件(2.x、3.x) -
支持直接移植
VSCode
主题,并且已经内置了大量优质主题 -
内置支持保存到github gist【gist API】,想要保存到自己的存储体系修改也十分简单
-
内置支持在未配置github gist的情况下将变动保存到url中,可方便的将url分享给他人查看
-
内置支持生成和carbon一样漂亮美观的代码图片
-
支持嵌入模式,方便在文档网站中使用,让文档示例更轻松
git clone https://github.com/wanglin2/code-run.git
cd code-run
npm i
npm run serve
请先确认打包后应用的基路径,项目默认的基路径为/code-run/
,如果你想换一个,可以按如下步骤修改:
1.修改vue.config.js
文件里的publicPath
字段。
2.修改src/config/index.js
文件的base
字段。
默认的路由模式为hash模式
,如果需要使用history
模式请修改src/config/index.js
文件的routerMode
字段。
另外history模式下如果存在多级路径,可能需要修改以下文件:
1.修改/public/index.html
文件的prettier
相关js
资源的路径;
npm run build
脚手架: Vue CLI
框架:Vue 3.X
全家桶,通过script setup
使用组合式API
UI库:element-plus
代码编辑器:Monaco Editor
目前在JavaScript
、TypeScript
、CoffeeScript
、Vue3
、Vue2
等模式下支持使用ESM
,默认情况下,如果你直接按下列方式导入模块的话:
import moment from 'moment'
最后会转换成:
import moment from 'https://unpkg.com/moment?module'
也就是使用unpkg,但是有些模块unpkg
获取不到ESM
版本,或者直接这样获取到的版本不是我们所期望的,比如导入vue
时,我们需要的是https://unpkg.com/[email protected]/dist/vue.esm-browser.js
,但是https://unpkg.com/vue?module
默认返回的是https://unpkg.com/[email protected]/dist/vue.runtime.esm-bundler.js?module
,这个版本无法运行在浏览器上,所以这时候就可以通过手动添加importmap来设置导入模块的来源。
本教程针对迁移VSCode
主题。
1.确定要新增的主题,先在本地VSCode
上安装并切换到该主题,然后按F1
或Command/Control + Shift + P
或鼠标右键点击Command Palette/命令面板
,接着找到并点击Developer:Generate Color Theme From Current Setting/开发人员:使用当前设置生成颜色主题
,然后VSCode
就会生成一份json
数据,保存到项目的/scripts/vscodeThemes/
目录下。
2.然后命令行执行命令npm run convertTheme
,转换后的主题会被输出到项目的/public/themes
目录下,接下来再执行命令npm run createThemeList
即可生成主题配置,接下来即可在设置->主题设置里看到所有主题,并可以切换使用
。
-
npm run buildConsole
:编译项目的/public/console/index.js
文件为ES5
语法,输出到同目录下的compile.js
,该文件会在页面预览的iframe
里进行加载,请勿直接修改compile.js
文件。 -
npm run buildMonacoWorker
:打包Monaco Editor
编辑器的worker
文件,如果使用的Monaco Editor
编辑器版本变化了需要重新打包。 -
npm run convertTheme
:将VSCode
主题文件转换成Monaco Editor
主题文件。 -
npm run createThemeList
:根据主题文件列表自动生成配置文件。 -
npm run buildVueSFCCompiler
:打包@vue/compiler-sfc
文件,针对Vue3
。
因为本项目是纯前端项目,所以在使用less
、sass
、typescript
等预处理语言或扩展语言时需要在线进行编译,这个工作是由各个语言的编译器处理的,这些编译器你可以在/public/parses/
目录下找到,随着时间的推移,肯定会落后于它们的新版本,所以你需要定期更新它们,获取它们的浏览器使用版本并不是一件易事,所以在这里将有些仅有的经验分享给大家。
less
首先npm i less
,然后在node_modules
找到less/dist/
目录,该目录下的两个文件都是umd
格式的,可以直接使用。
sass
sass
目前使用的是这个项目sass.js,但是这个项目已经三年没有更新了。
babel
babel
提供了浏览器使用版本,具体可以参考官方文档@babel/standalone。
typescript
typescript
直接npm i typescript
,然后找到node_modules/typescript/lib/typescript.js
文件,它也是支持直接在浏览器上使用的。
coffeescript
coffeescript
也是直接npm i coffeescript
,然后找到node_modules/coffeescript/coffeescript-browser-compiler-legacy/coffeescript.js
文件,支持直接在浏览器上使用。
livescript
livescript
的浏览器使用版本可以直接去其官方仓库下载browser,不过也两年没有更新了。
postcss
可以使用Browserify
或 webpack
把它打包到一个文件中。
- 其他
stylus
暂时没有找到浏览器使用版本或编译成功,知道的朋友欢迎提个issue
。
项目内置了几个常用的代码模板,可以根据需要进行增减,模板配置文件在src/config/templates.js
。
项目内置了几个常用的页面布局模板,如果不满足你的需求也可以新增布局,一个布局就是一个vue单文件
,可以在src/pages/edit/layouts/
目录下找到所有布局,每个布局其实就是确定如何显示编辑器
、控制台
、预览
三部分,编辑器
包含js
、css
、html
、vue
四个编辑器,可配置显示哪几个、顺序、是否允许拖动等,需要新增的布局也需要放到该目录下。
接下来以新增一个vue单文件的布局
为例来看,首先确定布局细节,我们想左侧显示一个vue
编辑器,右侧显示预览
和控制台
,预览
模块默认展开,控制台
默认最小化:
1.首先我们在layouts
目录下创建一个VueSFC.vue
。
2.修改src/config/constants.js
文件,引入该组件,并在layoutList
和layoutMap
两个配置上新增该布局:
import VueSFC from '../pages/edit/layouts/VueSFC.vue'
export const layoutList = [
// ...
{
name: 'Vue单文件',
value: 'vue',
}
]
export const layoutMap = {
// ...
vue: VueSFC
}
可以添加一张该布局的预览图片,放置到src/assets/layoutImgs/
目录下,然后在constants.js
文件里引入,最后在previewImgMap
配置上添加即可。
这样修改完后即可在页面的设置
功能里的布局设置
的下拉列表里看到新增的Vue单文件
选项。接下来完善VueSFC.vue
的内容。
3.可参考其他布局结构的内容,复制过来修改,最终的内容应该是这样的:
<template>
<!-- 该容器的直接DragItem直接数量为2,方向水平排列,第一个DragItem直接允许缩小到0,第二个DragItem组件最小允许缩小到20px -->
<Drag :number="2" dir="h" :config="[{ min: 0 }, { min: 20 }]">
<!-- 编辑器块,索引为0,禁止缩放该块,隐藏拖动条 -->
<DragItem :index="0" :disabled="true" :showTouchBar="false">
<!-- 编辑器增加,内部编辑器排列方向为垂直,配置了要显示的编辑器 -->
<Editor dir="v" :showList="showList"></Editor>
</DragItem>
<!-- 预览&控制台,索引为1,允许拖动进行缩放 -->
<DragItem :index="1" :disabled="false">
<!-- DragItem又嵌套了一个容器组件,该容器的直接DragItem直接数量为2,方向垂直排列,第一个DragItem直接允许缩小到0,第二个DragItem组件默认显示的高度为48px,且最小允许缩小到48px -->
<Drag :number="2" dir="v" :config="[{ min: 0 }, { min: 48, default: 48 }]">
<DragItem
:index="0"
:disabled="true"
:showTouchBar="false"
title="预览"
>
<Preview></Preview>
</DragItem>
<DragItem :index="1" :disabled="false" title="控制台">
<Console></Console>
</DragItem>
</Drag>
</DragItem>
</Drag>
</template>
<script setup>
import Editor from '@/components/Editor.vue'
import Preview from '@/components/Preview.vue'
import Console from '@/components/Console.vue'
import Drag from '@/components/Drag.vue'
import DragItem from '@/components/DragItem.vue'
import { reactive } from 'vue'
// 配置只显示vue编辑器
const showList = reactive([
{
title: 'VUE',// 编辑器名称
disableDrag: true,// 禁止拖动进行缩放
showTouchBar: false// 隐藏推动条
}
])
</script>
注释已经解释的很详细,详情可参考接下来的组件文档。
该组件相当于是一个容器,每个容器会实例化一个Resize
尺寸拖动调整类,内部需要放置DragItem
组件。
组件props
:
名称 | 介绍 | 类型 | 默认值 |
---|---|---|---|
dir | 容器内部的DragItem 组件排列方式,可选项:h(水平排列)、v(垂直排列) |
String | h |
number | 内部的DragItem 组件数量 |
Number | 0 |
config | 配置内部的DragItem 组件的信息,数组类型,每一项都是一个对象,具体的属性请看表1 |
Array | [] |
config
数组每一项的对象的属性:
名称 | 介绍 | 类型 | 默认值 |
---|---|---|---|
default | 对应索引的DragItem 组件默认显示的尺寸,dir 为h 时指宽度,为v 时指高度 |
Number | 默认容器内的所有DragItem 组件平分空间 |
min | 对应索引的DragItem 组件允许显示的最小尺寸,当发生拖动时,如果该组件空间被挤压,默认允许被压缩到0,即完全不显示,如果配置了该属性,则缩小到配置的大小后不再变化 |
Number | 0 |
max | 对应索引的DragItem 组件允许显示的最大尺寸,当发生拖动时,如果该组件空间被增加,默认会增加到允许的最大尺寸,如果配置了该属性,则增加到配置的大小后不再变化 |
Number | 0 |
该组件代表一个可拖动的块,需要放置在Drag
组件下,通过slot
来传入需要实际显示的内容。DragItem
组件内可再嵌套Drag
容器。
组件props
:
名称 | 介绍 | 类型 | 默认值 |
---|---|---|---|
disabled | 是否禁止拖动 | Boolean | false |
touchBarSize | 拖动条的尺寸,dir 为h 时指宽度,为v 时指高度 |
Number | 20 |
index | 该组件在容器内的同级DragItem 组件列表中的索引,从0开始 |
Number | 0 |
showTouchBar | 是否显示拖动条 | Boolean | true |
title | 标题 | String | |
hide | 是否隐藏该组件 | Boolean | false |
该组件目前包含js
、css
、html
、vue
四个编辑器,可以控制具体显示哪几个,以及它们的排列方式。
组件props
:
名称 | 介绍 | 类型 | 默认值 |
---|---|---|---|
hide | 是否隐藏编辑器 | Boolean | false |
dir | 排布方向,v(垂直)、h(水平) | String | h |
showList | 要显示的编辑器列表,数组类型,每一项可以是数字也可以是一个对象,见表2 | Array | ['HTML', 'CSS', 'JS'] |
showList
数组的每一项可以是一个字符串,可选值为:HTML
、 CSS
、 JS
、VUE
,代表四种编辑器,配置了哪几个就显示哪几个。
如果需要再配置一些属性,比如是否允许该编辑器拖动等等,可配置的属性如下:
名称 | 介绍 | 类型 | 默认值 |
---|---|---|---|
title | 编辑器名称,可选项:HTML 、 CSS 、 JS 、VUE |
String | |
disableDrag | 是否禁止拖动缩放该编辑器 | Boolean | |
showTouchBar | 是否显示该编辑器的推动条 | Boolean |
1.生成代码图片功能偶尔生成的图片高度超出了代码实际的高度,目前暂未找到原因及根本解决方法。可选方法之一为生成图片后再提供一个图片裁剪的功能。
2.极少数情况下会出现主题不生效的问题。
本项目中预处理/扩展语言的编译部分、其他一些细节有参考了项目codepan的实现。