@chr33s/solarflare 0.0.3 → 0.0.5
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/package.json +1 -1
- 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 -0
- package/src/solarflare.d.ts +3 -4
package/package.json
CHANGED
|
@@ -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
|
@@ -7,6 +7,7 @@ import { argv, env } from "node:process";
|
|
|
7
7
|
import { parseArgs } from "node:util";
|
|
8
8
|
import { buildClient } from "./build.bundle-client.ts";
|
|
9
9
|
import { buildServer } from "./build.bundle-server.ts";
|
|
10
|
+
import { loadUserConfig } from "./build.bundle.ts";
|
|
10
11
|
import { exists } from "./fs.ts";
|
|
11
12
|
|
|
12
13
|
/** Resolve paths relative to the current working directory. */
|
|
@@ -110,6 +111,9 @@ async function build() {
|
|
|
110
111
|
|
|
111
112
|
await scaffoldTemplates();
|
|
112
113
|
|
|
114
|
+
const userConfig = await loadUserConfig(ROOT_DIR);
|
|
115
|
+
if (userConfig) console.log("📋 Loaded rolldown.config.ts");
|
|
116
|
+
|
|
113
117
|
await buildClient({
|
|
114
118
|
args,
|
|
115
119
|
rootDir: ROOT_DIR,
|
|
@@ -118,6 +122,7 @@ async function build() {
|
|
|
118
122
|
distClient: DIST_CLIENT,
|
|
119
123
|
publicDir: PUBLIC_DIR,
|
|
120
124
|
chunksPath: CHUNKS_PATH,
|
|
125
|
+
userConfig,
|
|
121
126
|
});
|
|
122
127
|
|
|
123
128
|
await buildServer({
|
|
@@ -128,6 +133,7 @@ async function build() {
|
|
|
128
133
|
modulesPath: MODULES_PATH,
|
|
129
134
|
chunksPath: CHUNKS_PATH,
|
|
130
135
|
routesTypePath: ROUTES_TYPE_PATH,
|
|
136
|
+
userConfig,
|
|
131
137
|
});
|
|
132
138
|
|
|
133
139
|
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" {
|