@savvy-web/bundler 0.5.0 → 0.6.0
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/config.js +4 -1
- package/index.d.ts +2 -0
- package/package.json +2 -2
- package/run.js +60 -13
package/config.js
CHANGED
|
@@ -26,14 +26,17 @@ function defineBuild(input = {}) {
|
|
|
26
26
|
function parseArgs(argv) {
|
|
27
27
|
let target = "dev";
|
|
28
28
|
let watch = false;
|
|
29
|
+
let noExe = false;
|
|
29
30
|
for (let i = 0; i < argv.length; i++) if (argv[i] === "--target") {
|
|
30
31
|
const v = argv[i + 1];
|
|
31
32
|
if (v === "dev" || v === "prod" || v === "meta" || v === "exe") target = v;
|
|
32
33
|
i++;
|
|
33
34
|
} else if (argv[i] === "--watch") watch = true;
|
|
35
|
+
else if (argv[i] === "--no-exe") noExe = true;
|
|
34
36
|
return {
|
|
35
37
|
target,
|
|
36
|
-
watch
|
|
38
|
+
watch,
|
|
39
|
+
noExe
|
|
37
40
|
};
|
|
38
41
|
}
|
|
39
42
|
|
package/index.d.ts
CHANGED
|
@@ -173,6 +173,8 @@ declare function defineBuild(input?: BuildConfigInput): BuildConfig;
|
|
|
173
173
|
interface ParsedArgs {
|
|
174
174
|
readonly target: "dev" | "prod" | "meta" | "exe";
|
|
175
175
|
readonly watch: boolean;
|
|
176
|
+
/** Skip the SEA compile step of a dev/prod build (the manifest is still programmed). Used by `prepare`. */
|
|
177
|
+
readonly noExe: boolean;
|
|
176
178
|
}
|
|
177
179
|
declare function parseArgs(argv: ReadonlyArray<string>): ParsedArgs;
|
|
178
180
|
//#endregion
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@savvy-web/bundler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Zero-config tsdown-based bundler for Silk Suite TypeScript packages",
|
|
6
6
|
"homepage": "https://github.com/savvy-web/systems/tree/main/packages/bundler",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"./package.json": "./package.json"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@savvy-web/tsdown-plugins": "0.
|
|
32
|
+
"@savvy-web/tsdown-plugins": "0.6.0",
|
|
33
33
|
"@tsdown/exe": "^0.22.1",
|
|
34
34
|
"tsdown": "^0.22.2"
|
|
35
35
|
},
|
package/run.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { parseArgs } from "./config.js";
|
|
2
|
-
import { ConfigValidator, ConfigValidatorLive, ReportPipelineLive, buildTargetGroups, createEntryName, generateMeta, normalizeExeOptions, normalizeLooseFiles, normalizeMetaOptions, packageJsonEntries, readTsconfigJsx, removeDeclarationMaps, renderReport, resolveJsxConfig, resolveTargets, runExeBuild, writeResolvedTsconfig, writeTargetsBinding } from "@savvy-web/tsdown-plugins";
|
|
3
|
-
import { readFileSync } from "node:fs";
|
|
2
|
+
import { ConfigValidator, ConfigValidatorLive, ReportPipelineLive, buildEmittedManifest, buildTargetGroups, computeExeFileName, createEntryName, generateMeta, normalizeExeOptions, normalizeLooseFiles, normalizeMetaOptions, packageJsonEntries, readTsconfigJsx, removeDeclarationMaps, renderReport, resolveJsxConfig, resolveTargets, runExeBuild, writeResolvedTsconfig, writeTargetsBinding } from "@savvy-web/tsdown-plugins";
|
|
3
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { Effect } from "effect";
|
|
6
6
|
|
|
@@ -74,7 +74,7 @@ function applySubdirMetaEntries(overrides, dtsBasenames, exportPaths) {
|
|
|
74
74
|
}
|
|
75
75
|
/** Run a build from a normalized config. Pure orchestration; all IO injectable. */
|
|
76
76
|
async function runBuild(config, options) {
|
|
77
|
-
const { target } = parseArgs(options.argv);
|
|
77
|
+
const { target, noExe } = parseArgs(options.argv);
|
|
78
78
|
const build = options.buildTargetGroups ?? buildTargetGroups;
|
|
79
79
|
const cwd = options.cwd;
|
|
80
80
|
const pkg = readPackageJson(cwd);
|
|
@@ -89,10 +89,6 @@ async function runBuild(config, options) {
|
|
|
89
89
|
} : {},
|
|
90
90
|
...jsx?.runtime === "classic" ? { jsx: "react" } : {}
|
|
91
91
|
})))(cwd);
|
|
92
|
-
const entries = packageJsonEntries({
|
|
93
|
-
pkg,
|
|
94
|
-
cwd
|
|
95
|
-
});
|
|
96
92
|
const exportsMap = options.readExports ? options.readExports() : pkg.exports;
|
|
97
93
|
const runGenerateMeta = options.generateMeta ?? generateMeta;
|
|
98
94
|
const publishTargets = (options.readPublishTargets ?? (() => {
|
|
@@ -113,6 +109,23 @@ async function runBuild(config, options) {
|
|
|
113
109
|
...config.meta !== void 0 && config.meta !== false ? { meta: config.meta } : {},
|
|
114
110
|
...config.looseFiles !== void 0 ? { looseFiles: config.looseFiles } : {}
|
|
115
111
|
})).pipe(Effect.provide(ConfigValidatorLive)));
|
|
112
|
+
const exeSpecs = config.exe !== void 0 ? normalizeExeOptions(config.exe, osCpuForValidate) : [];
|
|
113
|
+
if (config.exe !== void 0 && (exeSpecs.length !== 1 || (exeSpecs[0]?.targets.length ?? 0) !== 1)) throw new Error(`exe build requires exactly one binary with one target (got ${exeSpecs.length} spec(s), ${exeSpecs[0]?.targets.length ?? 0} target(s) on the first). A package's exports["."] resolves to a single SEA — cross-platform binaries must each ship as their own per-platform package.`);
|
|
114
|
+
const exeSpec = exeSpecs[0];
|
|
115
|
+
const exeTarget = exeSpec?.targets[0];
|
|
116
|
+
const exeFileName = exeSpec && exeTarget ? computeExeFileName(exeSpec.fileName, exeTarget) : void 0;
|
|
117
|
+
const exeEntrySource = exeSpec?.entry ?? "./src/bin.ts";
|
|
118
|
+
const exeRewrite = config.exe !== void 0 && exeFileName !== void 0 ? {
|
|
119
|
+
source: exeEntrySource,
|
|
120
|
+
fileName: exeFileName,
|
|
121
|
+
dir: "bin"
|
|
122
|
+
} : void 0;
|
|
123
|
+
const entries = packageJsonEntries({
|
|
124
|
+
pkg,
|
|
125
|
+
cwd,
|
|
126
|
+
...config.exe !== void 0 ? { excludeSources: [exeEntrySource] } : {}
|
|
127
|
+
});
|
|
128
|
+
const hasJsEntries = Object.keys(entries).length > 0;
|
|
116
129
|
validateSubdirOverrides(config.overrides, entries, packageName);
|
|
117
130
|
if (target === "meta") {
|
|
118
131
|
if (config.meta === false) {
|
|
@@ -148,16 +161,15 @@ async function runBuild(config, options) {
|
|
|
148
161
|
}
|
|
149
162
|
if (target === "exe") {
|
|
150
163
|
if (config.exe === void 0) throw new Error("`savvy build --target exe` requires an `exe` option in the build config");
|
|
151
|
-
const specs = normalizeExeOptions(config.exe, osCpuForValidate);
|
|
152
164
|
await (options.runExeBuild ?? runExeBuild)({
|
|
153
165
|
cwd,
|
|
154
166
|
outDir: join(cwd, "dist", "dev", "pkg", "bin"),
|
|
155
|
-
specs
|
|
167
|
+
specs: exeSpecs
|
|
156
168
|
});
|
|
157
169
|
(options.writeOutput ?? ((o) => process.stdout.write(`${o.content}\n`)))({
|
|
158
170
|
target: "stdout",
|
|
159
171
|
contentType: "text/plain",
|
|
160
|
-
content: `exe: compiled ${
|
|
172
|
+
content: `exe: compiled ${exeSpecs.length} binary/binaries for ${packageName}`
|
|
161
173
|
});
|
|
162
174
|
return;
|
|
163
175
|
}
|
|
@@ -217,7 +229,7 @@ async function runBuild(config, options) {
|
|
|
217
229
|
}],
|
|
218
230
|
resolution: void 0
|
|
219
231
|
} : deriveProdGroups(publishTargets, packageName);
|
|
220
|
-
await build({
|
|
232
|
+
if (hasJsEntries || config.exe === void 0) await build({
|
|
221
233
|
cwd,
|
|
222
234
|
version,
|
|
223
235
|
entry: config.overrides !== void 0 ? baseEntries : entries,
|
|
@@ -237,10 +249,11 @@ async function runBuild(config, options) {
|
|
|
237
249
|
...overridePartitions.length > 0 ? { overrides: overridePartitions } : {},
|
|
238
250
|
...dualExports !== void 0 ? { dualExports } : {},
|
|
239
251
|
...subdirExports.size > 0 ? { subdirExports } : {},
|
|
240
|
-
...looseFiles !== void 0 ? { looseFiles } : {}
|
|
252
|
+
...looseFiles !== void 0 ? { looseFiles } : {},
|
|
253
|
+
...exeRewrite !== void 0 ? { exeRewrite } : {}
|
|
241
254
|
});
|
|
242
255
|
if (target === "prod" && resolution !== void 0) writeBinding(cwd, resolution);
|
|
243
|
-
if (target === "prod" && config.meta !== false) {
|
|
256
|
+
if (target === "prod" && config.meta !== false && (config.exe === void 0 || hasJsEntries)) {
|
|
244
257
|
const metaGroupId = (groups.find((g) => g.name === packageName) ?? groups[0])?.id ?? "npm";
|
|
245
258
|
const norm = normalizeMetaOptions(config.meta ?? {});
|
|
246
259
|
const dtsBasenames = {};
|
|
@@ -260,6 +273,40 @@ async function runBuild(config, options) {
|
|
|
260
273
|
});
|
|
261
274
|
}
|
|
262
275
|
if (target === "prod") for (const g of groups) removeDeclarationMaps(join(cwd, "dist", "prod", g.id, "pkg"));
|
|
276
|
+
if (config.exe !== void 0 && exeSpec !== void 0 && exeRewrite !== void 0 && exeFileName !== void 0) {
|
|
277
|
+
const runExe = options.runExeBuild ?? runExeBuild;
|
|
278
|
+
const groupOutDir = (g) => target === "dev" ? join(cwd, "dist", "dev", "pkg") : join(cwd, "dist", "prod", g.id, "pkg");
|
|
279
|
+
for (const g of groups) {
|
|
280
|
+
const outDir = groupOutDir(g);
|
|
281
|
+
if (!hasJsEntries) {
|
|
282
|
+
const manifest = await buildEmittedManifest({
|
|
283
|
+
pkg,
|
|
284
|
+
targetGroup: {
|
|
285
|
+
id: g.id,
|
|
286
|
+
name: g.name,
|
|
287
|
+
isProd: target === "prod"
|
|
288
|
+
},
|
|
289
|
+
devManifest: config.devManifest,
|
|
290
|
+
...config.transform !== void 0 ? { transform: config.transform } : {},
|
|
291
|
+
exeRewrite
|
|
292
|
+
});
|
|
293
|
+
mkdirSync(outDir, { recursive: true });
|
|
294
|
+
writeFileSync(join(outDir, "package.json"), `${JSON.stringify(manifest, null, " ")}\n`);
|
|
295
|
+
for (const file of ["LICENSE", "README.md"]) try {
|
|
296
|
+
copyFileSync(join(cwd, file), join(outDir, file));
|
|
297
|
+
} catch {}
|
|
298
|
+
}
|
|
299
|
+
if (!noExe) {
|
|
300
|
+
const binDir = join(outDir, "bin");
|
|
301
|
+
await runExe({
|
|
302
|
+
cwd,
|
|
303
|
+
outDir: binDir,
|
|
304
|
+
specs: exeSpecs
|
|
305
|
+
});
|
|
306
|
+
if (options.runExeBuild === void 0 && !existsSync(join(binDir, exeFileName))) throw new Error(`exe: expected compiled binary at ${join(binDir, exeFileName)} but it is missing — tsdown's emitted name may have drifted from computeExeFileName`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
263
310
|
const totalMs = Date.now() - startMs;
|
|
264
311
|
const reportEntries = Object.keys(entries);
|
|
265
312
|
const report = {
|