@taole/deploy-helper 1.1.6 → 1.1.8-beta.1

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.
package/lib/archive.mjs CHANGED
@@ -20,42 +20,128 @@ export function archiveToBuffer(setupArchive) {
20
20
  });
21
21
  }
22
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 });
23
+ function toPosixRelativePath(distPath, filePath) {
24
+ return path.relative(distPath, filePath).split(path.sep).join("/");
25
+ }
26
+
27
+ function matchDistFileFilter(relativePath, filterItem) {
28
+ if (typeof filterItem === "string") {
29
+ return relativePath === filterItem;
30
+ }
31
+ if (filterItem && typeof filterItem.regex === "string") {
32
+ return new RegExp(filterItem.regex).test(relativePath);
33
+ }
34
+ throw new Error(`无效的 distFileFilters 规则: ${JSON.stringify(filterItem)}`);
35
+ }
36
+
37
+ function shouldIncludeDistFile(relativePath, distFileFilters) {
38
+ if (!distFileFilters) {
39
+ return true;
40
+ }
41
+
42
+ const includeList = distFileFilters.include || [];
43
+ const excludeList = distFileFilters.exclude || [];
44
+
45
+ if (includeList.length > 0) {
46
+ const included = includeList.some((item) =>
47
+ matchDistFileFilter(relativePath, item)
48
+ );
49
+ if (!included) {
50
+ return false;
33
51
  }
34
52
  }
53
+
54
+ if (excludeList.length > 0) {
55
+ const excluded = excludeList.some((item) =>
56
+ matchDistFileFilter(relativePath, item)
57
+ );
58
+ if (excluded) {
59
+ return false;
60
+ }
61
+ }
62
+
63
+ return true;
35
64
  }
36
65
 
37
- export function genProjectArchiveBuffer(distPath) {
66
+ function collectDistFiles(distPath, distFileFilters) {
67
+ const files = [];
68
+
69
+ function walk(dir) {
70
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
71
+ const fullPath = path.join(dir, entry.name);
72
+ if (entry.isDirectory()) {
73
+ walk(fullPath);
74
+ continue;
75
+ }
76
+
77
+ const relativePath = toPosixRelativePath(distPath, fullPath);
78
+ if (shouldIncludeDistFile(relativePath, distFileFilters)) {
79
+ files.push({ fullPath, relativePath });
80
+ }
81
+ }
82
+ }
83
+
84
+ walk(distPath);
85
+ return files;
86
+ }
87
+
88
+ function appendFilesToArchive(archive, files, zipPrefix) {
89
+ for (const { fullPath, relativePath } of files) {
90
+ const zipPath = zipPrefix
91
+ ? path.posix.join(zipPrefix, relativePath)
92
+ : relativePath;
93
+ archive.file(fullPath, { name: zipPath });
94
+ }
95
+ }
96
+
97
+ export function validateDistFileFilters(distFileFilters) {
98
+ if (distFileFilters == null) {
99
+ return;
100
+ }
101
+ if (typeof distFileFilters !== "object" || Array.isArray(distFileFilters)) {
102
+ throw new Error("distFileFilters 必须是包含 include/exclude 的对象");
103
+ }
104
+
105
+ for (const key of ["include", "exclude"]) {
106
+ const list = distFileFilters[key];
107
+ if (list == null) {
108
+ continue;
109
+ }
110
+ if (!Array.isArray(list)) {
111
+ throw new Error(`distFileFilters.${key} 必须是数组`);
112
+ }
113
+ for (const item of list) {
114
+ if (typeof item === "string") {
115
+ continue;
116
+ }
117
+ if (item && typeof item.regex === "string") {
118
+ continue;
119
+ }
120
+ throw new Error(`无效的 distFileFilters.${key} 规则: ${JSON.stringify(item)}`);
121
+ }
122
+ }
123
+ }
124
+
125
+ export function genProjectArchiveBuffer(distPath, distFileFilters) {
38
126
  return archiveToBuffer((archive) => {
39
- archive.directory(distPath, false);
127
+ const files = collectDistFiles(distPath, distFileFilters);
128
+ appendFilesToArchive(archive, files);
40
129
  });
41
130
  }
42
131
 
43
132
  /**
44
133
  * lib 类型 CDN 打包:若 dist 内仅有名为 version 的子目录则原样打包;
45
- * 若无子目录则为 zip 内所有文件加上 version 前缀。
134
+ * 否则为 zip 内所有文件加上 version 前缀。
46
135
  */
47
- export function genLibArchiveBuffer(distPath, version) {
136
+ export function genLibArchiveBuffer(distPath, version, distFileFilters) {
48
137
  const subdirs = fs
49
138
  .readdirSync(distPath, { withFileTypes: true })
50
139
  .filter((entry) => entry.isDirectory());
51
140
 
52
141
  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
- }
142
+ const files = collectDistFiles(distPath, distFileFilters);
143
+ const zipPrefix =
144
+ subdirs.length === 1 && subdirs[0].name === version ? "" : version;
145
+ appendFilesToArchive(archive, files, zipPrefix);
60
146
  });
61
147
  }
@@ -5,6 +5,7 @@ import { getCache as getLoginCache } from "./login.mjs";
5
5
  import {
6
6
  genLibArchiveBuffer,
7
7
  genProjectArchiveBuffer,
8
+ validateDistFileFilters,
8
9
  } from "./archive.mjs";
9
10
 
10
11
  const isDev = false;
@@ -102,6 +103,8 @@ export async function lightDeploy(config, mode) {
102
103
  const workDir = process.cwd();
103
104
  const distDir = config.distDir || "dist";
104
105
  const distPath = path.join(workDir, distDir);
106
+ const distFileFilters = config.distFileFilters;
107
+ validateDistFileFilters(distFileFilters);
105
108
  if (!fs.existsSync(distPath)) {
106
109
  throw new Error(`${distPath} 不存在,请先执行构建`);
107
110
  }
@@ -109,8 +112,8 @@ export async function lightDeploy(config, mode) {
109
112
  log(`开始打包 ${distPath}`);
110
113
  const distZipBuffer =
111
114
  cdnType === "lib"
112
- ? await genLibArchiveBuffer(distPath, version)
113
- : await genProjectArchiveBuffer(distPath);
115
+ ? await genLibArchiveBuffer(distPath, version, distFileFilters)
116
+ : await genProjectArchiveBuffer(distPath, distFileFilters);
114
117
  log(`打包完成,大小 ${distZipBuffer.length} 字节`);
115
118
 
116
119
  const includeHtml = config.includeHtml === true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taole/deploy-helper",
3
- "version": "1.1.6",
3
+ "version": "1.1.8-beta.1",
4
4
  "description": "脚本部署工具,用于将项目部署到测试环境或生产环境",
5
5
  "main": "index.mjs",
6
6
  "type": "module",