天天看點

LiveQing打包方法介紹

LiveQing 高性能流媒體伺服器以打成壓縮包的形式提供給客戶使用, 同時支援 Linux 和 Windows 平台. Linux 平台打成 tar 包, Windows 平台打成 zip 包. 通過 NodeJS 運作打包腳本, 實作了打包過程的自動化.

打包核心庫 archiver

用到一個打包的核心庫 archiverjs, 這個 archiver 庫, 支援 glob 表達式, 可以非常友善的指定 需要打包哪些檔案和目錄 和 排除哪些檔案和目錄. 關于 arhiver 對 glob 的支援, 可以點選這裡檢視. archiver 功能強大到可以指定工作目錄

cwd

, 給壓縮包指定字首目錄

prefix

.

位元組大小格式化輸出

pretty-bytes 一個将位元組大小格式化成 human-readable 的庫. 友善在壓縮過程中顯示進度資訊.

commander 指令行工具

commander 結合 tj 創作的這個指令行工具, 快速生成一個打包的指令, 并将打包的格式做成指令行選項.

以下是執行

node release.js -h

輸出

Usage: release [options] [command]


  Options:

    -V, --version           output the version number
    -F, --format [tar,zip]  archive format [tar]
    -h, --help              output usage information


  Commands:

    clean
           

完整的打包腳本

const archiver = require('archiver');
const prettyBytes = require('pretty-bytes');
const os = require('os');
const path = require('path');
const fs = require('fs');
const program = require('commander');

var dir = path.basename(__dirname);

function doArchive() {
    switch (program.format) {
        case 'zip':
            var output = fs.createWriteStream(`${__dirname}/${dir}.zip`);
            var archive = archiver('tar', { zlib: { level: 9 } })
            break;
        case 'tar':
            var output = fs.createWriteStream(`${__dirname}/${dir}.tar.gz`);
            var archive = archiver('tar', { gzip: true });
            break;
        default:
            console.log('unknow format');
            program.help();
            break;
    }
    output.on('close', function () {
        console.log(os.EOL + prettyBytes(archive.pointer()) + ' total bytes');
    });
    archive.on('warning', function (err) {
        if (err.code === 'ENOENT') {
            console.log(err);
        } else {
            throw err;
        }
    }).on('error', function (err) {
        throw err;
    }).on('progress', data => {
        process.stdout.clearLine();
        process.stdout.cursorTo(0);
        process.stdout.write(`${prettyBytes(data.fs.processedBytes)} / ${prettyBytes(data.fs.totalBytes)}`);
    })

    archive.pipe(output);
    archive.glob(`**`, {
        cwd: path.resolve(__dirname, "dist"),
        dot: true,
        ignore: ['logs/**/*', 'temp/**/*']
    },{
        prefix: dir
    })
    console.log(`do ${program.format} ...`);
    archive.finalize();
}

program.version(require('./package.json').version)
    .option('-F, --format [tar,zip]', 'archive format [tar]', 'tar')

program.command('clean').action(function () {
    if(fs.existsSync(path.resolve(__dirname, `${dir}.zip`))){
        fs.unlinkSync(path.resolve(__dirname, `${dir}.zip`));
    }
    if(fs.existsSync(path.resolve(__dirname, `${dir}.tar.gz`))){
        fs.unlinkSync(path.resolve(__dirname, `${dir}.tar.gz`));
    }
    console.log('clean done.');
    process.exit();
})

program.command('*', '', {
    noHelp: true
}).action(function () {
    program.help();
})

program.parse(process.argv);

doArchive();