如何在VS Code Web扩展中获取子文件夹所有文件并生成Zip及执行后续代码
解决VS Code Web扩展中递归打包文件夹到Zip的问题
你的核心问题在于原代码没有正确等待所有异步文件读取和递归遍历完成,导致JSZip还未添加完所有文件就可能执行生成操作,后续代码也无法同步等待打包流程结束。下面是可靠的实现方案:
核心思路
- 使用
async/await替代回调链,避免异步操作顺序混乱 - 用
Promise.all等待当前目录下所有文件/子目录的处理任务完成 - 递归遍历文件夹时,同步维护Zip内的路径结构
实现代码
const JSZip = require('jszip'); /** * 递归遍历文件夹并添加到JSZip实例 * @param {vscode.Uri} folderUri - 要打包的文件夹URI * @param {JSZip} zip - JSZip实例 * @param {string} currentZipPath - 当前在Zip中的相对路径,默认为空(根目录) */ async function addFolderToZip(folderUri, zip, currentZipPath = '') { // 读取当前目录下的所有条目 const entries = await vscode.workspace.fs.readDirectory(folderUri); // 等待所有条目处理完成 await Promise.all(entries.map(async ([name, type]) => { const itemUri = vscode.Uri.joinPath(folderUri, name); const zipItemPath = currentZipPath ? `${currentZipPath}/${name}` : name; if (type === vscode.FileType.File) { // 读取文件内容并添加到Zip const fileContent = await vscode.workspace.fs.readFile(itemUri); zip.file(zipItemPath, fileContent); } else if (type === vscode.FileType.Directory) { // 创建Zip内的子文件夹,递归处理子目录 const subZip = zip.folder(zipItemPath); await addFolderToZip(itemUri, subZip, zipItemPath); } })); } // 主打包函数 async function packFolderToZip(targetFolderUri) { const zip = new JSZip(); try { // 等待所有文件添加完成 await addFolderToZip(targetFolderUri, zip); // 生成Zip文件(可根据需求调整压缩级别和格式) const zipBuffer = await zip.generateAsync({ type: 'uint8array', compression: 'DEFLATE', compressionOptions: { level: 6 } }); // 这里执行打包完成后的后续代码 console.log('Zip生成完成,大小:', zipBuffer.length); // 示例:保存Zip到指定位置或下载 // await vscode.workspace.fs.writeFile(saveUri, zipBuffer); } catch (error) { console.error('打包出错:', error); } }
关键说明
- 异步等待:所有涉及
vscode.workspace.fs的异步操作都用await处理,确保每个步骤完成后再执行下一步 - Promise.all批量处理:当前目录下的所有文件/子目录处理任务并行执行,同时等待全部完成,保证整个目录遍历的完整性
- Zip路径维护:通过
currentZipPath参数同步维护Zip内的目录结构,避免文件路径混乱 - 错误捕获:用
try/catch包裹整个流程,便于处理文件读取或打包过程中的异常
内容的提问来源于stack exchange,提问作者AdamRaichu
相关产品推荐
相关产品推荐

