如何在网页实现 TypeScript 编辑器?
myzbx 2024-12-01 18:30 44 浏览
有的需求需要在网页上写代码。
比如在线执行代码的 playground:
或者在线面试:
如果让你实现网页版 TypeScript 编辑器,你会如何做呢?
有的同学说,直接用微软的 monaco editor 呀:
确实,直接用它就可以,但是有挺多地方需要处理的。
我们来试试看。
npx create-vite
创建个 vite + react 的项目。
安装依赖:
npm install
npm install @monaco-editor/react
这里用 @monaco-editor/react 这个包,它把 monaco editor 封装成了 react 组件。
去掉 main.tsx 里的 index.css
然后在 App.tsx 用一下:
import MonacoEditor from '@monaco-editor/react'
export default function App() {
const code = `import lodash from 'lodash';
function App() {
return <div>guang</div>
}
`;
return <MonacoEditor
height={'100vh'}
path={"guang.tsx"}
language={"typescript"}
value={code}
/>
}
跑下开发服务:
npm run dev
试下看:
现在就可以在网页写 ts 代码了。
但是有报错:
jsx 语法不知道怎么处理。
这里明显要改 typescript 的 tsconfig.json。
怎么改呢?
这样:
import MonacoEditor, { OnMount } from '@monaco-editor/react'
export default function App() {
const code = `import lodash from 'lodash';
function App() {
return <div>guang</div>
}
`;
const handleEditorMount: OnMount = (editor, monaco) => {
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
jsx: monaco.languages.typescript.JsxEmit.Preserve,
esModuleInterop: true,
})
}
return <MonacoEditor
height={'100vh'}
path={"guang.tsx"}
language={"typescript"}
onMount={handleEditorMount}
value={code}
/>
}
onMount 的时候,设置 ts 的 compilerOptions。
这里设置 jsx 为 preserve,也就是输入 <div> 输出 <div>,保留原样。
如果设置为 react 会输出 React.createElement("div")。
再就是 esModuleInterop,这个也是 ts 常用配置。
默认 fs 要这么引入,因为它是 commonjs 的包,没有 default 属性:
import * as fs from 'fs';
设置 esModuleInterop 会在编译的时候自动加上 default 属性。
就可以这样引入了:
import fs from 'fs';
可以看到,现在 jsx 就不报错了:
还有一个错误:
没有 lodash 的类型定义。
写 ts 代码没提示怎么行呢?
我们也要支持下。
这里用到 @typescript/ata 这个包:
ata 是 automatic type acquisition 自动类型获取。
它可以传入源码,自动分析出需要的 ts 类型包,然后自动下载。
我们新建个 ./ata.ts,复制文档里的示例代码:
import { setupTypeAcquisition } from '@typescript/ata'
import typescriprt from 'typescript';
export function createATA(onDownloadFile: (code: string, path: string) => void) {
const ata = setupTypeAcquisition({
projectName: 'my-ata',
typescript: typescriprt,
logger: console,
delegate: {
receivedFile: (code, path) => {
console.log('自动下载的包', path);
onDownloadFile(code, path);
}
},
})
return ata;
}
安装用到的包:
npm install --save @typescript/ata -f
这里就是用 ts 包去分析代码,然后自动下载用到的类型包,有个 receivedFile 的回调函数里可以拿到下载的代码和路径。
然后在 mount 的时候调用下:
const ata = createATA((code, path) => {
monaco.languages.typescript.typescriptDefaults.addExtraLib(code, `file://${path}`)
})
editor.onDidChangeModelContent(() => {
ata(editor.getValue());
});
ata(editor.getValue());
就是最开始获取一次类型,然后内容改变之后获取一次类型,获取类型之后用 addExtraLib 添加到 ts 里。
看下效果:
有类型了!
写代码的时候用到的包也会动态去下载它的类型:
比如我们用到了 ahooks,就会实时下载它的类型包然后应用。
这样,ts 的开发体验就有了。
再就是现在字体有点小,明明内容不多右边却有一个滚动条:
这些改下 options 的配置就好了:
scrollBeyondLastLine 是到了最后一行之后依然可以滚动一屏,关闭后就不会了。
minimap 就是缩略图,关掉就没了。
scrollbar 是设置横向纵向滚动条宽度的。
theme 是修改主题。
return <MonacoEditor
height={'100vh'}
path={"guang.tsx"}
language={"typescript"}
onMount={handleEditorMount}
theme: "vs-dark",
value={code}
options={
{
fontSize: 16,
scrollBeyondLastLine: false,
minimap: {
enabled: false,
},
scrollbar: {
verticalScrollbarSize: 6,
horizontalScrollbarSize: 6,
}
}
}
/>
好多了。
我们还可以添加快捷键的交互:
默认 cmd(windows 下是 ctrl) + j 没有处理。
我们可以 cmd + j 的时候格式化代码。
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyJ, () => {
editor.getAction('editor.action.formatDocument')?.run()
});
试下效果:
有同学可能问,monaco editor 还有哪些 action 呢?
打印下就知道了:
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyJ, () => {
// editor.getAction('editor.action.formatDocument')?.run()
let actions = editor.getSupportedActions().map((a) => a.id);
console.log(actions);
});
有 131 个:
用到再搜就行。
这样,我们的网页版 TypeScript 编辑器就完成了。
总结
有的需求需要实现网页版编辑器,我们一般都用 monaco editor 来做。
今天我们基于 @monaco-editor/react 实现了 TypeScript 编辑器。
可以在 options 里配置滚动条、字体大小、主题等。
然后 onMount 里可以设置 compilerOptions,用 addCommand 添加快捷键等。
并且我们基于 @typescript/ata 实现了自动下载用到的 ts 类型的功能,它会扫描代码里的 import,然后自动下载类型,之后 addExtraLib 添加到 ts 里。
这样在网页里就有和 vscode 一样的 ts 编写体验了。
原文链接:https://juejin.cn/post/7361934843209777152
相关推荐
- 首次被击毁!低调但先进的S-350,为何活得比韩国仿版差这么多?
-
【军武次位面】作者:乐乐2月18日,乌克兰军方网站发布了其前线炮兵侦察旅,在顿涅茨克地区攻击俄军S-350防空系统的现场视频。这也是这款地位独特的先进防空系统,第一次确认在战场上被摧毁——考虑到近三年...
- Windows 10 LTSC 2021 vs 2019:哪个更适合你?
-
本内容来源于@什么值得买APP,观点仅代表作者本人|作者:闪电神龙微软近日发布了2024年11月份ISO镜像,包括Windows1124H2、Windows1022H2以及Server2025...
- 叛变投敌?俄军最先进隐身无人机S-70,在乌东上空被苏-57击落!
-
【军武次位面】作者:天狼2024年10月5日,乌克兰东部战区传来一条令人震惊的消息:一架俄罗斯最先进的隐身无人机S-70“猎人-B”在乌东上空被击落,令人意外的是,击落它的竟然是俄罗斯自己的战斗机。这...
- 自动驾驶车祸致1死1伤!特斯拉被判赔偿2.43亿美元
-
当地时间8月1日,美国佛罗里达州一个陪审团裁定,美国电动汽车制造商特斯拉应为2019年一辆配备自动驾驶系统的ModelS所致的致命车祸承担部分责任,并判令该公司向一名遇难女性的家属及一名伤者支付约2...
- HP488DZ 无绳电锤钻(18V)牧田DTD156SFJ
-
HP488DZ无绳电锤钻(18V)牧田DTD156SFJHP488DZ无绳电锤钻(18V)HP488DZ特征HP488D是一款基于HP457D开发的无绳电锤,采用18V锂离子电池供电。其...
- FJK-SJRFPZS防爆阀位行程开关级
-
解答常见误区在工业自动化和安全控制领域,FJK-SJRFPZS防爆阀位行程开关等级是一个关乎设备安全与运行效率的重要参数。许多用户在选择和应用这类开关时,可能对其等级分类存在一些误解。本文将通过通俗易...
- China's PLA aerobatic team to perform in Thailand for 50th anniversary of bilateral diplomatic ties
-
TIANJIN,March2(Xinhua)--TheBayiAerobaticTeamoftheChinesePeople'sLiberationArmy(PLA)A...
- JD.com Enters Travel and Hospitality With Supply Chain-Focused Strategy
-
TMTPOST--JD.comhasofficiallythrownitshatintoChina’sfiercelycompetitivetravelandhospita...
- JD.com Drives Robotics Funding Frenzy With Investments in LimX Dynamics, Spirit AI, and EngineAI
-
TMTPOST--JD.comisdoublingdownonembodiedintelligence,catalyzinganewwaveoffundinginChi...
- JD.com opens first JD Mall in Beijing, steps up offline retail push
-
bySongJiananJD.comhaslauncheditsfirstJDMALLinBeijing,expandingitsofflineretailfootpr...
- JD.com's food delivery fleet tops 120,000 full-time riders
-
JD.com'sfull-timefooddeliveryfleethassurpassed120,000ridersandisexpectedtoexceed150,00...
- China willing to share military equipment achievements with friendly countries: defense ministry
-
BEIJING,July8(Xinhua)--Chinahasalwaystakenaprudent,responsibleapproachtomilitaryexpor...
- FJK-SJRFPZS防爆阀位行程开关等级
-
解答常见误区在工业自动化和安全控制领域,FJK-SJRFPZS防爆阀位行程开关等级是一个关乎设备安全与运行效率的重要参数。许多用户在选择和应用这类开关时,可能对其等级分类存在一些误解。本文将通过通俗易...
- JD's 618 Festival Smashes Records as AI Powers Next-Gen Retail Engine
-
AsianFin–JD.com’s2025“618ShoppingFestival”wrappedupwithrecord-breakingmomentum,drivenby...
- JD’s Food Delivery Blitz Shakes Meituan as Founder Wang Xing Vows to Win at All Costs
-
Credit:CFPAsianFin--JD.comInc.isturninguptheheatinChina'sfooddeliverywars,andfounder...
- 一周热门
- 最近发表
-
- 首次被击毁!低调但先进的S-350,为何活得比韩国仿版差这么多?
- Windows 10 LTSC 2021 vs 2019:哪个更适合你?
- 叛变投敌?俄军最先进隐身无人机S-70,在乌东上空被苏-57击落!
- 自动驾驶车祸致1死1伤!特斯拉被判赔偿2.43亿美元
- HP488DZ 无绳电锤钻(18V)牧田DTD156SFJ
- FJK-SJRFPZS防爆阀位行程开关级
- China's PLA aerobatic team to perform in Thailand for 50th anniversary of bilateral diplomatic ties
- JD.com Enters Travel and Hospitality With Supply Chain-Focused Strategy
- JD.com Drives Robotics Funding Frenzy With Investments in LimX Dynamics, Spirit AI, and EngineAI
- JD.com opens first JD Mall in Beijing, steps up offline retail push
- 标签列表
-
- HTML 简介 (30)
- HTML 响应式设计 (31)
- HTML URL 编码 (32)
- HTML Web 服务器 (31)
- HTML 表单属性 (32)
- HTML 音频 (31)
- HTML5 支持 (33)
- HTML API (36)
- HTML 总结 (32)
- HTML 全局属性 (32)
- HTML 事件 (31)
- HTML 画布 (32)
- HTTP 方法 (30)
- 键盘快捷键 (30)
- CSS 语法 (35)
- CSS 轮廓宽度 (31)
- CSS 谷歌字体 (33)
- CSS 链接 (31)
- CSS 定位 (31)
- CSS 图片库 (32)
- CSS 图像精灵 (31)
- SVG 文本 (32)
- 时钟启动 (33)
- HTML 游戏 (34)
- JS Loop For (32)