实现一个基础版的vscode(web版本)

469 阅读3分钟

开发背景

最近在MDN上看file相关的api,发现,现在js真的很强大,都可以在网页进行文件(夹)的增删改查了。我想着,反正也大概看了一遍,索性写个基础的项目,也算巩固知识了不是,所以我就瞄准了vscode,毕竟天天用这东西,废话不多话,开整。

项目部分截图

  1. 创建文件 index.png
  2. 创建文件夹 folder.png
  3. 查看vue文件 vue.png
  4. 查看tsx文件 vscode截图.png
  5. 预览图片 pngg.png

项目目标

  1. 对文件夹进行常规增删改查。
  2. js/json/vue/ts/tsx/jsx/html/css/sass/less等文件进行常规增删改查。
  3. png/jpeg/svg+xml/webp等图片资源的预览。

文件夹的增删改查

要想对文件夹进行增删改查,首先就是先要选择本地目录,这里需要调用我们的file系统提供的 showDirectoryPicker方法,因为我们要进行读写操作,所以需要传递参数showDirectoryPicker({ mode: 'readwrite' }),调用如下图:

vue.png 01.png

读取文件夹

    showDirectoryPicker({ mode: 'readwrite' }).then(async (res) => {
    let result = []
    for await (const [key, value] of res.entries()) {
    result.push(value)
    }
    })

result就是我们获取juejin目录下的文件和文件夹,如下图(antdtree组件):

Snipaste_2024-06-23_23-10-12.png

这解释下,图一的showDirectoryPicker({ mode: 'readwrite' }).then((res)),这个res,其实就是一个文件目录的句柄,而这个句柄对象FileSystemDirectoryHandle会提供很多方法,我们其实就是用它提供的方法进行文件夹的新增(getDirectoryHandle)和删除(removeEntry)

新增文件夹

showDirectoryPicker({ mode: 'readwrite' }).then(async (res) => {
try {
await res.getDirectoryHandle('文件夹名称',{create:true})
}catch(error){
console.log('文件夹新增失败',error)
}
})

这段代码,会在你选择的文件夹下,新增一个目录

删除文件夹

showDirectoryPicker({ mode: 'readwrite' }).then(async (res) => {
try {
await res.removeEntry('文件夹名称')
}catch(error){
console.log('文件夹删除失败',error)
}
})

这段代码,会在你选择的文件夹下,删除这个文件夹,至此文件夹相关的就基本写完了。

文件的增删改查

这里我们还是使用showDirectoryPicker来做示例

getFileHandle(新增文件),removeEntry(删除文件),createWritable(修改文件)

新增文件

showDirectoryPicker({ mode: 'readwrite' }).then(async (res) => {
try {
await res.getFileHandle('文件名称',{create:true})
}catch(error){
console.log('文件新增失败',error)
}
})

这段代码,会在你选择的文件夹下,创建一个新的文件

删除文件

showDirectoryPicker({ mode: 'readwrite' }).then(async (res) => {
try {
await res.removeEntry('文件名称')
}catch(error){
console.log('文件删除失败',error)
}
})

这段代码,会在你选择的文件夹下,删除当前文件

修改文件

  const handleSaveFile = async () => {
      [fileHandle] = await showOpenFilePicker()
    try {
      const writableStream = await fileHandle.createWritable()
      await writableStream.write('文件内容')
      await writableStream.close()
    } catch (error) {
      console.log('文件修改失败')
    }
  }

这段代码,可以修改文件内容,并保存到本地文件内。

查看文件

  const handleSaveFile = async () => {
      [fileHandle] = await showOpenFilePicker()
    try {
      const file = await fileHandle.getFile()
      const read =  new FileReader()
      reader.onload = (event) => {
      console.log(event.target.result)
      }
      reader.readAsText(file)
    } catch (error) {
      console.log('文件获取失败')
    }
  }

FileReader,就是我们经常用的读取文件的读取器,对于常规文件js/json/vue/ts/tsx/jsx/html/css/sass/less使用readAsText方法读取,此方法会返回string,我们只需要拿到string,赋值给DominnerText,就可以在页面显示出来。其实图片(png/jpeg/svg+xml/webp)的相关预览跟上面基本一样,只是换一个读取方法,使用readAsDataURL方法读取,它会返回base64给我们,这时候,我们只需要把值绑定到imgsrc上面就可以了,页面在显示img就ok了。

总结

至此基于以上,就可以实现一个基础版本的vscode,我已经发布了在线版vscode,代码也已经上传到github,花了一天多的时间,基于umi+react+antd,大家有兴趣,可以自己git clone下来本地跑一下。