import glob, { IGlob } from 'glob'; import fs from 'fs'; import path from 'path'; import { concat } from 'lodash'; import archiver from 'archiver'; import { readFile } from 'fs-extra'; const defaultIgnores = ['git', 'svn', 'bin', 'tea', 'node'].map((item) => { return `**/.${item}/**`; }); defaultIgnores.push('**/.DS_Store'); type ArchiveFiles = { name: string; buffer: Buffer; }[]; export interface GlobPackOptions { cwd: string; dist: string; pattern?: string; ignore?: string[]; parseFiles?: (files: ArchiveFiles) => ArchiveFiles; } function pack(dist: string, files: ArchiveFiles) { return new Promise((resolve, reject) => { const output = fs.createWriteStream(dist); const extname = path.extname(dist); const archiveExt = extname === '.zip' ? 'zip' : 'tar'; const archive = archiver(archiveExt, { gzip: extname !== '.tar', gzipOptions: {}, }); output.on('close', () => { resolve(); }); archive.on('error', (err) => { reject(err); }); archive.pipe(output); for (const file of files) { archive.append(file.buffer, { name: file.name }); } archive.finalize(); }); } /** * 打包指定目录,支持ignores */ async function globPack(options: GlobPackOptions): Promise { // TS MODIFY const vm = await new Promise((resolve, reject) => { const g = new glob.Glob( options.pattern || '**', { nodir: true, follow: false, ignore: concat(defaultIgnores, options.ignore || []), nosort: true, strict: true, silent: false, cwd: options.cwd, absolute: false, mark: true, dot: true, }, function (err) { if (err) { reject(err); return; } resolve(g); } ); }); for (const key in vm.symlinks) { // 存在软连接 if (vm.symlinks[key]) { return Promise.reject( new Error( `目录存在软链接 ${key},打包失败,请使用 yarn install或者npm install --no-bin-links 安装依赖` ) ); } } let files = await Promise.all( vm.found.map((name) => { const filePath = path.join(options.cwd, name); return readFile(filePath).then((buffer) => { return { name, buffer, }; }); }) ); if (options.parseFiles) { files = options.parseFiles(files); } await pack(options.dist, files); } export default globPack;