files - Necesita ZIP un directorio completo utilizando Node.js
node zip folder (8)
Necesito comprimir un directorio completo usando Node.js. Actualmente estoy usando node-zip y cada vez que se ejecuta el proceso, genera un archivo ZIP no válido (como puede ver en este problema de Github ).
¿Hay otra opción, mejor, Node.js que me permita ZIP un directorio?
EDITAR: terminé usando el 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);
};
valor de muestra para los parámetros:
dir = /tmp/jsd-<randomstring>/
name = <randomstring>
ACTUALIZACIÓN: Para aquellos que preguntan sobre la implementación que utilicé, aquí hay un enlace a mi descargador :
Use la aplicación child_process
nativa de child_process
para lograr esto.
No hay necesidad de libs de terceros. Dos líneas de código.
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
});
Estoy usando la API síncrona. Puede usar child_process.exec(path, options, callback)
si necesita asincronización. Hay muchas más opciones que solo especificar el CWD para afinar aún más tus solicitudes. Ver exec/execSync docs.
Adm-zip tiene problemas simplemente al comprimir un archivo existente https://github.com/cthackers/adm-zip/issues/64 , así como daños al comprimir archivos binarios.
También me encontré con problemas de corrupción de compresión con node-zip https://github.com/daraosn/node-zip/issues/4
node-archiver es el único que parece funcionar bien para comprimir pero no tiene ninguna funcionalidad de descompresión.
Esta es otra biblioteca que comprime la carpeta en una línea: zip-local
var zipper = require(''zip-local'');
zipper.sync.zip("./hello/world/").compress().save("pack.zip");
No pretendo mostrar algo nuevo, solo quiero resumir las soluciones anteriores para aquellos a los que les gusta usar las funciones Promise en su código (como yo).
const archiver = require(''archiver'');
/**
* @param {String} source
* @param {String} 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();
});
}
Espero que ayude a alguien;)
Para canalizar el resultado al objeto de respuesta (escenarios donde hay una necesidad de descargar el archivo zip en lugar de almacenar localmente)
archive.pipe(res);
Los consejos de Sam para acceder al contenido del directorio me funcionaron.
src: ["**/*"]
Para incluir todos los archivos y directorios:
archive.bulk([
{
expand: true,
cwd: "temp/freewheel-bvi-120",
src: ["**/*"],
dot: true
}
]);
Utiliza node-glob ( https://github.com/isaacs/node-glob ) debajo, por lo que cualquier expresión coincidente compatible con eso funcionará.
Terminé usando archiver lib. Funciona genial.
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();
Archive.bulk
ahora está en desuso, el nuevo método que se utilizará para esto es 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();