开发背景
最近在
MDN上看file相关的api,发现,现在js真的很强大,都可以在网页进行文件(夹)的增删改查了。我想着,反正也大概看了一遍,索性写个基础的项目,也算巩固知识了不是,所以我就瞄准了vscode,毕竟天天用这东西,废话不多话,开整。
项目部分截图
- 创建文件
- 创建文件夹
- 查看vue文件
- 查看tsx文件
- 预览图片
项目目标
- 对文件夹进行常规增删改查。
- 对
js/json/vue/ts/tsx/jsx/html/css/sass/less等文件进行常规增删改查。 - 对
png/jpeg/svg+xml/webp等图片资源的预览。
文件夹的增删改查
要想对文件夹进行增删改查,首先就是先要选择本地目录,这里需要调用我们的file系统提供的
showDirectoryPicker方法,因为我们要进行读写操作,所以需要传递参数showDirectoryPicker({ mode: 'readwrite' }),调用如下图:
读取文件夹
showDirectoryPicker({ mode: 'readwrite' }).then(async (res) => {
let result = []
for await (const [key, value] of res.entries()) {
result.push(value)
}
})
result就是我们获取juejin目录下的文件和文件夹,如下图(antd的tree组件):
这解释下,图一的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,赋值给Dom的innerText,就可以在页面显示出来。其实图片(png/jpeg/svg+xml/webp)的相关预览跟上面基本一样,只是换一个读取方法,使用readAsDataURL方法读取,它会返回base64给我们,这时候,我们只需要把值绑定到img的src上面就可以了,页面在显示img就ok了。
总结
至此基于以上,就可以实现一个基础版本的vscode,我已经发布了在线版vscode,代码也已经上传到github,花了一天多的时间,基于umi+react+antd,大家有兴趣,可以自己git clone下来本地跑一下。