@taole/deploy-helper 1.1.5 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,61 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { PassThrough } from "stream";
4
+ import archiver from "archiver";
5
+
6
+ export function archiveToBuffer(setupArchive) {
7
+ return new Promise((resolve, reject) => {
8
+ const chunks = [];
9
+ const output = new PassThrough();
10
+ output.on("data", (chunk) => chunks.push(chunk));
11
+ output.on("end", () => resolve(Buffer.concat(chunks)));
12
+ output.on("error", reject);
13
+
14
+ const archive = archiver("zip", { zlib: { level: 1 } });
15
+ archive.on("error", reject);
16
+ archive.pipe(output);
17
+
18
+ setupArchive(archive);
19
+ archive.finalize();
20
+ });
21
+ }
22
+
23
+ function appendDirToArchive(archive, dir, zipPrefix) {
24
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
25
+ const fullPath = path.join(dir, entry.name);
26
+ const entryZipPath = zipPrefix
27
+ ? path.posix.join(zipPrefix, entry.name)
28
+ : entry.name;
29
+ if (entry.isDirectory()) {
30
+ appendDirToArchive(archive, fullPath, entryZipPath);
31
+ } else {
32
+ archive.file(fullPath, { name: entryZipPath });
33
+ }
34
+ }
35
+ }
36
+
37
+ export function genProjectArchiveBuffer(distPath) {
38
+ return archiveToBuffer((archive) => {
39
+ archive.directory(distPath, false);
40
+ });
41
+ }
42
+
43
+ /**
44
+ * lib 类型 CDN 打包:若 dist 内仅有名为 version 的子目录则原样打包;
45
+ * 若无子目录则为 zip 内所有文件加上 version 前缀。
46
+ */
47
+ export function genLibArchiveBuffer(distPath, version) {
48
+ const subdirs = fs
49
+ .readdirSync(distPath, { withFileTypes: true })
50
+ .filter((entry) => entry.isDirectory());
51
+
52
+ return archiveToBuffer((archive) => {
53
+ if (subdirs.length === 1 && subdirs[0].name === version) {
54
+ archive.directory(distPath, false);
55
+ } else if (subdirs.length === 0) {
56
+ appendDirToArchive(archive, distPath, version);
57
+ } else {
58
+ archive.directory(distPath, false);
59
+ }
60
+ });
61
+ }
@@ -2,7 +2,10 @@ import fs from "fs";
2
2
  import path from "path";
3
3
  import { log } from "./util.mjs";
4
4
  import { getCache as getLoginCache } from "./login.mjs";
5
- import { genArchive } from "./project.mjs";
5
+ import {
6
+ genLibArchiveBuffer,
7
+ genProjectArchiveBuffer,
8
+ } from "./archive.mjs";
6
9
 
7
10
  const isDev = false;
8
11
  const apiHost = isDev ? "http://localhost:9000" : "https://fapi.tuwan.com";
@@ -19,7 +22,7 @@ function getErrorMessage(resJson, fallback) {
19
22
  }
20
23
 
21
24
  async function apiCdnUpload(
22
- { distZipPath, prefix, mode, includeHtml, entryHtmlMap, type, version },
25
+ { distZipBuffer, prefix, mode, includeHtml, entryHtmlMap, type, version },
23
26
  userCache
24
27
  ) {
25
28
  const formData = new FormData();
@@ -41,7 +44,7 @@ async function apiCdnUpload(
41
44
  }
42
45
  formData.append(
43
46
  "file",
44
- new Blob([fs.readFileSync(distZipPath)], { type: "application/zip" }),
47
+ new Blob([distZipBuffer], { type: "application/zip" }),
45
48
  "dist.zip"
46
49
  );
47
50
 
@@ -69,6 +72,11 @@ export async function lightDeploy(config, mode) {
69
72
  fs.readFileSync(path.join(process.cwd(), "package.json"), "utf-8")
70
73
  );
71
74
  const version = projectJson.version;
75
+ // 校验cdnType只能是lib或者project
76
+ const cdnType = config.cdnType;
77
+ if (cdnType !== "lib" && cdnType !== "project") {
78
+ throw new Error("配置项 cdnType 仅支持 'lib' 或 'project'");
79
+ }
72
80
  log(`light模式, 开始部署`, {
73
81
  mode,
74
82
  prefix: config.prefix,
@@ -98,14 +106,12 @@ export async function lightDeploy(config, mode) {
98
106
  throw new Error(`${distPath} 不存在,请先执行构建`);
99
107
  }
100
108
 
101
- const distZipPath = path.join(workDir, "cdnDist.zip");
102
- if (fs.existsSync(distZipPath)) {
103
- fs.unlinkSync(distZipPath);
104
- }
105
-
106
109
  log(`开始打包 ${distPath}`);
107
- await genArchive(distZipPath, distPath);
108
- log(`打包完成: ${distZipPath}`);
110
+ const distZipBuffer =
111
+ cdnType === "lib"
112
+ ? await genLibArchiveBuffer(distPath, version)
113
+ : await genProjectArchiveBuffer(distPath);
114
+ log(`打包完成,大小 ${distZipBuffer.length} 字节`);
109
115
 
110
116
  const includeHtml = config.includeHtml === true;
111
117
  log(
@@ -113,25 +119,17 @@ export async function lightDeploy(config, mode) {
113
119
  config.cdnType || "project"
114
120
  }, version=${version}, includeHtml=${includeHtml}`
115
121
  );
116
- try {
117
- const result = await apiCdnUpload(
118
- {
119
- distZipPath,
120
- prefix,
121
- mode,
122
- includeHtml,
123
- entryHtmlMap: config.entryHtmlMap,
124
- type: config.cdnType,
125
- version,
126
- },
127
- userCache
128
- );
129
- log(`CDN 上传成功`, result);
130
- } catch (error) {
131
- throw error;
132
- } finally {
133
- if (fs.existsSync(distZipPath)) {
134
- fs.unlinkSync(distZipPath);
135
- }
136
- }
122
+ const result = await apiCdnUpload(
123
+ {
124
+ distZipBuffer,
125
+ prefix,
126
+ mode,
127
+ includeHtml,
128
+ entryHtmlMap: config.entryHtmlMap,
129
+ type: config.cdnType,
130
+ version,
131
+ },
132
+ userCache
133
+ );
134
+ log(`CDN 上传成功`, result);
137
135
  }
package/lib/project.mjs CHANGED
@@ -2,9 +2,9 @@
2
2
  import { simpleGit } from "simple-git";
3
3
  import path from "path";
4
4
  import fs from "fs";
5
- import archiver from "archiver";
6
5
  import { log, getJsonConfig, runCmdAsync } from "./util.mjs";
7
6
  import { getCache as getLoginCache } from "./login.mjs";
7
+ import { genProjectArchiveBuffer } from "./archive.mjs";
8
8
 
9
9
  const isDev = false;
10
10
  const apiHost = isDev ? "http://localhost:9000" : "https://fapi.tuwan.com";
@@ -28,26 +28,6 @@ async function checkPackageNameWithGitRemote(git, packageName) {
28
28
  }
29
29
  }
30
30
 
31
- export function genArchive(outputPath, dir) {
32
- return new Promise((resolve, reject) => {
33
- const output = fs.createWriteStream(outputPath);
34
- const archive = archiver("zip", {
35
- zlib: { level: 1 }, // Sets the compression level.
36
- });
37
- archive.on("error", reject);
38
- archive.on("finish", () => {
39
- // console.log("genArchive finish");
40
- setTimeout(() => {
41
- // console.log("genArchive finish true");
42
- resolve();
43
- }, 300);
44
- });
45
- archive.pipe(output);
46
- archive.directory(dir, false);
47
- archive.finalize();
48
- });
49
- }
50
-
51
31
  async function apiDeployProject(name, version, env, userCache) {
52
32
  try {
53
33
  const urlPath = `/h5projects/${name}/deploy`;
@@ -103,14 +83,14 @@ async function apiCreateProject(name, userCache) {
103
83
  }
104
84
  }
105
85
 
106
- async function apiPublishProject(name, version, distZipPath, userCache) {
86
+ async function apiPublishProject(name, version, distZipBuffer, userCache) {
107
87
  const urlPath = `/h5projects/${name}/publish`;
108
88
  const formData = new FormData();
109
89
  formData.append("updaterUid", userCache.userInfo.uid);
110
90
  formData.append("version", version);
111
91
  formData.append(
112
92
  "file",
113
- new Blob([fs.readFileSync(distZipPath)], { type: "application/zip" }),
93
+ new Blob([distZipBuffer], { type: "application/zip" }),
114
94
  "dist.zip"
115
95
  );
116
96
  const res = await fetch(`${apiHost}${urlPath}`, {
@@ -277,21 +257,17 @@ export const cmdProjectPublish = async () => {
277
257
  await runCmdAsync(buildCmd);
278
258
  log(`构建项目成功,开始打包构建产物`);
279
259
  const distPath = path.join(process.cwd(), "dist");
280
- const distZipPath = path.join(process.cwd(), "dist.zip");
281
260
  if (!fs.existsSync(distPath)) {
282
261
  log("dist目录不存在");
283
262
  process.exit(1);
284
263
  }
285
- // 把dist目录打包为zip包
286
- if (fs.existsSync(distZipPath)) {
287
- fs.unlinkSync(distZipPath);
288
- }
289
- await genArchive(distZipPath, distPath);
290
- log(`dist目录打包为zip包: ${distZipPath}, 开始推送构建产物`);
264
+ log(`开始打包 ${distPath}`);
265
+ const distZipBuffer = await genProjectArchiveBuffer(distPath);
266
+ log(`打包完成,大小 ${distZipBuffer.length} 字节,开始推送构建产物`);
291
267
  const _publishResult = await apiPublishProject(
292
268
  packageJson.name,
293
269
  packageJson.version,
294
- distZipPath,
270
+ distZipBuffer,
295
271
  userCache
296
272
  );
297
273
  log(`构建产物推送成功, 开始部署项目至${env}环境`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taole/deploy-helper",
3
- "version": "1.1.5",
3
+ "version": "1.1.6",
4
4
  "description": "脚本部署工具,用于将项目部署到测试环境或生产环境",
5
5
  "main": "index.mjs",
6
6
  "type": "module",