@rainfw/core 0.2.3 → 0.2.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/cli/index.js +3 -0
- package/cli/utils/banner.js +14 -0
- package/package.json +1 -1
- package/scripts/dev.js +3 -0
- package/scripts/generate.js +66 -4
package/cli/index.js
CHANGED
|
@@ -5,6 +5,7 @@ const fs = require("node:fs");
|
|
|
5
5
|
const { spawn } = require("node:child_process");
|
|
6
6
|
|
|
7
7
|
const { stripControlChars } = require("./utils/sanitize");
|
|
8
|
+
const { printBanner } = require("./utils/banner");
|
|
8
9
|
|
|
9
10
|
const PACKAGE_JSON = path.join(__dirname, "..", "package.json");
|
|
10
11
|
const pkg = JSON.parse(fs.readFileSync(PACKAGE_JSON, "utf-8"));
|
|
@@ -44,6 +45,8 @@ if (command === "--version" || command === "-v") {
|
|
|
44
45
|
process.exit(0);
|
|
45
46
|
}
|
|
46
47
|
|
|
48
|
+
printBanner();
|
|
49
|
+
|
|
47
50
|
if (!VALID_COMMANDS.includes(command)) {
|
|
48
51
|
console.error(
|
|
49
52
|
`[Rain] Error: Unknown command "${stripControlChars(command)}".\n` +
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const path = require("node:path");
|
|
2
|
+
|
|
3
|
+
const BRAND_COLOR = "\x1b[38;2;101;187;233m";
|
|
4
|
+
const RESET = "\x1b[0m";
|
|
5
|
+
const version = require(path.join(__dirname, "..", "..", "package.json")).version;
|
|
6
|
+
|
|
7
|
+
function printBanner() {
|
|
8
|
+
console.log(
|
|
9
|
+
`\n ${BRAND_COLOR}\u{1F327}\uFE0F rain.js ${version}${RESET}`,
|
|
10
|
+
);
|
|
11
|
+
console.log(`${BRAND_COLOR}${"─".repeat(20)}${RESET}\n`);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = { printBanner, version, BRAND_COLOR, RESET };
|
package/package.json
CHANGED
package/scripts/dev.js
CHANGED
|
@@ -2,9 +2,12 @@ const fs = require("node:fs");
|
|
|
2
2
|
const path = require("node:path");
|
|
3
3
|
const { spawn } = require("node:child_process");
|
|
4
4
|
const { generate, regenerateClient, ROUTES_DIR } = require("./generate");
|
|
5
|
+
const { printBanner } = require("../cli/utils/banner");
|
|
5
6
|
|
|
6
7
|
const SRC_DIR = path.join(process.cwd(), "src");
|
|
7
8
|
|
|
9
|
+
printBanner();
|
|
10
|
+
|
|
8
11
|
generate();
|
|
9
12
|
|
|
10
13
|
let debounceTimer = null;
|
package/scripts/generate.js
CHANGED
|
@@ -2,6 +2,7 @@ const fs = require("node:fs");
|
|
|
2
2
|
const path = require("node:path");
|
|
3
3
|
const { execSync } = require("node:child_process");
|
|
4
4
|
const ts = require("typescript");
|
|
5
|
+
const { printBanner } = require("../cli/utils/banner");
|
|
5
6
|
|
|
6
7
|
let esbuild;
|
|
7
8
|
try {
|
|
@@ -212,6 +213,59 @@ function getClientFiles(dir, base = "") {
|
|
|
212
213
|
return files;
|
|
213
214
|
}
|
|
214
215
|
|
|
216
|
+
function ensureRelativeImport(importPath) {
|
|
217
|
+
return importPath.startsWith(".") ? importPath : `./${importPath}`;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function buildIslandImportLines(index, file, srcDir, entryDir) {
|
|
221
|
+
const fullPath = path.join(srcDir, file);
|
|
222
|
+
const content = fs.readFileSync(fullPath, "utf-8");
|
|
223
|
+
const { named, hasDefault } = detectAllExportsFromContent(content);
|
|
224
|
+
const islandId = clientFileToIslandId(file);
|
|
225
|
+
|
|
226
|
+
const importPath = path
|
|
227
|
+
.relative(entryDir, path.join(srcDir, file.replace(/\.tsx?$/, "")))
|
|
228
|
+
.replace(/\\/g, "/");
|
|
229
|
+
const safeImport = ensureRelativeImport(importPath);
|
|
230
|
+
|
|
231
|
+
const specifiers = [];
|
|
232
|
+
if (hasDefault) specifiers.push(`default as _d${index}`);
|
|
233
|
+
for (const name of named) specifiers.push(`${name} as _n${index}_${name}`);
|
|
234
|
+
if (specifiers.length === 0) return [];
|
|
235
|
+
|
|
236
|
+
const lines = [];
|
|
237
|
+
lines.push(`import { ${specifiers.join(", ")} } from "${safeImport}";`);
|
|
238
|
+
if (hasDefault) {
|
|
239
|
+
lines.push(`registerIsland("${islandId}:default", _d${index});`);
|
|
240
|
+
}
|
|
241
|
+
for (const name of named) {
|
|
242
|
+
lines.push(`registerIsland("${islandId}:${name}", _n${index}_${name});`);
|
|
243
|
+
}
|
|
244
|
+
return lines;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function generateClientEntrySource(clientFiles, srcDir) {
|
|
248
|
+
const entryDir = path.join(PROJECT_ROOT, BUILD_CONFIG.outDir);
|
|
249
|
+
const runtimePath = path
|
|
250
|
+
.relative(entryDir, path.join(PROJECT_ROOT, "src/framework/client/runtime"))
|
|
251
|
+
.replace(/\\/g, "/");
|
|
252
|
+
const runtimeImport = ensureRelativeImport(runtimePath);
|
|
253
|
+
|
|
254
|
+
const lines = [];
|
|
255
|
+
lines.push(
|
|
256
|
+
`import { registerIsland, startHydration } from "${runtimeImport}";`,
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
for (let i = 0; i < clientFiles.length; i++) {
|
|
260
|
+
lines.push(...buildIslandImportLines(i, clientFiles[i], srcDir, entryDir));
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
lines.push("startHydration();");
|
|
264
|
+
lines.push("");
|
|
265
|
+
|
|
266
|
+
return lines.join("\n");
|
|
267
|
+
}
|
|
268
|
+
|
|
215
269
|
function bundleClientFilesSync(clientFiles, srcDir) {
|
|
216
270
|
if (clientFiles.length === 0) return [];
|
|
217
271
|
if (!esbuild) {
|
|
@@ -229,21 +283,27 @@ function bundleClientFilesSync(clientFiles, srcDir) {
|
|
|
229
283
|
}
|
|
230
284
|
|
|
231
285
|
for (const file of fs.readdirSync(outDir)) {
|
|
232
|
-
if (file.startsWith("island-")) {
|
|
286
|
+
if (file.startsWith("island-") || file.startsWith("rain-client-")) {
|
|
233
287
|
fs.unlinkSync(path.join(outDir, file));
|
|
234
288
|
}
|
|
235
289
|
}
|
|
236
290
|
|
|
237
|
-
const
|
|
291
|
+
const entrySource = generateClientEntrySource(clientFiles, srcDir);
|
|
292
|
+
const entryDir = path.join(PROJECT_ROOT, BUILD_CONFIG.outDir);
|
|
293
|
+
if (!fs.existsSync(entryDir)) {
|
|
294
|
+
fs.mkdirSync(entryDir, { recursive: true });
|
|
295
|
+
}
|
|
296
|
+
const clientEntryPath = path.join(entryDir, "client-entry.ts");
|
|
297
|
+
fs.writeFileSync(clientEntryPath, entrySource);
|
|
238
298
|
|
|
239
299
|
const result = esbuild.buildSync({
|
|
240
|
-
entryPoints,
|
|
300
|
+
entryPoints: [clientEntryPath],
|
|
241
301
|
outdir: outDir,
|
|
242
302
|
bundle: true,
|
|
243
303
|
minify: true,
|
|
244
304
|
format: "esm",
|
|
245
305
|
metafile: true,
|
|
246
|
-
entryNames: "
|
|
306
|
+
entryNames: "rain-client-[hash]",
|
|
247
307
|
write: true,
|
|
248
308
|
treeShaking: true,
|
|
249
309
|
platform: "browser",
|
|
@@ -1124,6 +1184,7 @@ module.exports = {
|
|
|
1124
1184
|
updateWranglerAliases,
|
|
1125
1185
|
clientFileToIslandId,
|
|
1126
1186
|
bundleClientFilesSync,
|
|
1187
|
+
generateClientEntrySource,
|
|
1127
1188
|
validateNoPageRouteColocation,
|
|
1128
1189
|
validateNoDuplicateUrls,
|
|
1129
1190
|
stripRouteGroupSegments,
|
|
@@ -1133,5 +1194,6 @@ module.exports = {
|
|
|
1133
1194
|
};
|
|
1134
1195
|
|
|
1135
1196
|
if (require.main === module) {
|
|
1197
|
+
printBanner();
|
|
1136
1198
|
generate();
|
|
1137
1199
|
}
|