182 votes

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

J'ai besoin de zipper 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 invalide (comme vous pouvez le voir dans la section ce problème Github ).

Existe-t-il une autre option Node.js, meilleure, qui me permette de mettre un répertoire sous forme de ZIP ?

EDIT : J'ai fini par utiliser 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 paramètres :

dir = /tmp/jsd-<randomstring>/
name = <randomstring>

UPDATE : Pour ceux qui s'interrogent sur la mise en œuvre que j'ai utilisée, Voici un lien vers mon téléchargeur :

198voto

commadelimited Points 1657

J'ai fini par utiliser archiveur lib. Elle 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);

// append files from a sub-directory, putting its contents at the root of archive
archive.directory(source_dir, false);

// append files from a sub-directory and naming it `new-subdir` within the archive
archive.directory('subdir/', 'new-subdir');

archive.finalize();

135voto

D.Dimitrioglo Points 1375

Je ne vais pas montrer quelque chose de nouveau, je voulais juste résumer les solutions ci-dessus pour ceux qui aiment les promesses autant que moi .

const archiver = require('archiver');

/**
 * @param {String} sourceDir: /some/folder/to/compress
 * @param {String} outPath: /path/to/created.zip
 * @returns {Promise}
 */
function zipDirectory(sourceDir, outPath) {
  const archive = archiver('zip', { zlib: { level: 9 }});
  const stream = fs.createWriteStream(outPath);

  return new Promise((resolve, reject) => {
    archive
      .directory(sourceDir, false)
      .on('error', err => reject(err))
      .pipe(stream)
    ;

    stream.on('close', () => resolve());
    archive.finalize();
  });
}

J'espère que cela aidera quelqu'un

49voto

Govind Rai Points 3726

Utilisez la fonction native de Node child_process pour y parvenir.

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>
});

L'exemple ci-dessus présente l'API synchrone. Vous pouvez également utiliser child_process.exec(path, options, callback) si vous voulez un comportement asynchrone. Il y a beaucoup plus de options vous pouvez spécifier d'autres éléments que cwd pour affiner votre demande.


Lisez cette section uniquement si vous ne disposez pas de l'utilitaire ZIP :

Cette question porte spécifiquement sur le zip à des fins d'archivage/compression. Par conséquent, cet exemple suppose que vous avez le zip installé sur votre système. Pour être complet, certains systèmes d'exploitation peuvent ne pas avoir l'utilitaire installé par défaut. Dans ce cas, vous avez au moins trois options :

  1. Travaillez avec l'utilitaire d'archivage/compression qui est natif de votre plateforme.

    Remplacez la commande shell dans le code node.js ci-dessus par le code de votre système. Par exemple, les distributions Linux sont généralement livrées avec la commande tar / gzip des services publics :

    tar -cfz <DESIRED_NAME_OF_ZIP_FILE_HERE> <PATH_TO_FOLDER_YOU_WANT_ZIPPED_HERE> .

    C'est une option intéressante car vous n'avez pas besoin d'installer quoi que ce soit de nouveau sur votre système d'exploitation ou de gérer une autre dépendance (ce qui est en quelque sorte le but de cette réponse).

  2. Obtenir le zip pour votre système d'exploitation/distribution ( zip est assez omniprésente).

    Faites une recherche rapide sur Google ou allez sur le site du créateur, Info-ZIP, pour télécharger les binaires.

    L'utilitaire ZIP est éprouvé depuis des décennies, il est assez omniprésent et c'est un choix sûr.

  3. Utiliser un module tiers (il y en a beaucoup sur NPM).

    Je ne préfère pas cette option. Cependant, si vous ne vous souciez pas vraiment de comprendre les méthodes natives et que l'introduction d'une nouvelle dépendance n'est pas un problème, c'est également une option valable.

22voto

Dreams Points 1033

Il s'agit d'une autre bibliothèque qui zippe le dossier en une seule ligne : zip-local

var zipper = require('zip-local');

zipper.sync.zip("./hello/world/").compress().save("pack.zip");

13voto

caiocpricci2 Points 3681

Archive.bulk est désormais obsolète, la nouvelle méthode à utiliser pour cela est la suivante globe terrestre :

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();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X