@chr33s/solarflare 0.0.4 → 0.0.7
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/bin/solarflare +3 -0
- package/package.json +3 -2
- package/src/build.bundle-client.ts +89 -71
- package/src/build.bundle-server.ts +64 -45
- package/src/build.bundle.ts +79 -1
- package/src/build.ts +6 -1
- package/src/solarflare.d.ts +3 -4
package/bin/solarflare
ADDED
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chr33s/solarflare",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/chr33s/solarflare"
|
|
8
8
|
},
|
|
9
9
|
"bin": {
|
|
10
|
-
"solarflare": "
|
|
10
|
+
"solarflare": "bin/solarflare"
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
|
+
"bin",
|
|
13
14
|
"src",
|
|
14
15
|
"tsconfig.json",
|
|
15
16
|
"!src/*.test.ts"
|
|
@@ -3,11 +3,18 @@ import { readFile, unlink, mkdir, writeFile } from "node:fs/promises";
|
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import ts from "typescript";
|
|
5
5
|
import { rolldown } from "rolldown";
|
|
6
|
+
import type { RolldownOptions } from "rolldown";
|
|
6
7
|
import { replacePlugin } from "rolldown/plugins";
|
|
7
8
|
import { transform } from "lightningcss";
|
|
8
9
|
import { createProgram, getDefaultExportInfo } from "./ast.ts";
|
|
9
10
|
import { exists } from "./fs.ts";
|
|
10
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
assetUrlPrefixPlugin,
|
|
13
|
+
type BuildArgs,
|
|
14
|
+
mergeInputOptions,
|
|
15
|
+
mergeOutputOptions,
|
|
16
|
+
moduleTypes,
|
|
17
|
+
} from "./build.bundle.ts";
|
|
11
18
|
import { parsePath } from "./paths.ts";
|
|
12
19
|
import { generateClientScript } from "./console-forward.ts";
|
|
13
20
|
import { createScanner } from "./build.scan.ts";
|
|
@@ -22,6 +29,7 @@ export interface BuildClientOptions {
|
|
|
22
29
|
distClient: string;
|
|
23
30
|
publicDir: string;
|
|
24
31
|
chunksPath: string;
|
|
32
|
+
userConfig?: RolldownOptions;
|
|
25
33
|
}
|
|
26
34
|
|
|
27
35
|
async function remove(path: string) {
|
|
@@ -82,7 +90,7 @@ async function getComponentMeta(program: ts.Program, appDir: string, file: strin
|
|
|
82
90
|
}
|
|
83
91
|
|
|
84
92
|
export async function buildClient(options: BuildClientOptions) {
|
|
85
|
-
const { args, rootDir, appDir, distDir, distClient, publicDir, chunksPath } = options;
|
|
93
|
+
const { args, rootDir, appDir, distDir, distClient, publicDir, chunksPath, userConfig } = options;
|
|
86
94
|
const distClientAssets = join(distClient, "assets");
|
|
87
95
|
const scanner = createScanner({ rootDir, appDir });
|
|
88
96
|
|
|
@@ -255,80 +263,90 @@ export async function buildClient(options: BuildClientOptions) {
|
|
|
255
263
|
|
|
256
264
|
const packageImports = await scanner.getPackageImports();
|
|
257
265
|
|
|
258
|
-
const bundle = await rolldown(
|
|
259
|
-
|
|
260
|
-
platform: "browser",
|
|
261
|
-
tsconfig: true,
|
|
262
|
-
moduleTypes,
|
|
263
|
-
plugins: [
|
|
264
|
-
replacePlugin({
|
|
265
|
-
"globalThis.__SF_DEV__": JSON.stringify(!args.production),
|
|
266
|
-
}),
|
|
266
|
+
const bundle = await rolldown(
|
|
267
|
+
mergeInputOptions(
|
|
267
268
|
{
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
269
|
+
input,
|
|
270
|
+
platform: "browser",
|
|
271
|
+
tsconfig: true,
|
|
272
|
+
moduleTypes,
|
|
273
|
+
plugins: [
|
|
274
|
+
replacePlugin({
|
|
275
|
+
"globalThis.__SF_DEV__": JSON.stringify(!args.production),
|
|
276
|
+
}),
|
|
277
|
+
{
|
|
278
|
+
name: "raw-css-loader",
|
|
279
|
+
resolveId(source: string, importer: string | undefined) {
|
|
280
|
+
if (source.endsWith("?raw") && source.includes(".css")) {
|
|
281
|
+
const realPath = source.replace(/\?raw$/, "");
|
|
282
|
+
if (importer) {
|
|
283
|
+
const importerDir = importer.split("/").slice(0, -1).join("/");
|
|
284
|
+
return {
|
|
285
|
+
id: join(importerDir, realPath) + "?raw",
|
|
286
|
+
external: false,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
return { id: realPath + "?raw", external: false };
|
|
290
|
+
}
|
|
291
|
+
return null;
|
|
292
|
+
},
|
|
293
|
+
async load(id: string) {
|
|
294
|
+
if (id.endsWith("?raw")) {
|
|
295
|
+
const realPath = id.replace(/\?raw$/, "");
|
|
296
|
+
try {
|
|
297
|
+
const content = await readFile(realPath, "utf-8");
|
|
298
|
+
return {
|
|
299
|
+
code: /* tsx */ `export default ${JSON.stringify(content)};`,
|
|
300
|
+
moduleType: "js",
|
|
301
|
+
};
|
|
302
|
+
} catch {
|
|
303
|
+
console.warn(`[raw-css-loader] Could not load: ${realPath}`);
|
|
304
|
+
return { code: `export default "";`, moduleType: "js" };
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return null;
|
|
308
|
+
},
|
|
309
|
+
},
|
|
310
|
+
assetUrlPrefixPlugin,
|
|
311
|
+
],
|
|
312
|
+
resolve: {
|
|
313
|
+
alias: packageImports,
|
|
282
314
|
},
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
code: /* tsx */ `export default ${JSON.stringify(content)};`,
|
|
290
|
-
moduleType: "js",
|
|
291
|
-
};
|
|
292
|
-
} catch {
|
|
293
|
-
console.warn(`[raw-css-loader] Could not load: ${realPath}`);
|
|
294
|
-
return { code: `export default "";`, moduleType: "js" };
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
return null;
|
|
315
|
+
transform: {
|
|
316
|
+
target: "es2020",
|
|
317
|
+
jsx: {
|
|
318
|
+
runtime: "automatic",
|
|
319
|
+
development: !args.production,
|
|
320
|
+
},
|
|
298
321
|
},
|
|
299
322
|
},
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
codeSplitting: {
|
|
322
|
-
minSize: 20000,
|
|
323
|
-
groups: [
|
|
324
|
-
{
|
|
325
|
-
name: "vendor",
|
|
326
|
-
test: /node_modules/,
|
|
323
|
+
userConfig,
|
|
324
|
+
),
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
await bundle.write(
|
|
328
|
+
mergeOutputOptions(
|
|
329
|
+
{
|
|
330
|
+
dir: distClientAssets,
|
|
331
|
+
format: "esm",
|
|
332
|
+
entryFileNames: "[name].js",
|
|
333
|
+
minify: args.production,
|
|
334
|
+
chunkFileNames: "[name]-[hash].js",
|
|
335
|
+
assetFileNames: "[name]-[hash][extname]",
|
|
336
|
+
codeSplitting: {
|
|
337
|
+
minSize: 20000,
|
|
338
|
+
groups: [
|
|
339
|
+
{
|
|
340
|
+
name: "vendor",
|
|
341
|
+
test: /node_modules/,
|
|
342
|
+
},
|
|
343
|
+
],
|
|
327
344
|
},
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
345
|
+
...(args.sourcemap && { sourcemap: true }),
|
|
346
|
+
},
|
|
347
|
+
userConfig,
|
|
348
|
+
),
|
|
349
|
+
);
|
|
332
350
|
|
|
333
351
|
if (cssOutputsByBase.size > 0) {
|
|
334
352
|
const emittedCss = new Set(cssOutputsByBase.values());
|
|
@@ -2,8 +2,15 @@ import { mkdir, unlink, writeFile } from "node:fs/promises";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { glob } from "node:fs/promises";
|
|
4
4
|
import { rolldown } from "rolldown";
|
|
5
|
+
import type { RolldownOptions } from "rolldown";
|
|
5
6
|
import { createProgram } from "./ast.ts";
|
|
6
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
assetUrlPrefixPlugin,
|
|
9
|
+
type BuildArgs,
|
|
10
|
+
mergeInputOptions,
|
|
11
|
+
mergeOutputOptions,
|
|
12
|
+
moduleTypes,
|
|
13
|
+
} from "./build.bundle.ts";
|
|
7
14
|
import { createScanner } from "./build.scan.ts";
|
|
8
15
|
import { validateRoutes, generateRoutesTypeFile } from "./build.validate.ts";
|
|
9
16
|
import { generateModulesFile } from "./build.emit-manifests.ts";
|
|
@@ -16,10 +23,12 @@ export interface BuildServerOptions {
|
|
|
16
23
|
modulesPath: string;
|
|
17
24
|
chunksPath: string;
|
|
18
25
|
routesTypePath: string;
|
|
26
|
+
userConfig?: RolldownOptions;
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
export async function buildServer(options: BuildServerOptions) {
|
|
22
|
-
const { args, rootDir, appDir, distServer, modulesPath, chunksPath, routesTypePath } =
|
|
30
|
+
const { args, rootDir, appDir, distServer, modulesPath, chunksPath, routesTypePath, userConfig } =
|
|
31
|
+
options;
|
|
23
32
|
const scanner = createScanner({ rootDir, appDir });
|
|
24
33
|
|
|
25
34
|
console.log("🔍 Scanning for route modules...");
|
|
@@ -73,51 +82,61 @@ export async function buildServer(options: BuildServerOptions) {
|
|
|
73
82
|
|
|
74
83
|
const packageImports = await scanner.getPackageImports();
|
|
75
84
|
|
|
76
|
-
const bundle = await rolldown(
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
85
|
+
const bundle = await rolldown(
|
|
86
|
+
mergeInputOptions(
|
|
87
|
+
{
|
|
88
|
+
input: join(appDir, "index.ts"),
|
|
89
|
+
platform: "node",
|
|
90
|
+
tsconfig: true,
|
|
91
|
+
moduleTypes,
|
|
92
|
+
external: [
|
|
93
|
+
"cloudflare:workers",
|
|
94
|
+
"preact",
|
|
95
|
+
"preact/hooks",
|
|
96
|
+
"preact/compat",
|
|
97
|
+
"preact/jsx-runtime",
|
|
98
|
+
"preact/jsx-dev-runtime",
|
|
99
|
+
"preact/debug",
|
|
100
|
+
"@preact/signals",
|
|
101
|
+
"@preact/signals-core",
|
|
102
|
+
"@preact/signals-debug",
|
|
103
|
+
"preact-render-to-string",
|
|
104
|
+
"preact-render-to-string/stream",
|
|
105
|
+
"preact-custom-element",
|
|
106
|
+
],
|
|
107
|
+
resolve: {
|
|
108
|
+
alias: {
|
|
109
|
+
...packageImports,
|
|
110
|
+
".modules.generated": modulesPath,
|
|
111
|
+
".chunks.generated.json": chunksPath,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
plugins: [assetUrlPrefixPlugin],
|
|
115
|
+
transform: {
|
|
116
|
+
jsx: {
|
|
117
|
+
runtime: "automatic",
|
|
118
|
+
development: false,
|
|
119
|
+
},
|
|
120
|
+
},
|
|
101
121
|
},
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
122
|
+
userConfig,
|
|
123
|
+
),
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
await bundle.write(
|
|
127
|
+
mergeOutputOptions(
|
|
128
|
+
{
|
|
129
|
+
dir: distServer,
|
|
130
|
+
format: "esm",
|
|
131
|
+
codeSplitting: false,
|
|
132
|
+
entryFileNames: "index.js",
|
|
133
|
+
assetFileNames: "[name]-[hash][extname]",
|
|
134
|
+
minify: args.production,
|
|
135
|
+
...(args.sourcemap && { sourcemap: true }),
|
|
108
136
|
},
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
await bundle.write({
|
|
113
|
-
dir: distServer,
|
|
114
|
-
format: "esm",
|
|
115
|
-
codeSplitting: false,
|
|
116
|
-
entryFileNames: "index.js",
|
|
117
|
-
assetFileNames: "[name]-[hash][extname]",
|
|
118
|
-
minify: args.production,
|
|
119
|
-
...(args.sourcemap && { sourcemap: true }),
|
|
120
|
-
});
|
|
137
|
+
userConfig,
|
|
138
|
+
),
|
|
139
|
+
);
|
|
121
140
|
|
|
122
141
|
await bundle.close();
|
|
123
142
|
|
package/src/build.bundle.ts
CHANGED
|
@@ -1,4 +1,82 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import type {
|
|
3
|
+
ExternalOption,
|
|
4
|
+
InputOptions,
|
|
5
|
+
ModuleTypes,
|
|
6
|
+
NormalizedOutputOptions,
|
|
7
|
+
OutputBundle,
|
|
8
|
+
OutputOptions,
|
|
9
|
+
Plugin,
|
|
10
|
+
RolldownOptions,
|
|
11
|
+
RolldownPluginOption,
|
|
12
|
+
} from "rolldown";
|
|
13
|
+
import { exists } from "./fs.ts";
|
|
14
|
+
|
|
15
|
+
/** Load a `rolldown.config.ts` from `rootDir` if it exists. */
|
|
16
|
+
export async function loadUserConfig(rootDir: string): Promise<RolldownOptions | undefined> {
|
|
17
|
+
const configPath = join(rootDir, "rolldown.config.ts");
|
|
18
|
+
if (!(await exists(configPath))) return undefined;
|
|
19
|
+
const { loadConfig } = await import("rolldown/config");
|
|
20
|
+
const exported = await loadConfig(configPath);
|
|
21
|
+
if (typeof exported === "function") return (await exported({})) as RolldownOptions;
|
|
22
|
+
if (Array.isArray(exported)) return exported[0];
|
|
23
|
+
return exported;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Merge user input options onto a framework base (plugins appended, resolve/external merged). */
|
|
27
|
+
export function mergeInputOptions(base: InputOptions, user?: RolldownOptions): InputOptions {
|
|
28
|
+
if (!user) return base;
|
|
29
|
+
const {
|
|
30
|
+
output: _,
|
|
31
|
+
plugins: userPlugins,
|
|
32
|
+
resolve: userResolve,
|
|
33
|
+
external: userExternal,
|
|
34
|
+
...rest
|
|
35
|
+
} = user;
|
|
36
|
+
return {
|
|
37
|
+
...base,
|
|
38
|
+
...rest,
|
|
39
|
+
plugins: [...toArray(base.plugins), ...toArray(userPlugins)] as RolldownPluginOption[],
|
|
40
|
+
resolve: {
|
|
41
|
+
...base.resolve,
|
|
42
|
+
...userResolve,
|
|
43
|
+
alias: {
|
|
44
|
+
...(base.resolve?.alias as Record<string, string>),
|
|
45
|
+
...(userResolve?.alias as Record<string, string>),
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
external: [...toArray(base.external), ...toArray(userExternal)] as ExternalOption,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Merge user output options onto a framework base. */
|
|
53
|
+
export function mergeOutputOptions(base: OutputOptions, user?: RolldownOptions): OutputOptions {
|
|
54
|
+
if (!user?.output) return base;
|
|
55
|
+
const out = Array.isArray(user.output) ? user.output[0] : user.output;
|
|
56
|
+
return { ...base, ...out };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function toArray<T>(value: T | T[] | undefined | null): T[] {
|
|
60
|
+
if (value == null) return [];
|
|
61
|
+
return Array.isArray(value) ? value : [value];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Raw text replacement plugin for `%KEY%` patterns (like Vite's html env replacement). */
|
|
65
|
+
export function htmlReplacePlugin(replacements: Record<string, string>): Plugin {
|
|
66
|
+
const entries = Object.entries(replacements);
|
|
67
|
+
if (entries.length === 0) return { name: "html-replace" };
|
|
68
|
+
return {
|
|
69
|
+
name: "html-replace",
|
|
70
|
+
transform(code) {
|
|
71
|
+
let result = code;
|
|
72
|
+
for (const [key, value] of entries) {
|
|
73
|
+
result = result.replaceAll(key, value);
|
|
74
|
+
}
|
|
75
|
+
if (result === code) return null;
|
|
76
|
+
return { code: result };
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
2
80
|
|
|
3
81
|
export const assetUrlPrefixPlugin = {
|
|
4
82
|
name: "asset-url-prefix",
|
package/src/build.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
import { spawn, type ChildProcess } from "node:child_process";
|
|
3
2
|
import { watch } from "node:fs";
|
|
4
3
|
import { writeFile } from "node:fs/promises";
|
|
@@ -7,6 +6,7 @@ import { argv, env } from "node:process";
|
|
|
7
6
|
import { parseArgs } from "node:util";
|
|
8
7
|
import { buildClient } from "./build.bundle-client.ts";
|
|
9
8
|
import { buildServer } from "./build.bundle-server.ts";
|
|
9
|
+
import { loadUserConfig } from "./build.bundle.ts";
|
|
10
10
|
import { exists } from "./fs.ts";
|
|
11
11
|
|
|
12
12
|
/** Resolve paths relative to the current working directory. */
|
|
@@ -110,6 +110,9 @@ async function build() {
|
|
|
110
110
|
|
|
111
111
|
await scaffoldTemplates();
|
|
112
112
|
|
|
113
|
+
const userConfig = await loadUserConfig(ROOT_DIR);
|
|
114
|
+
if (userConfig) console.log("📋 Loaded rolldown.config.ts");
|
|
115
|
+
|
|
113
116
|
await buildClient({
|
|
114
117
|
args,
|
|
115
118
|
rootDir: ROOT_DIR,
|
|
@@ -118,6 +121,7 @@ async function build() {
|
|
|
118
121
|
distClient: DIST_CLIENT,
|
|
119
122
|
publicDir: PUBLIC_DIR,
|
|
120
123
|
chunksPath: CHUNKS_PATH,
|
|
124
|
+
userConfig,
|
|
121
125
|
});
|
|
122
126
|
|
|
123
127
|
await buildServer({
|
|
@@ -128,6 +132,7 @@ async function build() {
|
|
|
128
132
|
modulesPath: MODULES_PATH,
|
|
129
133
|
chunksPath: CHUNKS_PATH,
|
|
130
134
|
routesTypePath: ROUTES_TYPE_PATH,
|
|
135
|
+
userConfig,
|
|
131
136
|
});
|
|
132
137
|
|
|
133
138
|
const duration = ((performance.now() - startTime) / 1000).toFixed(2);
|
package/src/solarflare.d.ts
CHANGED
|
@@ -5,13 +5,12 @@ interface ImportMeta {
|
|
|
5
5
|
): Record<string, () => Promise<T>>;
|
|
6
6
|
/** The file path of the current module (Node runtime) */
|
|
7
7
|
path?: string;
|
|
8
|
-
/** Environment variables
|
|
9
|
-
env
|
|
8
|
+
/** Environment variables replaced at build time via `transform.define` in `rolldown.config.ts`. */
|
|
9
|
+
env: {
|
|
10
10
|
DEV?: boolean;
|
|
11
11
|
PROD?: boolean;
|
|
12
12
|
MODE?: string;
|
|
13
|
-
|
|
14
|
-
};
|
|
13
|
+
} & Record<string, string>;
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
declare module "*.css" {
|