[node.js] Node.js를 사용하여 전체 디렉토리를 압축해야합니다.

Node.js를 사용하여 전체 디렉토리를 압축해야합니다. 현재 node-zip을 사용하고 있으며 프로세스가 실행될 때마다 잘못된 ZIP 파일이 생성됩니다 ( 이 Github 문제 에서 볼 수 있듯이 ).

디렉토리를 압축 할 수있는 또 다른 더 나은 Node.js 옵션이 있습니까?

편집 : 아카이버 를 사용하여 끝났습니다.

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

매개 변수의 샘플 값 :

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

업데이트 : 내가 사용한 구현에 대해 묻는 사람들 을 위해 내 다운로더에 대한 링크가 있습니다 .



답변

결국 아카이버 lib 를 사용하게되었습니다 . 잘 작동합니다.

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 and naming it `new-subdir` within the archive (see docs for more options):
archive.directory(source_dir, false);
archive.finalize();


답변

나는 새로운 것을 보여주는 척하지 않고 (나와 같은) 코드에서 Promise 함수를 사용하는 것을 좋아하는 사람들을 위해 위의 솔루션을 요약하고 싶습니다.

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

누군가를 도울 수 있기를 바랍니다.)


답변

child_process이를 위해 Node의 네이티브 API를 사용하세요.

타사 라이브러리가 필요하지 않습니다. 두 줄의 코드.

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

동기식 API를 사용하고 있습니다. child_process.exec(path, options, callback)비동기가 필요한 경우 사용할 수 있습니다 . 요청을 더 세부적으로 조정하기 위해 CWD를 지정하는 것보다 훨씬 더 많은 옵션이 있습니다. exec / execSync 문서를 참조하십시오 .


참고 :
이 예제는 시스템에 zip 유틸리티가 설치되어 있다고 가정합니다 (적어도 OSX와 함께 제공됨). 일부 운영 체제에는 유틸리티가 설치되어 있지 않을 수 있습니다 (예 : AWS Lambda 런타임에는 설치되지 않음). 이 경우 여기 에서 쉽게 zip 유틸리티 바이너리를 가져 와서 애플리케이션 소스 코드와 함께 패키징하거나 (AWS Lambda의 경우 Lambda 계층에서도 패키징 할 수 있음) 타사 모듈을 사용해야합니다. (그 중 NPM에 많은 것이 있습니다). ZIP 유틸리티는 수십 년 동안 시도되고 테스트 되었기 때문에 이전 접근 방식을 선호합니다.


답변

Archive.bulk이제 더 이상 사용되지 않으며이를 위해 사용할 새 메서드는 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();


답변

모든 파일 및 디렉토리를 포함하려면 :

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

아래에 node-glob ( https://github.com/isaacs/node-glob )을 사용 하므로 호환되는 모든 일치 표현식이 작동합니다.


답변

이것은 폴더를 한 줄로 압축 하는 또 다른 라이브러리입니다.
zip-local

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

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


답변

결과를 응답 개체로 파이프하려면 (로컬에 저장하지 않고 zip을 다운로드해야하는 시나리오)

 archive.pipe(res);

디렉토리의 내용에 액세스하기위한 Sam의 힌트가 저에게 효과적이었습니다.

src: ["**/*"]