-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcombine.js
More file actions
139 lines (124 loc) · 4.51 KB
/
Copy pathcombine.js
File metadata and controls
139 lines (124 loc) · 4.51 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
import http from 'node:http';
import handler from 'serve-handler';
import { cwd, argv } from 'node:process';
import { basename, join, relative, resolve } from 'node:path';
import { readdirSync, existsSync, rmSync, mkdirSync, watch, watchFile } from 'node:fs';
import { copyfile, copydir } from './copy.js';
import { workspaces } from '../package.json';
const DIST_DIR = 'dist';
const INDEX_HTML = 'index.html';
const distDir = resolve(cwd(), DIST_DIR);
const publicDir = resolve(cwd(), 'public');
const isDev = Bun.env.BUN_ENV !== 'production';
const isWatch = argv[2] === 'watch';
const isClean = argv[2] === 'clean';
if (isClean && existsSync(distDir)) {
rmSync(distDir, { recursive: true, force: true });
mkdirSync(distDir, { recursive: true });
}
if (isWatch) {
http
.createServer((req, res) =>
handler(req, res, {
public: distDir,
}),
)
.listen(3000, () => {
console.log('Running at http://localhost:3000');
});
}
// 复制 public 文件夹
copydir(publicDir, distDir);
// 复制并监控项目
const watchAndCopyfile = (src, dist) => {
copyfile(src, dist);
// 添加监控
if (isWatch) {
watchFile(src, () => copyfile(src, dist));
}
};
// 复制并监控资源
const watchAndCopydir = (src, dist) => {
copydir(src, dist);
// 添加监控
if (isWatch) {
let timer = null;
let timestamp = 0;
watch(src, (_, f) => {
timestamp = Date.now();
if (!timer) {
timer = setInterval(() => {
if (Date.now() - timestamp < 1000) return;
copydir(src, dist);
clearInterval(timer);
timer = null;
}, 1000);
}
});
}
};
// 合并子模块和库文件
//
(async (imports) => {
// 核心 Preact 库文件
//
const runtimeFile = `preact/jsx-${isDev ? 'dev-' : ''}runtime`;
imports.preact = './preact/index.mjs';
imports['preact/hooks'] = './preact/hooks.mjs';
imports['preact/jsx-runtime'] = `./${runtimeFile}.mjs`;
imports['preact/jsx-dev-runtime'] = `./${runtimeFile}.mjs`;
imports['@preact/signals'] = './preact/signals.mjs';
imports['@preact/signals-core'] = './preact/signals-core.mjs';
// 复制文件
copyfile(Bun.resolveSync('preact', '.'), resolve(distDir, 'preact/index.mjs'));
copyfile(Bun.resolveSync('preact/hooks', '.'), resolve(distDir, 'preact/hooks.mjs'));
copyfile(Bun.resolveSync(runtimeFile, '.'), resolve(distDir, `${runtimeFile}.mjs`));
copyfile(Bun.resolveSync('@preact/signals', '.'), resolve(distDir, 'preact/signals.mjs'));
copyfile(Bun.resolveSync('@preact/signals-core', '.'), resolve(distDir, 'preact/signals-core.mjs'));
// 子模块文件
//
for (const workspace of workspaces) {
let path = resolve(cwd(), workspace.slice(0, -1));
const dirs = readdirSync(path, { withFileTypes: true }).filter((d) => d.isDirectory());
for (const dir of dirs) {
// 读取子模块 package.json
path = resolve(dir.parentPath, dir.name, 'package.json');
if (!existsSync(path)) continue;
path = relative(import.meta.dir, path);
path = path[0] !== '.' ? `./${path}` : path;
const { default: packageJson } = await import(path);
// 复制文件
if (packageJson.exports) {
for (const id in packageJson.exports) {
const src = resolve(dir.parentPath, dir.name, packageJson.exports[id].import);
const file = `${packageJson.name}/${basename(src)}`;
imports[join(packageJson.name, id)] = `./${file}`;
watchAndCopyfile(src, resolve(distDir, file));
}
} else if (packageJson.module) {
const src = resolve(dir.parentPath, dir.name, packageJson.module);
const file = `${packageJson.name}/${basename(packageJson.module)}`;
imports[packageJson.name] = `./${file}`;
watchAndCopyfile(src, resolve(distDir, file));
}
// 复制资源
// DIST_DIR 路径下的所有文件夹
readdirSync(resolve(dir.parentPath, dir.name, DIST_DIR), { withFileTypes: true })
.filter((d) => d.isDirectory())
.forEach((res) => {
const path = resolve(dir.parentPath, dir.name, DIST_DIR, res.name);
watchAndCopydir(path, resolve(distDir, res.name));
});
}
}
// 生成 index.html 文件
//
const file = resolve(publicDir, INDEX_HTML);
const html = await Bun.file(file).text();
const content = html.replace(
'<script type="importmap"></script>',
`<script type="importmap">{"imports":${JSON.stringify(imports)}}</script>`,
);
const outpath = resolve(distDir, INDEX_HTML);
Bun.write(outpath, content);
})({});