@zappdev/vite 0.5.0-alpha.0 → 0.5.0-alpha.2
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/dist/index.js +200 -0
- package/package.json +8 -3
- package/src/index.ts +36 -12
package/dist/index.js
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
3
|
+
|
|
4
|
+
// src/index.ts
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { existsSync } from "node:fs";
|
|
7
|
+
import { mkdir, readdir, readFile } from "node:fs/promises";
|
|
8
|
+
var WORKER_PATTERN = /new\s+(?:SharedWorker|Worker)\s*\(\s*(?:new\s+URL\(\s*["'`](.+?)["'`]\s*,\s*import\.meta\.url\s*\)|["'`](.+?)["'`])/g;
|
|
9
|
+
async function scanDir(dir) {
|
|
10
|
+
const results = [];
|
|
11
|
+
try {
|
|
12
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
13
|
+
for (const entry of entries) {
|
|
14
|
+
if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "zapp")
|
|
15
|
+
continue;
|
|
16
|
+
const full = path.join(dir, entry.name);
|
|
17
|
+
if (entry.isDirectory()) {
|
|
18
|
+
results.push(...await scanDir(full));
|
|
19
|
+
} else if (/\.(ts|tsx|js|jsx|mjs)$/.test(entry.name)) {
|
|
20
|
+
results.push(full);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
} catch {}
|
|
24
|
+
return results;
|
|
25
|
+
}
|
|
26
|
+
async function discoverWorkers(srcDir) {
|
|
27
|
+
const files = await scanDir(srcDir);
|
|
28
|
+
const found = new Map;
|
|
29
|
+
for (const file of files) {
|
|
30
|
+
const content = await readFile(file, "utf-8");
|
|
31
|
+
let match;
|
|
32
|
+
WORKER_PATTERN.lastIndex = 0;
|
|
33
|
+
while ((match = WORKER_PATTERN.exec(content)) !== null) {
|
|
34
|
+
const spec = match[1] || match[2];
|
|
35
|
+
if (!spec || found.has(spec))
|
|
36
|
+
continue;
|
|
37
|
+
const sourcePath = path.resolve(path.dirname(file), spec);
|
|
38
|
+
const baseName = path.basename(spec).replace(/\.[^.]+$/, "");
|
|
39
|
+
found.set(spec, {
|
|
40
|
+
specifier: spec,
|
|
41
|
+
sourcePath,
|
|
42
|
+
outputName: `${baseName}.mjs`,
|
|
43
|
+
outputUrl: `/_workers/${baseName}.mjs`
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return [...found.values()];
|
|
48
|
+
}
|
|
49
|
+
async function bundleWorker(entry, outDir, aliases) {
|
|
50
|
+
try {
|
|
51
|
+
const vite = await import("vite");
|
|
52
|
+
await vite.build({
|
|
53
|
+
configFile: false,
|
|
54
|
+
logLevel: "silent",
|
|
55
|
+
build: {
|
|
56
|
+
outDir,
|
|
57
|
+
emptyOutDir: false,
|
|
58
|
+
minify: true,
|
|
59
|
+
rollupOptions: {
|
|
60
|
+
input: entry.sourcePath,
|
|
61
|
+
output: {
|
|
62
|
+
format: "es",
|
|
63
|
+
entryFileNames: entry.outputName,
|
|
64
|
+
dir: outDir
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
resolve: { alias: aliases }
|
|
69
|
+
});
|
|
70
|
+
return true;
|
|
71
|
+
} catch (e) {
|
|
72
|
+
console.error(`[zapp] worker bundle failed: ${entry.specifier}`, e);
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function zappWorkers(options) {
|
|
77
|
+
let root = "";
|
|
78
|
+
let srcDir = "";
|
|
79
|
+
let workers = [];
|
|
80
|
+
let backendEntry = null;
|
|
81
|
+
let aliases = {};
|
|
82
|
+
let isDev = false;
|
|
83
|
+
let outDir = "";
|
|
84
|
+
let backendFromConfig = options?.backend;
|
|
85
|
+
return {
|
|
86
|
+
name: "zapp-workers",
|
|
87
|
+
enforce: "pre",
|
|
88
|
+
async configResolved(config) {
|
|
89
|
+
root = config.root;
|
|
90
|
+
srcDir = path.join(root, "src");
|
|
91
|
+
outDir = path.join(root, "dist", "_workers");
|
|
92
|
+
isDev = config.command === "serve";
|
|
93
|
+
const resolvedAlias = config.resolve?.alias;
|
|
94
|
+
if (resolvedAlias && typeof resolvedAlias === "object" && !Array.isArray(resolvedAlias)) {
|
|
95
|
+
aliases = resolvedAlias;
|
|
96
|
+
}
|
|
97
|
+
if (!backendFromConfig) {
|
|
98
|
+
try {
|
|
99
|
+
const configPath = path.join(root, "zapp.config.ts");
|
|
100
|
+
const mod = await import(configPath);
|
|
101
|
+
const zappConfig = typeof mod.default === "function" ? mod.default() : mod.default;
|
|
102
|
+
if (zappConfig?.backend) {
|
|
103
|
+
backendFromConfig = zappConfig.backend;
|
|
104
|
+
}
|
|
105
|
+
} catch {}
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
async buildStart() {
|
|
109
|
+
workers = await discoverWorkers(srcDir);
|
|
110
|
+
const backendSrc = backendFromConfig ? path.resolve(root, backendFromConfig) : path.join(srcDir, "backend.ts");
|
|
111
|
+
if (existsSync(backendSrc)) {
|
|
112
|
+
backendEntry = {
|
|
113
|
+
specifier: path.relative(srcDir, backendSrc),
|
|
114
|
+
sourcePath: backendSrc,
|
|
115
|
+
outputName: "backend.mjs",
|
|
116
|
+
outputUrl: "/_workers/backend.mjs"
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (workers.length > 0) {
|
|
120
|
+
console.log(`[zapp] discovered ${workers.length} worker(s)`);
|
|
121
|
+
}
|
|
122
|
+
if (backendEntry) {
|
|
123
|
+
console.log(`[zapp] backend worker: ${path.relative(root, backendSrc)}`);
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
transform(code, id) {
|
|
127
|
+
if (!id.endsWith(".ts") && !id.endsWith(".tsx") && !id.endsWith(".js") && !id.endsWith(".jsx"))
|
|
128
|
+
return null;
|
|
129
|
+
if (id.includes("node_modules"))
|
|
130
|
+
return null;
|
|
131
|
+
let modified = false;
|
|
132
|
+
let result = code;
|
|
133
|
+
for (const entry of workers) {
|
|
134
|
+
const escaped = entry.specifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
135
|
+
const regex = new RegExp(`(new\\s+(?:SharedWorker|Worker)\\s*\\(\\s*["'\`])${escaped}(["'\`])`, "g");
|
|
136
|
+
const replaced = result.replace(regex, `$1${entry.outputUrl}$2`);
|
|
137
|
+
if (replaced !== result) {
|
|
138
|
+
result = replaced;
|
|
139
|
+
modified = true;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return modified ? { code: result, map: null } : null;
|
|
143
|
+
},
|
|
144
|
+
async configureServer(server) {
|
|
145
|
+
const devOutDir = path.join(root, ".zapp", "workers");
|
|
146
|
+
await mkdir(devOutDir, { recursive: true });
|
|
147
|
+
workers = await discoverWorkers(srcDir);
|
|
148
|
+
const backendSrc = backendFromConfig ? path.resolve(root, backendFromConfig) : path.join(srcDir, "backend.ts");
|
|
149
|
+
if (existsSync(backendSrc)) {
|
|
150
|
+
backendEntry = {
|
|
151
|
+
specifier: path.relative(srcDir, backendSrc),
|
|
152
|
+
sourcePath: backendSrc,
|
|
153
|
+
outputName: "backend.mjs",
|
|
154
|
+
outputUrl: "/_workers/backend.mjs"
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
const allEntries = [...workers];
|
|
158
|
+
if (backendEntry)
|
|
159
|
+
allEntries.push(backendEntry);
|
|
160
|
+
for (const entry of allEntries) {
|
|
161
|
+
const ok = await bundleWorker(entry, devOutDir, aliases);
|
|
162
|
+
if (ok)
|
|
163
|
+
console.log(`[zapp] dev-bundled worker: ${entry.outputName}`);
|
|
164
|
+
}
|
|
165
|
+
server.middlewares.use(async (req, res, next) => {
|
|
166
|
+
if (!req.url?.startsWith("/_workers/"))
|
|
167
|
+
return next();
|
|
168
|
+
const fileName = req.url.slice("/_workers/".length);
|
|
169
|
+
const filePath = path.join(devOutDir, fileName);
|
|
170
|
+
if (existsSync(filePath)) {
|
|
171
|
+
const content = await readFile(filePath, "utf-8");
|
|
172
|
+
res.setHeader("Content-Type", "application/javascript");
|
|
173
|
+
res.end(content);
|
|
174
|
+
} else {
|
|
175
|
+
res.statusCode = 404;
|
|
176
|
+
res.end("Worker not found");
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
},
|
|
180
|
+
async generateBundle() {
|
|
181
|
+
if (isDev)
|
|
182
|
+
return;
|
|
183
|
+
await mkdir(outDir, { recursive: true });
|
|
184
|
+
const allEntries = [...workers];
|
|
185
|
+
if (backendEntry)
|
|
186
|
+
allEntries.push(backendEntry);
|
|
187
|
+
for (const entry of allEntries) {
|
|
188
|
+
const ok = await bundleWorker(entry, outDir, aliases);
|
|
189
|
+
if (ok) {
|
|
190
|
+
console.log(`[zapp] bundled worker: ${entry.outputName}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
var src_default = zappWorkers;
|
|
197
|
+
export {
|
|
198
|
+
zappWorkers,
|
|
199
|
+
src_default as default
|
|
200
|
+
};
|
package/package.json
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zappdev/vite",
|
|
3
|
-
"version": "0.5.0-alpha.
|
|
3
|
+
"version": "0.5.0-alpha.2",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "dist/index.js",
|
|
6
6
|
"types": "src/index.ts",
|
|
7
7
|
"exports": {
|
|
8
|
-
".": "./
|
|
8
|
+
".": "./dist/index.js"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
|
+
"dist/",
|
|
11
12
|
"src/"
|
|
12
13
|
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "bun build src/index.ts --outdir dist --format esm --target node",
|
|
16
|
+
"prepack": "bun run build"
|
|
17
|
+
},
|
|
13
18
|
"peerDependencies": {
|
|
14
19
|
"vite": ">=5.0.0"
|
|
15
20
|
}
|
package/src/index.ts
CHANGED
|
@@ -104,7 +104,12 @@ async function bundleWorker(entry: WorkerEntry, outDir: string, aliases: Record<
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
interface ZappWorkersOptions {
|
|
108
|
+
/** Path to backend worker source, relative to project root. Overrides zapp.config.ts. */
|
|
109
|
+
backend?: string;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function zappWorkers(options?: ZappWorkersOptions): Plugin {
|
|
108
113
|
let root = "";
|
|
109
114
|
let srcDir = "";
|
|
110
115
|
let workers: WorkerEntry[] = [];
|
|
@@ -112,12 +117,13 @@ export function zappWorkers(): Plugin {
|
|
|
112
117
|
let aliases: Record<string, string> = {};
|
|
113
118
|
let isDev = false;
|
|
114
119
|
let outDir = "";
|
|
120
|
+
let backendFromConfig = options?.backend;
|
|
115
121
|
|
|
116
122
|
return {
|
|
117
123
|
name: "zapp-workers",
|
|
118
124
|
enforce: "pre",
|
|
119
125
|
|
|
120
|
-
configResolved(config) {
|
|
126
|
+
async configResolved(config) {
|
|
121
127
|
root = config.root;
|
|
122
128
|
srcDir = path.join(root, "src");
|
|
123
129
|
outDir = path.join(root, "dist", "_workers");
|
|
@@ -128,18 +134,34 @@ export function zappWorkers(): Plugin {
|
|
|
128
134
|
if (resolvedAlias && typeof resolvedAlias === "object" && !Array.isArray(resolvedAlias)) {
|
|
129
135
|
aliases = resolvedAlias as Record<string, string>;
|
|
130
136
|
}
|
|
137
|
+
|
|
138
|
+
// Auto-read backend path from zapp.config.ts if not passed as option
|
|
139
|
+
if (!backendFromConfig) {
|
|
140
|
+
try {
|
|
141
|
+
const configPath = path.join(root, "zapp.config.ts");
|
|
142
|
+
const mod = await import(configPath);
|
|
143
|
+
const zappConfig = typeof mod.default === "function" ? mod.default() : mod.default;
|
|
144
|
+
if (zappConfig?.backend) {
|
|
145
|
+
backendFromConfig = zappConfig.backend;
|
|
146
|
+
}
|
|
147
|
+
} catch {
|
|
148
|
+
// No zapp.config.ts or no backend field — that's fine
|
|
149
|
+
}
|
|
150
|
+
}
|
|
131
151
|
},
|
|
132
152
|
|
|
133
153
|
async buildStart() {
|
|
134
154
|
// Discover workers from source
|
|
135
155
|
workers = await discoverWorkers(srcDir);
|
|
136
156
|
|
|
137
|
-
//
|
|
138
|
-
const
|
|
139
|
-
|
|
157
|
+
// Backend worker — path from config, or fall back to src/backend.ts convention
|
|
158
|
+
const backendSrc = backendFromConfig
|
|
159
|
+
? path.resolve(root, backendFromConfig)
|
|
160
|
+
: path.join(srcDir, "backend.ts");
|
|
161
|
+
if (existsSync(backendSrc)) {
|
|
140
162
|
backendEntry = {
|
|
141
|
-
specifier:
|
|
142
|
-
sourcePath:
|
|
163
|
+
specifier: path.relative(srcDir, backendSrc),
|
|
164
|
+
sourcePath: backendSrc,
|
|
143
165
|
outputName: "backend.mjs",
|
|
144
166
|
outputUrl: "/_workers/backend.mjs",
|
|
145
167
|
};
|
|
@@ -149,7 +171,7 @@ export function zappWorkers(): Plugin {
|
|
|
149
171
|
console.log(`[zapp] discovered ${workers.length} worker(s)`);
|
|
150
172
|
}
|
|
151
173
|
if (backendEntry) {
|
|
152
|
-
console.log(
|
|
174
|
+
console.log(`[zapp] backend worker: ${path.relative(root, backendSrc)}`);
|
|
153
175
|
}
|
|
154
176
|
},
|
|
155
177
|
|
|
@@ -187,11 +209,13 @@ export function zappWorkers(): Plugin {
|
|
|
187
209
|
await mkdir(devOutDir, { recursive: true });
|
|
188
210
|
|
|
189
211
|
workers = await discoverWorkers(srcDir);
|
|
190
|
-
const
|
|
191
|
-
|
|
212
|
+
const backendSrc = backendFromConfig
|
|
213
|
+
? path.resolve(root, backendFromConfig)
|
|
214
|
+
: path.join(srcDir, "backend.ts");
|
|
215
|
+
if (existsSync(backendSrc)) {
|
|
192
216
|
backendEntry = {
|
|
193
|
-
specifier:
|
|
194
|
-
sourcePath:
|
|
217
|
+
specifier: path.relative(srcDir, backendSrc),
|
|
218
|
+
sourcePath: backendSrc,
|
|
195
219
|
outputName: "backend.mjs",
|
|
196
220
|
outputUrl: "/_workers/backend.mjs",
|
|
197
221
|
};
|