Je dois compresser un répertoire entier à l'aide de 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 dans ce problème de Github ).
Existe-t-il une autre option, meilleure, Node.js, qui me permettra de compresser un répertoire?
EDIT: J'ai fini par utiliser archiver
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 me posent des questions sur la mise en œuvre que j'ai utilisée, voici un lien vers mon téléchargeur :
J'ai fini par utiliser archiver lib. Fonctionne très bien.
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();
Je ne prétends pas montrer quelque chose de nouveau, je veux simplement résumer les solutions ci-dessus pour ceux qui aiment utiliser les fonctions Promise dans leur code (comme moi).
const archiver = require('archiver');
/**
* @param {String} source
* @param {String} out
* @returns {Promise}
*/
function zipDirectory(source, out) {
const archive = archiver('Zip', { zlib: { level: 9 }});
const stream = fs.createWriteStream(out);
return new Promise((resolve, reject) => {
archive
.directory(source, false)
.on('error', err => reject(err))
.pipe(stream)
;
stream.on('close', () => resolve());
archive.finalize();
});
}
J'espère que ça va aider quelqu'un;)
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, ainsi toute expression correspondante compatible avec cela fonctionnera.
Archive.bulk
est maintenant obsolète, la nouvelle méthode à utiliser 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();
child_process
native du nœud pour accomplir cela.Pas besoin de bibliothèques 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'async. Il y a beaucoup plus d'options que de simplement spécifier le CWD pour affiner vos demandes. Voir exec/execSync docs.
Adm-Zip a des problèmes lors de la compression d'une archive existante https://github.com/cthackers/adm-Zip/issues/64 ainsi que de la corruption lors de la compression des fichiers binaires.
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 compresser, mais il n'a pas de fonctionnalité de décompression.
Pour diriger le résultat vers l'objet de réponse (scénarios dans lesquels il est nécessaire de télécharger le zip plutôt que de le stocker localement)
archive.pipe(res);
Les astuces de Sam pour accéder au contenu du répertoire ont fonctionné pour moi.
src: ["**/*"]
Ceci est une autre bibliothèque qui ferme le dossier sur une ligne: Zip-local
var zipper = require('Zip-local');
zipper.sync.Zip("./hello/world/").compress().save("pack.Zip");
J'ai trouvé cette petite bibliothèque qui contient tout ce dont vous avez besoin.
npm install Zip-a-folder
const Zip-a-folder = require('Zip-a-folder');
await Zip-a-folder.Zip('/path/to/the/folder', '/path/to/archive.Zip');
Vous pouvez essayer de manière simple:
Installez Zip-dir
:
npm install Zip-dir
et l'utiliser
var zipdir = require('Zip-dir');
let foldername = src_path.split('/').pop()
zipdir(<<src_path>>, { saveTo: 'demo.Zip' }, function (err, buffer) {
});