-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrollup.config.cjs
More file actions
181 lines (158 loc) · 6.17 KB
/
rollup.config.cjs
File metadata and controls
181 lines (158 loc) · 6.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
const typescript = require("@rollup/plugin-typescript");
const terser = require("@rollup/plugin-terser");
const { readdirSync, statSync, copyFileSync, rmSync, readFileSync } = require("fs");
const { resolve, extname, basename, dirname, relative } = require("path");
const minutes = 0.08;
const inputDir = resolve(__dirname, "src");
const distDir = resolve(__dirname, "dist");
const now = Date.now();
const modifiedTimeLimit = now - minutes * 60 * 1000;
// 递归遍历目录
const walk = (dir) => {
const files = [];
readdirSync(dir).forEach((f) => {
const fullPath = resolve(dir, f);
// 如果是 src/utils 目录,跳过
if (fullPath.includes('src/utils')) return;
const stats = statSync(fullPath);
if (stats.isDirectory()) {
files.push(...walk(fullPath));
} else if (extname(f) === ".tsx" && stats.mtimeMs >= modifiedTimeLimit) {
files.push(fullPath);
}
});
return files;
};
const recentFiles = walk(inputDir);
if (recentFiles.length === 0) {
console.log(`没有在过去 ${minutes} 分钟内修改的 .tsx 文件。`);
process.exit(0);
}
// 清理 dist 目录中多余的文件和目录
const cleanDist = (srcDir, distDir) => {
const srcFiles = new Set(readdirSync(srcDir).map((f) => resolve(srcDir, f)));
const distFiles = readdirSync(distDir).map((f) => resolve(distDir, f));
distFiles.forEach((distFile) => {
const stats = statSync(distFile);
const distExt = extname(distFile);
const relPath = distFile.slice(distDir.length + 1); // 获取相对路径
const srcFile = resolve(srcDir, relPath.replace(/\.jsx$/, ".tsx")); // 假设它可能是由 .tsx 生成
if (stats.isDirectory()) {
// 如果是目录,递归处理之前先检查 src 中是否存在该目录
if (srcFiles.has(srcFile)) {
cleanDist(srcFile, distFile); // 如果 src 中存在该目录,才递归
} else {
// 如果 src 中没有该目录,删除 dist 中的目录
console.log(`删除目录 ${distFile}`);
rmSync(distFile, { recursive: true, force: true });
}
return;
}
const srcExists = srcFiles.has(srcFile);
if (srcExists) {
const srcExt = extname(srcFile);
if (distExt === ".jsx" && srcExt === ".tsx") {
// 如果 .jsx 文件对应 .tsx 文件,则保留
return;
}
// 删除与 .tsx 文件同名但后缀不为 .jsx 的文件
console.log(`删除文件 ${distFile}`);
rmSync(distFile, { force: true });
} else {
// 如果 src 中不存在对应的文件,删除 dist 文件
console.log(`删除文件 ${distFile}`);
rmSync(distFile, { force: true });
}
});
};
// 清理 dist 目录
console.log("清理 dist 目录中...");
cleanDist(inputDir, distDir);
console.log("dist 目录清理完成。");
// 复制非 .tsx 文件
const copyNonTsxFiles = (inputPath, outputPath) => {
const inputDir = dirname(inputPath);
const outputDir = dirname(outputPath);
try {
require("fs").mkdirSync(outputDir, { recursive: true });
} catch (e) {
console.error(`无法创建输出目录 ${outputDir}: ${e.message}`);
}
readdirSync(inputDir).forEach((f) => {
const fullPath = resolve(inputDir, f);
const stats = statSync(fullPath);
if (!stats.isDirectory() && extname(f) !== ".tsx") {
const outputFilePath = resolve(outputDir, f);
copyFileSync(fullPath, outputFilePath);
console.log(`复制文件 ${fullPath} 到 ${outputFilePath}`);
}
});
};
// 自定义插件:替换占位符为图片数据
// 使用方法:在 .tsx 文件中使用 __IMAGE_PLACEHOLDER__(图片路径) 占位符,例如 __IMAGE_PLACEHOLDER__(./images/icon.png)
const replacePlaceholders = () => {
return {
name: 'replace-placeholders',
transform(code, id) {
if (extname(id) !== '.tsx') return null;
// 替换占位符
const placeholderRegex = /__IMAGE_PLACEHOLDER__\((.*?)\)/g;
let match;
let transformedCode = code;
while ((match = placeholderRegex.exec(code)) !== null) {
const imagePath = match[1];
const imageData = readFileSync(resolve(__dirname, imagePath), 'base64');
transformedCode = transformedCode.replace(match[0], `"data:image/png;base64,${imageData}"`);
}
return {
code: transformedCode,
map: null
};
}
};
};
const configs = recentFiles.map((file) => {
const inputPath = file;
const outputPath = file.replace(inputDir, distDir).replace(extname(file), ".jsx");
// 复制非 .tsx 文件
copyNonTsxFiles(inputPath, outputPath);
return {
input: inputPath,
output: {
file: outputPath,
// format: "iife",
intro: "(function () {",
outro: "}).call(this);",
sourcemap: false,
},
plugins: [
typescript(),
replacePlaceholders(), // 添加自定义插件
terser({
compress: false,
mangle: false,
format: {
beautify: true,
braces: true,
comments: false,
keep_quoted_props: true,
keep_numbers: true,
preamble: [
"// 本脚本基于Soil/at_script开发",
"// Soil作者: Raymond Yan (raymondclr@foxmail.com / qq: 1107677019)",
"// Soil Github: https://github.com/RaymondClr/Soil",
"",
`// - ${new Date().toLocaleString()}`,
].join("\n"),
wrap_func_args: false,
},
}),
],
treeshake: {
propertyReadSideEffects: false,
unknownGlobalSideEffects: false,
},
context: "this",
};
});
module.exports = configs;