node-zip icon indicating copy to clipboard operation
node-zip copied to clipboard

Is it possible to create a zip from an existing file/folder structure?

Open thinkloop opened this issue 9 years ago • 4 comments

Hello, thanks a lot for the lib.

Is it possible to create a zip from existing file/folder structures?

I would like to do something like:

const fs = require("fs");
const Zip = require('node-zip');
const zip = new Zip();

zip.folder('./src/existing-folder-with-files-and-subfolders');
var data = zip.generate({base64: false, compression: 'DEFLATE'});
fs.writeFileSync('./output/zipped-files-exactly-as-they-appear-in-filesystem.zip', data, 'binary');

Instead of creating new files and folders from within the zip utility. Is this possible?

thinkloop avatar Dec 17 '16 16:12 thinkloop

Someone has a workaround for this? I also need to compress a folder.

adelriosantiago avatar May 02 '17 20:05 adelriosantiago

I used zip-folder.

thinkloop avatar May 03 '17 14:05 thinkloop

I also needed such a functionality, but seems like there is no way to do it simply. So I did all folder creation and adding files to zip file using methods from JSZip library on which this library is based.

kkuatov avatar May 15 '17 13:05 kkuatov

@thinkloop @adelriosantiago @kkuatov

If your folder structure is not soooo deep, it's easy to walk the folder and add each file to zip. For example:

const fs = require('fs');
const path = require('path');
const NodeZip = require('node-zip');

const zip = new NodeZip();
const BUILD_PATH = './build';
const OUTPUT_PATH = path.join(__dirname, `${BUILD_PATH}.zip`);
const ALL_FILES = {};

const isFolder = folderPath => fs.statSync(folderPath).isDirectory();

const folderWalker = (folder = './', lastFolder = './') => {
  const folderPath = path.join(__dirname, BUILD_PATH, lastFolder, folder);
  fs.readdirSync(folderPath)
    .filter(filename => filename[0] !== '.')
    .forEach((file) => {
      const fullpath = path.resolve(__dirname, BUILD_PATH, lastFolder, folder, file);
      if (isFolder(fullpath)) {
        const fatherFolder = path.join(lastFolder, folder);
        folderWalker(file, fatherFolder);
      } else {
        const relativePath = path.join(lastFolder, folder, file);
        ALL_FILES[fullpath] = relativePath;
      }
    });
};

const zipFolder = (folder) => {
  folderWalker(folder);
  Object.keys(ALL_FILES).forEach((fullpath) => {
    const relativePath = ALL_FILES[fullpath];
    zip.file(relativePath, fs.readFileSync(fullpath));
  });
  const data = zip.generate({ base64: false, compression: 'DEFLATE' });
  fs.writeFileSync(OUTPUT_PATH, data, 'binary');
};

zipFolder();

Check Gist here to see full code.

ecmadao avatar May 30 '17 03:05 ecmadao