You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js如何通过流而非磁盘实现文件夹复制与压缩?

问题与解决方案:Netlify函数无磁盘写入权限下的模板压缩返回

问题背景

原代码在本地可正常运行:读取/template目录,替换变量后写入/theme目录,再压缩该目录并通过HTTP返回。但部署到Netlify后失败,因为Netlify函数环境不允许磁盘写入操作。

解决方案思路

跳过磁盘写入步骤,全程在内存中完成模板变量替换与压缩:

  1. 遍历模板目录的所有文件
  2. 读取文件内容并替换变量
  3. 将处理后的内容直接添加到JSZip实例
  4. 生成zip文件并返回响应

修改后代码

const path = require("path");
const fs = require("fs").promises;
const JSZip = require("JSZip");

const templateDir = path.join(__dirname, "template");

exports.handler = async (event, context) => {
    // 初始化变量,优先从查询参数获取
    const vars = {
        theme_name: "Theme Name",
        theme_slug: "theme-slug",
        author_name: "Author Name",
        ...event.queryStringParameters
    };

    // 遍历目录并处理文件,添加到zip
    const processDirectory = async (dir, zip, basePath = "") => {
        const entries = await fs.readdir(dir, { withFileTypes: true });
        
        for (const entry of entries) {
            const fullPath = path.join(dir, entry.name);
            const zipPath = path.join(basePath, entry.name);

            if (entry.isDirectory()) {
                await processDirectory(fullPath, zip, zipPath);
            } else {
                // 读取文件内容并替换变量
                let content = await fs.readFile(fullPath, "utf-8");
                // 替换所有变量占位符,比如{{theme_name}}
                Object.keys(vars).forEach(key => {
                    const placeholder = `{{${key}}}`;
                    content = content.replace(new RegExp(placeholder, "g"), vars[key]);
                });
                // 将处理后的内容添加到zip
                zip.file(zipPath, content);
            }
        }
    };

    try {
        const zip = new JSZip();
        await processDirectory(templateDir, zip);
        
        // 生成zip的base64格式内容
        const zipBase64 = await zip.generateAsync({ type: "base64" });

        return {
            statusCode: 200,
            body: zipBase64,
            headers: {
                "Content-Type": "application/zip",
                "Content-Disposition": "attachment; filename=theme.zip",
                "Content-Transfer-Encoding": "base64"
            }
        };
    } catch (err) {
        return {
            statusCode: 500,
            body: JSON.stringify({ error: err.message })
        };
    }
};

关键改动说明

  • 移除磁盘写入依赖:不再使用copy-template-dir写入本地目录,改为直接在内存中处理文件内容
  • 异步文件操作:使用fs.promises替代同步方法,符合Netlify函数的异步执行要求
  • 变量替换逻辑:手动实现模板变量替换,兼容原代码的{{变量名}}占位符格式
  • 内存中压缩:处理后的文件直接加入JSZip,无需先写入磁盘再读取,完全规避磁盘权限问题

内容的提问来源于stack exchange,提问作者Joseph Farruggio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 00:24:17