Besoin de compresser un répertoire entier en utilisant Node.js

Je dois compresser un répertoire entier en utilisant Node.js. J’utilise actuellement node-zip et chaque fois que le processus s’exécute, il génère un fichier ZIP non valide (comme vous pouvez le voir sur ce problème Github ).

Existe-t-il une autre option, mieux, Node.js, qui me permettra d’ouvrir un répertoire?

EDIT: j’ai fini par utiliser l’ archiveur

writeZip = function(dir,name) { var zip = new JSZip(), code = zip.folder(dir), output = zip.generate(), filename = ['jsd-',name,'.zip'].join(''); fs.writeFileSync(baseDir + filename, output); console.log('creating ' + filename); }; 

valeur d’échantillon pour les parameters:

 dir = /tmp/jsd-/ name =  

MISE À JOUR: Pour ceux qui s’interrogent sur l’implémentation que j’ai utilisée, voici un lien vers mon téléchargeur :

J’ai fini par utiliser l’ archivage lib. Fonctionne très bien.

Exemple

 var file_system = require('fs'); var archiver = require('archiver'); var output = file_system.createWriteStream('target.zip'); var archive = archiver('zip'); output.on('close', function () { console.log(archive.pointer() + ' total bytes'); console.log('archiver has been finalized and the output file descriptor has closed.'); }); archive.on('error', function(err){ throw err; }); archive.pipe(output); archive.bulk([ { expand: true, cwd: 'source', src: ['**'], dest: 'source'} ]); archive.finalize(); 

Pour inclure tous les fichiers et répertoires:

 archive.bulk([ { expand: true, cwd: "temp/freewheel-bvi-120", src: ["**/*"], dot: true } ]); 

Il utilise node-glob ( https://github.com/isaacs/node-glob ) en dessous, donc toutes les expressions compatibles avec cela fonctionneront.

Archive.bulk est maintenant obsolète, la nouvelle méthode à utiliser pour cela est glob :

 var fileName = 'zipOutput.zip' var fileOutput = fs.createWriteStream(fileName); fileOutput.on('close', function () { console.log(archive.pointer() + ' total bytes'); console.log('archiver has been finalized and the output file descriptor has closed.'); }); archive.pipe(fileOutput); archive.glob("../dist/**/*"); //some glob pattern here archive.glob("../dist/.htaccess"); //another glob pattern // add as many as you like archive.on('error', function(err){ throw err; }); archive.finalize(); 

Adm-zip a du mal à compresser une archive existante, https://github.com/cthackers/adm-zip/issues/64 , ainsi que la corruption avec la compression des fichiers binarys.

J’ai également rencontré des problèmes de corruption de compression avec node-zip https://github.com/daraosn/node-zip/issues/4

node-archiver est le seul qui semble bien fonctionner pour compresser, mais il ne possède aucune fonctionnalité de décompression.

Pour diriger le résultat vers l’object de réponse (scénarios dans lesquels il est nécessaire de télécharger le fichier zip plutôt que de le stocker localement)

  archive.pipe(res); 

Les conseils de Sam pour accéder au contenu du répertoire ont fonctionné pour moi.

 src: ["**/*"] 

Utilisez pour child_process API child_process natif de Node.

Pas besoin de librairies tierces. Deux lignes de code.

 const child_process = require("child_process"); child_process.execSync(`zip -r DESIRED_NAME_OF_ZIP_FILE_HERE *`, { cwd: PATH_TO_FOLDER_YOU_WANT_ZIPPED_HERE }); 

J’utilise l’API synchrone. Vous pouvez utiliser child_process.exec(path, options, callback) si vous avez besoin d’un asynchrone. Il y a beaucoup plus d’options que de spécifier le CWD pour affiner davantage vos requêtes. Voir les documents exec / execSync .

Je ne prétends pas montrer quelque chose de nouveau, je veux juste résumer les solutions ci-dessus pour ceux qui aiment utiliser les fonctions Promise dans leur code (comme moi).

 const archiver = require('archiver'); /** * @param {Ssortingng} source * @param {Ssortingng} out * @returns {Promise} */ function zipDirectory(source, out) { const archive = archiver('zip', { zlib: { level: 9 }}); const lambdaStream = fs.createWriteStream(out); return new Promise((resolve, reject) => { archive .directory(source, false) .on('error', err => reject(err)) .pipe(lambdaStream) ; lambdaStream.on('close', () => resolve()); archive.finalize(); }); } 

J’espère que ça va aider quelqu’un;)

Ceci est une autre bibliothèque qui zippe le dossier dans une ligne: zip-local

 var zipper = require('zip-local'); zipper.sync.zip("./hello/world/").compress().save("pack.zip");