百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

如何在网页实现 TypeScript 编辑器?

myzbx 2024-12-01 18:30 12 浏览

有的需求需要在网页上写代码。

比如在线执行代码的 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

相关推荐

魔兽WLK:P2牌子装机制详解,232装备直接拿,肯瑞托戒指成真BIS

魔兽世界WLK怀旧服P2阶段即将开放,虽然国服只能体验3天时间,但是鉴于绝大部分玩家都认为国服未来还有重新开放的希望,因此在这3天时间内也可以收集一些非常不错的装备,下面胖哥就和大家分享一下P2阶段牌...

PDD旗下的小马是谁,有多强,你们知道吗?

lol国服最强王者第一是谁?曾经的国服大神区艾欧尼亚迎来了一位18岁王者第一,王者1600胜点,堪称国服史上最高,18岁少年登顶LOL国服第一,lol马彦毅个人资料及id段位介绍。1600胜点,国服史...

Vorsteiner Wheels改装蓝色奥迪S5

当你想到奥迪S5,那么你就想象一种结合性能和豪华优雅的运动跑车。由于车辆低调的设计,将很难再叫S5'大胆'或'古怪'。下面的S5,Vorsteiner最近插手但肯定是这两件事情。毫无疑问,最值得关注...

英雄联盟S6排位奖励徽章曝光 质感十足

近日,英雄联盟客户端再次迎来更新,官方曝光了青铜到最强王者8个段位的徽章,看起来非常精致和形象。从无段位的黄色圆环到金色的王者边框,段位越高光泽和款式也更加华丽丰富。不同于以往"展翼"的形象,圆环...

Apple Watch Series 5外观与上代相同,内部构造呢?

集微网消息(文/叶子),苹果今年更新的AppleWatchSeries5在整体外观上延续了上一代的设计,依旧是传统的方形表盘设计,采用40mm/44mm表盘。既然外观没有太大变化,那内部结构呢?...

教你如何连接Gear 三星GALAXY Tab S教程

平板电脑和智能手表是当前两大热门的数码产品,智能穿戴设备也成为今年各大IT厂商下大力气推广的领域,尤其是智能手表异常火热。三星旗下Gear智能手表已经推出了第二代产品,无论是做工品质还是软件功能以及交...

试试这个,你的三星S5/Note4能更快

IT之家(www.ithome.com):试试这个,你的三星S5/Note4能更快想到三星手机,大家脑海中免不了出现Galaxy,这个系列的三星手机颇受欢迎,同时也是三星的旗舰系列。当然这个系列的手机...

Surface Book详细拆解:千万不要自己动手修

微软或许打造了世界上最好的笔记本之一——SurfaceBook,如果你购买了SurfaceBook,我们为你拥有这样一款优秀的笔记本而开心,不过,我们也为你要维修这样一款笔记本而担忧,奉劝你最好不...

蒂升电梯蒂森UCMP轿厢移动测试及复位方法

蒂升电梯蒂森UCMP轿厢移动测试及复位方法UCMP功能测试一、轿厢上行制停距离测试注意空载状态下1、将电梯轿箱停靠在次高层平层位置2、按下主板锁门按钮(MC1∶S4在MZ1、MC2∶S804按钮),将...

18张图!看懂六代三星GALAXY S的改变

从2010年的第一代三星GALAXYS,到2015年的第六代三星GALAXYS6,五年的时间,三星GALAXYS系列经历了六代的更迭,你还能记得第一代产品的样子吗?你还能记得每一代产品的配置吗?...

芯片级电脑维修,需掌握的20个信号,学懂后常见的故障不用求人

很大小白都知道,做技术的每个人都希望把相关的电路与相关的时序全部搞懂,对于大多数的信号名称与作用都不是很了解决,在这里我列出的部分主要的信号名称给大家参考,如果大家觉得有用的话建议大家可以学习与收芯片...

终于还是入了全画幅——松下S5(20-60/50mm)双镜头套装开箱

一、简单开箱视频开箱视频二、购买过程用了一年多的ZV-E10,其实主要用处还是给小孩拍日常记录照片。虽然ZV-E10是一台偏向视频的机器,真正实操体验过后才会知道视频上手难度比拍照大多了,想要观感不...

京张高铁昌平北站项目部开展安全生产警示教育活动

6月20日,中铁六局建安公司安在京张高铁昌平北站项目部开展安全生产警示教育活动。千龙网发千龙网北京6月21日讯(记者李贺)“看了这些案例,有些安全事故还是可以避免的,如果稍加小心,就不会造成工地意外...

深圳男子微博举报高速被恶意别车,视频却让网友炸了:坑老婆?

再过几天就是春节而春运大潮早已经开始每年一到这个时候总有一些小伙伴商量着自驾回家而说到自驾出行驾驶在高速公路上各位司机总有一箩筐的"槽"要吐其他的不多说光是恶意别车这一项就足够令各位老司机们心累了这不...

开车慢也违法?高速路上低速行驶,贵阳交警开出罚单!

平时一直强调的是“杜绝飙车”“小心不要超速!”“开快车很危险”然而也许有不少朋友或者不清楚低速行驶也违法!案例一近日,贵阳交警高速一大队民警巡逻时发现,一辆号牌为贵A8**S5号轻型货车沿兰海高速公路...