There is now an easier way to do it compared to the other answers.
archiver (page on npmjs) now has a method named 'directory' to help you do this.
Install archiver with:
npm install archiver --save
There are four things you need to do to recursively zip a directory and write it to a file.
A. Create an instance of archiver by using
var ar = archive.create('zip',{});
B. Create a fs.writeStream and set up its event handlers...
var outputStream = fs.createWriteStream(odsFilepath, {flags: 'w'});
outputStream.on('close', function () {
console.log(ar.pointer() + ' total bytes written');
console.log('ODS file written to:', odsFilepath);
});
...
C. Wire up the output of our archiver to be piped to the writeStream we created:
ar.pipe(outputStream);
D. Ask our archiver to zip up the contents of the directory and place it in the 'root' or '/' of our zip file.
ar.directory(directoryPathToAddToZip, '/')
.finalize();
Here is the code snippet of the function where I am using this.
Note: put the following code snippet into a file, say index.js
var archiver = require('archiver');
var utility = require('utility');
var path = require('path');
var fs = require('fs');
//This is the directory where the zip file will be written into.
var outputDirname = ".";
//This directory should contain the stuff that we want to
// put inside the zip file
var pathOfContentDirToInsertIntoArchive = "./tozip";
saveToZip(function () {
console.log('We are now done');
});
function saveToZip(done) {
//we use the utility package just to get a timestamp string that we put
//into the output zip filename
var ts = utility.logDate();
var timestamp = ts.replace(/[ :]/g, '-');
var zipFilepath = path.normalize(outputDirname + '/' + timestamp + '.zip')
var ar = archiver.create('zip', {});
var output = fs.createWriteStream(zipFilepath, {flags: 'w'});
output.on('close', function () {
//console.log(ar.pointer() + ' total bytes');
console.log('ZIP file written to:', zipFilepath);
return done(null, 'Finished writing')
});
ar.on('error', function (err) {
console.error('error compressing: ', err);
return done(err, 'Could not compress');
});
ar.pipe(output);
ar.directory(path.normalize(pathOfContentDirToInsertIntoArchive + '/'), '/')
.finalize();
}
Then do a npm install archiver --save
and npm install utility --save
Then create a directory named "tozip" in the current directory and put in there some files that you want to compress into the output zip file.
Then, run node index.js
and you will see output similar to:
$ node index.js
ZIP file written to: 2016-12-19-17-32-14.817.zip
We are now done
The zip file created will contain the contents of the tozip directory, compressed.