import fs from 'fs'; import path from 'path'; import Yazl from 'yazl'; import { MiniProjectConfig } from '../types/mini'; import globPack from './glob.pack'; import { getMBSize } from './util'; /** * 小程序只会打包指定格式的资源 * https://yuque.antfin-inc.com/tiny-site/framework/projectconfig */ const INCLUDES = [ 'acss', 'axml', 'js', 'json', 'sjs', 'png', 'jpg', 'jpeg', 'gif', 'svg', 'webp', 'eot', 'woff', 'ttf', 'woff2', 'otf', 'mp3', 'mp4', 'xml', 'mjs', 'txt', ]; const PATTERN = `**/*.{${INCLUDES.join(',')}}`; interface PackAmrOptions { cwd: string; destDir: string; miniProjectConfig: MiniProjectConfig; } function getProjectConfigBuffer(miniProjectConfig) { const result = { ...miniProjectConfig, miniprogramRoot: '', }; return Buffer.from(JSON.stringify(result), 'utf8'); } export default async function packAmr({ cwd, destDir, miniProjectConfig, }: PackAmrOptions): Promise { let packCwd; let appendMiniProjectConfig = false; // 插件模式需要打包整个目录 if (miniProjectConfig.compileType === 'plugin' || !miniProjectConfig.miniprogramRoot) { packCwd = cwd; } else { appendMiniProjectConfig = true; packCwd = path.join(cwd, miniProjectConfig.miniprogramRoot); } // 忽略 miniu 开发和构建产物 const miniuExcludeFiles = ['.miniu/**', 'miniu_dist/**']; if (!miniProjectConfig.exclude) { miniProjectConfig.exclude = miniuExcludeFiles; } else { // 避免重复 miniuExcludeFiles.forEach((excludeFile) => { if (!miniProjectConfig.exclude.includes(excludeFile)) { miniProjectConfig.exclude.push(excludeFile); } }); } miniProjectConfig.exclude = miniProjectConfig.exclude.filter((item) => { if (item.indexOf('node_modules') !== -1) { return false; } return true; }); const packParams = { cwd: packCwd, dist: path.join(destDir, 'dist.tar'), pattern: PATTERN, ignore: miniProjectConfig.exclude, parseFiles(files) { // 打包的时候只上传了小程序代码 if (appendMiniProjectConfig) { files.push({ name: 'mini.project.json', buffer: getProjectConfigBuffer(miniProjectConfig), }); } return files; }, }; try { await globPack(packParams); } catch (e) { console.log(e); } return new Promise((resolve, reject) => { const zip = new Yazl.ZipFile(); const destPath = path.join(destDir, 'dist.amr'); zip.addFile(packParams.dist, 'dist.tar'); zip.outputStream.pipe(fs.createWriteStream(destPath)).on('close', function () { const zipSize = getMBSize(zip.outputStreamCursor); if (Number(zipSize) > 100) { reject(new Error(`压缩包最大限制为100MB,目前是: ${zipSize}MB;压缩包地址: ${destPath}`)); } resolve(destPath); }); zip.end(); }); }