buner 1.0.2 → 1.0.4
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/buner.js +87 -79
- package/cli/buner.ts +33 -26
- package/cli/helpers/copy.ts +15 -16
- package/cli/helpers/format-files.ts +17 -13
- package/cli/install-template.ts +25 -30
- package/package.json +1 -1
package/bin/buner.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import path from "path";
|
|
3
3
|
import { execSync, spawn } from "child_process";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
4
5
|
import { Command } from "commander";
|
|
5
6
|
import chalk from "chalk";
|
|
6
7
|
import fetch from "node-fetch";
|
|
7
8
|
import prompts from "prompts";
|
|
8
9
|
import fs from "fs";
|
|
9
10
|
import fs$1 from "fs/promises";
|
|
10
|
-
import { fileURLToPath } from "url";
|
|
11
11
|
import os from "os";
|
|
12
12
|
import { globby } from "globby";
|
|
13
13
|
import { exec } from "node:child_process";
|
|
14
14
|
import validateProjectName from "validate-npm-package-name";
|
|
15
15
|
const name = "buner";
|
|
16
|
-
const version = "1.0.
|
|
16
|
+
const version = "1.0.4";
|
|
17
17
|
const description = "Frontend build toolkit for Vite + React SSR projects — SCSS pipeline, prerender, SSR dev server, and backend integration.";
|
|
18
18
|
const type = "module";
|
|
19
19
|
const license = "MIT";
|
|
@@ -139,23 +139,26 @@ const tryGitInit = (root) => {
|
|
|
139
139
|
};
|
|
140
140
|
const excludeFiles = [
|
|
141
141
|
".git",
|
|
142
|
+
".github",
|
|
143
|
+
".npmrc",
|
|
142
144
|
"bin",
|
|
145
|
+
"cli",
|
|
146
|
+
"xpack",
|
|
143
147
|
".vscode",
|
|
144
148
|
".build",
|
|
149
|
+
"node_modules",
|
|
150
|
+
"server.ts",
|
|
151
|
+
"prerender.ts",
|
|
152
|
+
"integration.ts",
|
|
153
|
+
"styles.ts",
|
|
154
|
+
"scripts.ts",
|
|
155
|
+
"states.ts",
|
|
156
|
+
"migrate-scss.ts",
|
|
157
|
+
"vite.config.ts",
|
|
158
|
+
"vite.cli.config.ts",
|
|
159
|
+
"src",
|
|
145
160
|
"public/samples",
|
|
146
|
-
"public/assets/vendors"
|
|
147
|
-
"src/_api/!(_base.ts)",
|
|
148
|
-
"src/_data",
|
|
149
|
-
"src/assets/scripts/!(color-mode|main|mock-api|pl-states|root|theme-critical).entry.ts",
|
|
150
|
-
"src/atoms",
|
|
151
|
-
"src/mocks/avatar",
|
|
152
|
-
"src/mocks/user",
|
|
153
|
-
"src/molecules",
|
|
154
|
-
"src/organisms/!(root|header|footer)/*",
|
|
155
|
-
"src/pages/!(Root|Home).tsx",
|
|
156
|
-
"src/templates/!(root|home)/*",
|
|
157
|
-
"!cli",
|
|
158
|
-
"!vite.cli.config.ts"
|
|
161
|
+
"public/assets/vendors"
|
|
159
162
|
];
|
|
160
163
|
const copy = async (src, dest, { cwd }) => {
|
|
161
164
|
const sourceFiles = await globby(src, {
|
|
@@ -166,9 +169,6 @@ const copy = async (src, dest, { cwd }) => {
|
|
|
166
169
|
ignore: excludeFiles
|
|
167
170
|
});
|
|
168
171
|
const destRelativeToCwd = path.resolve(dest);
|
|
169
|
-
await fs$1.mkdir(path.join(destRelativeToCwd, "src/atoms"), { recursive: true });
|
|
170
|
-
await fs$1.mkdir(path.join(destRelativeToCwd, "src/molecules"), { recursive: true });
|
|
171
|
-
await fs$1.mkdir(path.join(destRelativeToCwd, "src/mocks/example"), { recursive: true });
|
|
172
172
|
return Promise.all(
|
|
173
173
|
sourceFiles.map(async (p) => {
|
|
174
174
|
const dirname2 = path.dirname(p);
|
|
@@ -194,11 +194,15 @@ const install = async () => {
|
|
|
194
194
|
});
|
|
195
195
|
});
|
|
196
196
|
};
|
|
197
|
+
const writeFile = async (filePath, data) => {
|
|
198
|
+
await fs$1.mkdir(path.dirname(filePath), { recursive: true });
|
|
199
|
+
await fs$1.writeFile(filePath, data);
|
|
200
|
+
};
|
|
197
201
|
const formatFiles = async (root) => {
|
|
198
202
|
let filePath, data;
|
|
199
203
|
filePath = path.join(root, "src/mocks/handlers.ts");
|
|
200
204
|
data = "import { handlers } from './consts';\n\nexport { handlers };";
|
|
201
|
-
await
|
|
205
|
+
await writeFile(filePath, data + os.EOL);
|
|
202
206
|
filePath = path.join(root, "src/mocks/example/index.ts");
|
|
203
207
|
data = `
|
|
204
208
|
import { handlers } from '@mocks/handlers';
|
|
@@ -210,9 +214,8 @@ const formatFiles = async (root) => {
|
|
|
210
214
|
})
|
|
211
215
|
);
|
|
212
216
|
`;
|
|
213
|
-
await
|
|
217
|
+
await writeFile(filePath, data + os.EOL);
|
|
214
218
|
filePath = path.join(root, "src/react-loader.tsx");
|
|
215
|
-
await fs$1.mkdir(path.dirname(filePath), { recursive: true });
|
|
216
219
|
data = [
|
|
217
220
|
"import { lazy } from 'react';",
|
|
218
221
|
"",
|
|
@@ -221,23 +224,23 @@ const formatFiles = async (root) => {
|
|
|
221
224
|
"};",
|
|
222
225
|
""
|
|
223
226
|
].join("\n");
|
|
224
|
-
await
|
|
227
|
+
await writeFile(filePath, data);
|
|
225
228
|
filePath = path.join(root, "src/_types/atoms.d.ts");
|
|
226
|
-
await
|
|
229
|
+
await writeFile(
|
|
227
230
|
filePath,
|
|
228
231
|
`
|
|
229
232
|
import { BasedAtomicModel } from "./_general";
|
|
230
233
|
`
|
|
231
234
|
);
|
|
232
235
|
filePath = path.join(root, "src/_types/molecules.d.ts");
|
|
233
|
-
await
|
|
236
|
+
await writeFile(
|
|
234
237
|
filePath,
|
|
235
238
|
`
|
|
236
239
|
import { BasedAtomicModel } from "./_general";
|
|
237
240
|
`
|
|
238
241
|
);
|
|
239
242
|
filePath = path.join(root, "src/_types/organisms.d.ts");
|
|
240
|
-
await
|
|
243
|
+
await writeFile(
|
|
241
244
|
filePath,
|
|
242
245
|
`
|
|
243
246
|
import { BasedAtomicModel } from "./_general";
|
|
@@ -248,7 +251,7 @@ const formatFiles = async (root) => {
|
|
|
248
251
|
`
|
|
249
252
|
);
|
|
250
253
|
filePath = path.join(root, "src/pages/Home.tsx");
|
|
251
|
-
await
|
|
254
|
+
await writeFile(
|
|
252
255
|
filePath,
|
|
253
256
|
`
|
|
254
257
|
import Template from '@templates/home/Home';
|
|
@@ -261,7 +264,7 @@ const formatFiles = async (root) => {
|
|
|
261
264
|
`
|
|
262
265
|
);
|
|
263
266
|
filePath = path.join(root, "src/templates/home/Home.tsx");
|
|
264
|
-
await
|
|
267
|
+
await writeFile(
|
|
265
268
|
filePath,
|
|
266
269
|
`
|
|
267
270
|
import { FooterModel, HeaderModel } from '@_types/organisms';
|
|
@@ -293,7 +296,7 @@ const formatFiles = async (root) => {
|
|
|
293
296
|
`
|
|
294
297
|
);
|
|
295
298
|
filePath = path.join(root, "src/organisms/header/Header.tsx");
|
|
296
|
-
await
|
|
299
|
+
await writeFile(
|
|
297
300
|
filePath,
|
|
298
301
|
`
|
|
299
302
|
import { getModifiers } from '@helpers/functions';
|
|
@@ -315,9 +318,9 @@ const formatFiles = async (root) => {
|
|
|
315
318
|
`
|
|
316
319
|
);
|
|
317
320
|
filePath = path.join(root, "src/organisms/header/Header.scss");
|
|
318
|
-
await
|
|
321
|
+
await writeFile(filePath, "");
|
|
319
322
|
filePath = path.join(root, "src/organisms/footer/Footer.tsx");
|
|
320
|
-
await
|
|
323
|
+
await writeFile(
|
|
321
324
|
filePath,
|
|
322
325
|
`
|
|
323
326
|
import { getModifiers } from '@helpers/functions';
|
|
@@ -339,7 +342,7 @@ const formatFiles = async (root) => {
|
|
|
339
342
|
`
|
|
340
343
|
);
|
|
341
344
|
filePath = path.join(root, "src/organisms/footer/Footer.scss");
|
|
342
|
-
await
|
|
345
|
+
await writeFile(filePath, "");
|
|
343
346
|
return ["xxx"];
|
|
344
347
|
};
|
|
345
348
|
const filename = fileURLToPath(import.meta.url);
|
|
@@ -353,32 +356,35 @@ const installTemplate = async (model) => {
|
|
|
353
356
|
cwd: path.join(dirname, "..")
|
|
354
357
|
});
|
|
355
358
|
await formatFiles(root);
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
359
|
+
const packageJson$1 = {
|
|
360
|
+
name: appName,
|
|
361
|
+
description: "",
|
|
362
|
+
version: "0.1.0",
|
|
363
|
+
type: "module",
|
|
364
|
+
private: true,
|
|
365
|
+
scripts: {
|
|
366
|
+
start: "buner dev",
|
|
367
|
+
dev: "buner dev",
|
|
368
|
+
serve: "buner serve",
|
|
369
|
+
build: "buner build",
|
|
370
|
+
generate: "buner generate",
|
|
371
|
+
eshn: "buner eshn",
|
|
372
|
+
inte: "buner inte",
|
|
373
|
+
styles: "buner styles",
|
|
374
|
+
prerender: "buner prerender"
|
|
375
|
+
},
|
|
376
|
+
dependencies: {
|
|
377
|
+
buner: `^${packageJson.version}`,
|
|
378
|
+
react: "^19.0.0",
|
|
379
|
+
"react-dom": "^19.0.0",
|
|
380
|
+
"react-router-dom": "^7.0.0"
|
|
369
381
|
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
if (!devDeps) delete packageJson2.devDependencies;
|
|
373
|
-
await fs$1.writeFile(path.join(root, "package.json"), JSON.stringify(packageJson2, null, 2) + os.EOL);
|
|
382
|
+
};
|
|
383
|
+
await fs$1.writeFile(path.join(root, "package.json"), JSON.stringify(packageJson$1, null, 2) + os.EOL);
|
|
374
384
|
console.log("\nInstalling dependencies:");
|
|
375
|
-
for (const dependency in
|
|
385
|
+
for (const dependency in packageJson$1.dependencies) {
|
|
376
386
|
console.log(`- ${cyan$1(dependency)}`);
|
|
377
387
|
}
|
|
378
|
-
if (devDeps) {
|
|
379
|
-
console.log("\nInstalling devDependencies:");
|
|
380
|
-
for (const dependency in packageJson2.devDependencies) console.log(`- ${cyan$1(dependency)}`);
|
|
381
|
-
}
|
|
382
388
|
await install();
|
|
383
389
|
};
|
|
384
390
|
const { green: green$1 } = chalk;
|
|
@@ -424,6 +430,8 @@ function validateNpmName(name2) {
|
|
|
424
430
|
}
|
|
425
431
|
const { green, yellow, bold, cyan, red } = chalk;
|
|
426
432
|
const packageName = "buner";
|
|
433
|
+
const packageDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
434
|
+
const pkg = (file) => path.join(packageDir, file);
|
|
427
435
|
const run = (cmd, args = [], options = {}) => {
|
|
428
436
|
return new Promise((resolve, reject) => {
|
|
429
437
|
const child = spawn(cmd, args, {
|
|
@@ -510,52 +518,52 @@ program.command("dev").description("Start development mode with all watchers").a
|
|
|
510
518
|
await run("npx", [
|
|
511
519
|
"concurrently",
|
|
512
520
|
"--kill-others",
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
521
|
+
`"bun ${pkg("styles.ts")} --watch"`,
|
|
522
|
+
`"bun ${pkg("states.ts")} --watch"`,
|
|
523
|
+
`"cross-env scriptOnly=true npx vite build --config ${pkg("vite.config.ts")} --mode development --watch"`,
|
|
524
|
+
`"bun ${pkg("server.ts")} --mode development"`
|
|
517
525
|
]);
|
|
518
526
|
});
|
|
519
527
|
program.command("serve").description("Start the SSR dev server").option("--mode <mode>", "server mode", "development").action(async (opts) => {
|
|
520
|
-
await run("bun", ["server.ts", "--mode", opts.mode]);
|
|
528
|
+
await run("bun", [pkg("server.ts"), "--mode", opts.mode]);
|
|
521
529
|
});
|
|
522
530
|
program.command("build").description("Build the project (static + SSR)").action(async () => {
|
|
523
|
-
runSync(
|
|
524
|
-
runSync(
|
|
531
|
+
runSync(`npx vite build --config ${pkg("vite.config.ts")} --outDir dist/static`);
|
|
532
|
+
runSync(`npx vite build --config ${pkg("vite.config.ts")} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
525
533
|
});
|
|
526
534
|
program.command("generate").description("Full static site generation (states + styles + build + prerender)").option("--mode <mode>", "build mode", "production").action(async (opts) => {
|
|
527
|
-
runSync(
|
|
528
|
-
runSync(
|
|
535
|
+
runSync(`bun ${pkg("states.ts")}`);
|
|
536
|
+
runSync(`bun ${pkg("styles.ts")}`);
|
|
529
537
|
if (opts.mode === "production") {
|
|
530
|
-
runSync(
|
|
531
|
-
runSync(
|
|
538
|
+
runSync(`npx vite build --config ${pkg("vite.config.ts")} --outDir dist/static`);
|
|
539
|
+
runSync(`npx vite build --config ${pkg("vite.config.ts")} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
532
540
|
} else {
|
|
533
|
-
runSync(`npx vite build --outDir dist/static --mode ${opts.mode}`);
|
|
534
|
-
runSync(`npx vite build --ssr src/entry-server.tsx --outDir dist/server --mode ${opts.mode}`);
|
|
541
|
+
runSync(`npx vite build --config ${pkg("vite.config.ts")} --outDir dist/static --mode ${opts.mode}`);
|
|
542
|
+
runSync(`npx vite build --config ${pkg("vite.config.ts")} --ssr src/entry-server.tsx --outDir dist/server --mode ${opts.mode}`);
|
|
535
543
|
}
|
|
536
|
-
runSync(`bun prerender.ts --add-hash --mode ${opts.mode}`);
|
|
544
|
+
runSync(`bun ${pkg("prerender.ts")} --add-hash --mode ${opts.mode}`);
|
|
537
545
|
});
|
|
538
546
|
program.command("eshn").description("Generate with --mode eshn").action(async () => {
|
|
539
|
-
runSync(
|
|
540
|
-
runSync(
|
|
541
|
-
runSync(
|
|
542
|
-
runSync(
|
|
543
|
-
runSync(
|
|
547
|
+
runSync(`bun ${pkg("states.ts")}`);
|
|
548
|
+
runSync(`bun ${pkg("styles.ts")}`);
|
|
549
|
+
runSync(`npx vite build --config ${pkg("vite.config.ts")} --outDir dist/static --mode eshn`);
|
|
550
|
+
runSync(`npx vite build --config ${pkg("vite.config.ts")} --ssr src/entry-server.tsx --outDir dist/server --mode eshn`);
|
|
551
|
+
runSync(`bun ${pkg("prerender.ts")} --add-hash --mode eshn`);
|
|
544
552
|
});
|
|
545
553
|
program.command("inte").description("Build and integrate with backend (styles + build + prerender + integration)").action(async () => {
|
|
546
|
-
runSync(
|
|
547
|
-
runSync(
|
|
548
|
-
runSync(
|
|
549
|
-
runSync(
|
|
550
|
-
runSync(
|
|
554
|
+
runSync(`bun ${pkg("styles.ts")}`);
|
|
555
|
+
runSync(`npx vite build --config ${pkg("vite.config.ts")} --outDir dist/static`);
|
|
556
|
+
runSync(`npx vite build --config ${pkg("vite.config.ts")} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
557
|
+
runSync(`bun ${pkg("prerender.ts")}`);
|
|
558
|
+
runSync(`bun ${pkg("integration.ts")}`);
|
|
551
559
|
});
|
|
552
560
|
program.command("styles").description("Compile SCSS").option("--watch", "Watch for changes").action(async (opts) => {
|
|
553
|
-
const args = ["styles.ts"];
|
|
561
|
+
const args = [pkg("styles.ts")];
|
|
554
562
|
if (opts.watch) args.push("--watch");
|
|
555
563
|
await run("bun", args);
|
|
556
564
|
});
|
|
557
565
|
program.command("prerender").description("Pre-render HTML files").option("--add-hash", "Add content hashes to asset URLs").option("--mode <mode>", "build mode", "production").action(async (opts) => {
|
|
558
|
-
const args = ["prerender.ts"];
|
|
566
|
+
const args = [pkg("prerender.ts")];
|
|
559
567
|
if (opts.addHash) args.push("--add-hash");
|
|
560
568
|
args.push("--mode", opts.mode);
|
|
561
569
|
await run("bun", args);
|
package/cli/buner.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { execSync, spawn, SpawnOptions } from 'child_process';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
5
6
|
|
|
6
7
|
import { Command } from 'commander';
|
|
7
8
|
import chalk from 'chalk';
|
|
@@ -16,6 +17,12 @@ import { validateNpmName } from './helpers/validate-pkg.js';
|
|
|
16
17
|
const { green, yellow, bold, cyan, red } = chalk;
|
|
17
18
|
const packageName = 'buner';
|
|
18
19
|
|
|
20
|
+
// Package's own directory (where server.ts, styles.ts, etc. live)
|
|
21
|
+
const packageDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
22
|
+
|
|
23
|
+
/** Resolve a file path relative to the buner package directory */
|
|
24
|
+
const pkg = (file: string) => path.join(packageDir, file);
|
|
25
|
+
|
|
19
26
|
const run = (cmd: string, args: string[] = [], options: SpawnOptions = {}) => {
|
|
20
27
|
return new Promise<void>((resolve, reject) => {
|
|
21
28
|
const child = spawn(cmd, args, {
|
|
@@ -132,10 +139,10 @@ program
|
|
|
132
139
|
await run('npx', [
|
|
133
140
|
'concurrently',
|
|
134
141
|
'--kill-others',
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
142
|
+
`"bun ${pkg('styles.ts')} --watch"`,
|
|
143
|
+
`"bun ${pkg('states.ts')} --watch"`,
|
|
144
|
+
`"cross-env scriptOnly=true npx vite build --config ${pkg('vite.config.ts')} --mode development --watch"`,
|
|
145
|
+
`"bun ${pkg('server.ts')} --mode development"`,
|
|
139
146
|
]);
|
|
140
147
|
});
|
|
141
148
|
|
|
@@ -145,7 +152,7 @@ program
|
|
|
145
152
|
.description('Start the SSR dev server')
|
|
146
153
|
.option('--mode <mode>', 'server mode', 'development')
|
|
147
154
|
.action(async (opts) => {
|
|
148
|
-
await run('bun', ['server.ts', '--mode', opts.mode]);
|
|
155
|
+
await run('bun', [pkg('server.ts'), '--mode', opts.mode]);
|
|
149
156
|
});
|
|
150
157
|
|
|
151
158
|
// buner build
|
|
@@ -153,8 +160,8 @@ program
|
|
|
153
160
|
.command('build')
|
|
154
161
|
.description('Build the project (static + SSR)')
|
|
155
162
|
.action(async () => {
|
|
156
|
-
runSync(
|
|
157
|
-
runSync(
|
|
163
|
+
runSync(`npx vite build --config ${pkg('vite.config.ts')} --outDir dist/static`);
|
|
164
|
+
runSync(`npx vite build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
158
165
|
});
|
|
159
166
|
|
|
160
167
|
// buner generate
|
|
@@ -163,16 +170,16 @@ program
|
|
|
163
170
|
.description('Full static site generation (states + styles + build + prerender)')
|
|
164
171
|
.option('--mode <mode>', 'build mode', 'production')
|
|
165
172
|
.action(async (opts) => {
|
|
166
|
-
runSync(
|
|
167
|
-
runSync(
|
|
173
|
+
runSync(`bun ${pkg('states.ts')}`);
|
|
174
|
+
runSync(`bun ${pkg('styles.ts')}`);
|
|
168
175
|
if (opts.mode === 'production') {
|
|
169
|
-
runSync(
|
|
170
|
-
runSync(
|
|
176
|
+
runSync(`npx vite build --config ${pkg('vite.config.ts')} --outDir dist/static`);
|
|
177
|
+
runSync(`npx vite build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
171
178
|
} else {
|
|
172
|
-
runSync(`npx vite build --outDir dist/static --mode ${opts.mode}`);
|
|
173
|
-
runSync(`npx vite build --ssr src/entry-server.tsx --outDir dist/server --mode ${opts.mode}`);
|
|
179
|
+
runSync(`npx vite build --config ${pkg('vite.config.ts')} --outDir dist/static --mode ${opts.mode}`);
|
|
180
|
+
runSync(`npx vite build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server --mode ${opts.mode}`);
|
|
174
181
|
}
|
|
175
|
-
runSync(`bun prerender.ts --add-hash --mode ${opts.mode}`);
|
|
182
|
+
runSync(`bun ${pkg('prerender.ts')} --add-hash --mode ${opts.mode}`);
|
|
176
183
|
});
|
|
177
184
|
|
|
178
185
|
// buner eshn
|
|
@@ -180,11 +187,11 @@ program
|
|
|
180
187
|
.command('eshn')
|
|
181
188
|
.description('Generate with --mode eshn')
|
|
182
189
|
.action(async () => {
|
|
183
|
-
runSync(
|
|
184
|
-
runSync(
|
|
185
|
-
runSync(
|
|
186
|
-
runSync(
|
|
187
|
-
runSync(
|
|
190
|
+
runSync(`bun ${pkg('states.ts')}`);
|
|
191
|
+
runSync(`bun ${pkg('styles.ts')}`);
|
|
192
|
+
runSync(`npx vite build --config ${pkg('vite.config.ts')} --outDir dist/static --mode eshn`);
|
|
193
|
+
runSync(`npx vite build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server --mode eshn`);
|
|
194
|
+
runSync(`bun ${pkg('prerender.ts')} --add-hash --mode eshn`);
|
|
188
195
|
});
|
|
189
196
|
|
|
190
197
|
// buner inte
|
|
@@ -192,11 +199,11 @@ program
|
|
|
192
199
|
.command('inte')
|
|
193
200
|
.description('Build and integrate with backend (styles + build + prerender + integration)')
|
|
194
201
|
.action(async () => {
|
|
195
|
-
runSync(
|
|
196
|
-
runSync(
|
|
197
|
-
runSync(
|
|
198
|
-
runSync(
|
|
199
|
-
runSync(
|
|
202
|
+
runSync(`bun ${pkg('styles.ts')}`);
|
|
203
|
+
runSync(`npx vite build --config ${pkg('vite.config.ts')} --outDir dist/static`);
|
|
204
|
+
runSync(`npx vite build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
205
|
+
runSync(`bun ${pkg('prerender.ts')}`);
|
|
206
|
+
runSync(`bun ${pkg('integration.ts')}`);
|
|
200
207
|
});
|
|
201
208
|
|
|
202
209
|
// buner styles
|
|
@@ -205,7 +212,7 @@ program
|
|
|
205
212
|
.description('Compile SCSS')
|
|
206
213
|
.option('--watch', 'Watch for changes')
|
|
207
214
|
.action(async (opts) => {
|
|
208
|
-
const args = ['styles.ts'];
|
|
215
|
+
const args = [pkg('styles.ts')];
|
|
209
216
|
|
|
210
217
|
if (opts.watch) args.push('--watch');
|
|
211
218
|
await run('bun', args);
|
|
@@ -218,7 +225,7 @@ program
|
|
|
218
225
|
.option('--add-hash', 'Add content hashes to asset URLs')
|
|
219
226
|
.option('--mode <mode>', 'build mode', 'production')
|
|
220
227
|
.action(async (opts) => {
|
|
221
|
-
const args = ['prerender.ts'];
|
|
228
|
+
const args = [pkg('prerender.ts')];
|
|
222
229
|
|
|
223
230
|
if (opts.addHash) args.push('--add-hash');
|
|
224
231
|
args.push('--mode', opts.mode);
|
package/cli/helpers/copy.ts
CHANGED
|
@@ -9,23 +9,26 @@ interface CopyOption {
|
|
|
9
9
|
|
|
10
10
|
const excludeFiles = [
|
|
11
11
|
'.git',
|
|
12
|
+
'.github',
|
|
13
|
+
'.npmrc',
|
|
12
14
|
'bin',
|
|
15
|
+
'cli',
|
|
16
|
+
'xpack',
|
|
13
17
|
'.vscode',
|
|
14
18
|
'.build',
|
|
19
|
+
'node_modules',
|
|
20
|
+
'server.ts',
|
|
21
|
+
'prerender.ts',
|
|
22
|
+
'integration.ts',
|
|
23
|
+
'styles.ts',
|
|
24
|
+
'scripts.ts',
|
|
25
|
+
'states.ts',
|
|
26
|
+
'migrate-scss.ts',
|
|
27
|
+
'vite.config.ts',
|
|
28
|
+
'vite.cli.config.ts',
|
|
29
|
+
'src',
|
|
15
30
|
'public/samples',
|
|
16
31
|
'public/assets/vendors',
|
|
17
|
-
'src/_api/!(_base.ts)',
|
|
18
|
-
'src/_data',
|
|
19
|
-
'src/assets/scripts/!(color-mode|main|mock-api|pl-states|root|theme-critical).entry.ts',
|
|
20
|
-
'src/atoms',
|
|
21
|
-
'src/mocks/avatar',
|
|
22
|
-
'src/mocks/user',
|
|
23
|
-
'src/molecules',
|
|
24
|
-
'src/organisms/!(root|header|footer)/*',
|
|
25
|
-
'src/pages/!(Root|Home).tsx',
|
|
26
|
-
'src/templates/!(root|home)/*',
|
|
27
|
-
'!cli',
|
|
28
|
-
'!vite.cli.config.ts',
|
|
29
32
|
];
|
|
30
33
|
|
|
31
34
|
const copy = async (src: string | string[], dest: string, { cwd }: CopyOption) => {
|
|
@@ -39,10 +42,6 @@ const copy = async (src: string | string[], dest: string, { cwd }: CopyOption) =
|
|
|
39
42
|
|
|
40
43
|
const destRelativeToCwd = path.resolve(dest);
|
|
41
44
|
|
|
42
|
-
await fs.mkdir(path.join(destRelativeToCwd, 'src/atoms'), { recursive: true });
|
|
43
|
-
await fs.mkdir(path.join(destRelativeToCwd, 'src/molecules'), { recursive: true });
|
|
44
|
-
await fs.mkdir(path.join(destRelativeToCwd, 'src/mocks/example'), { recursive: true });
|
|
45
|
-
|
|
46
45
|
return Promise.all(
|
|
47
46
|
sourceFiles.map(async (p) => {
|
|
48
47
|
const dirname = path.dirname(p);
|
|
@@ -2,6 +2,11 @@ import path from 'path';
|
|
|
2
2
|
import os from 'os';
|
|
3
3
|
import fs from 'fs/promises';
|
|
4
4
|
|
|
5
|
+
const writeFile = async (filePath: string, data: string) => {
|
|
6
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
7
|
+
await fs.writeFile(filePath, data);
|
|
8
|
+
};
|
|
9
|
+
|
|
5
10
|
const formatFiles = async (root: string) => {
|
|
6
11
|
let filePath, data;
|
|
7
12
|
|
|
@@ -9,7 +14,7 @@ const formatFiles = async (root: string) => {
|
|
|
9
14
|
filePath = path.join(root, 'src/mocks/handlers.ts');
|
|
10
15
|
data = "import { handlers } from './consts';\n\nexport { handlers };";
|
|
11
16
|
|
|
12
|
-
await
|
|
17
|
+
await writeFile(filePath, data + os.EOL);
|
|
13
18
|
|
|
14
19
|
// example mock file
|
|
15
20
|
filePath = path.join(root, 'src/mocks/example/index.ts');
|
|
@@ -24,11 +29,10 @@ const formatFiles = async (root: string) => {
|
|
|
24
29
|
);
|
|
25
30
|
`;
|
|
26
31
|
|
|
27
|
-
await
|
|
32
|
+
await writeFile(filePath, data + os.EOL);
|
|
28
33
|
|
|
29
34
|
// react loader
|
|
30
35
|
filePath = path.join(root, 'src/react-loader.tsx');
|
|
31
|
-
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
32
36
|
data = [
|
|
33
37
|
"import { lazy } from 'react';",
|
|
34
38
|
'',
|
|
@@ -38,12 +42,12 @@ const formatFiles = async (root: string) => {
|
|
|
38
42
|
'',
|
|
39
43
|
].join('\n');
|
|
40
44
|
|
|
41
|
-
await
|
|
45
|
+
await writeFile(filePath, data);
|
|
42
46
|
|
|
43
47
|
// src/_types/atoms.d.ts
|
|
44
48
|
filePath = path.join(root, 'src/_types/atoms.d.ts');
|
|
45
49
|
|
|
46
|
-
await
|
|
50
|
+
await writeFile(
|
|
47
51
|
filePath,
|
|
48
52
|
`
|
|
49
53
|
import { BasedAtomicModel } from "./_general";
|
|
@@ -53,7 +57,7 @@ const formatFiles = async (root: string) => {
|
|
|
53
57
|
// src/_types/molecules.d.d.ts
|
|
54
58
|
filePath = path.join(root, 'src/_types/molecules.d.ts');
|
|
55
59
|
|
|
56
|
-
await
|
|
60
|
+
await writeFile(
|
|
57
61
|
filePath,
|
|
58
62
|
`
|
|
59
63
|
import { BasedAtomicModel } from "./_general";
|
|
@@ -63,7 +67,7 @@ const formatFiles = async (root: string) => {
|
|
|
63
67
|
// src/_types/organisms.d.ts
|
|
64
68
|
filePath = path.join(root, 'src/_types/organisms.d.ts');
|
|
65
69
|
|
|
66
|
-
await
|
|
70
|
+
await writeFile(
|
|
67
71
|
filePath,
|
|
68
72
|
`
|
|
69
73
|
import { BasedAtomicModel } from "./_general";
|
|
@@ -77,7 +81,7 @@ const formatFiles = async (root: string) => {
|
|
|
77
81
|
// pages/Home.tsx
|
|
78
82
|
filePath = path.join(root, 'src/pages/Home.tsx');
|
|
79
83
|
|
|
80
|
-
await
|
|
84
|
+
await writeFile(
|
|
81
85
|
filePath,
|
|
82
86
|
`
|
|
83
87
|
import Template from '@templates/home/Home';
|
|
@@ -93,7 +97,7 @@ const formatFiles = async (root: string) => {
|
|
|
93
97
|
// templates/home/Home.tsx
|
|
94
98
|
filePath = path.join(root, 'src/templates/home/Home.tsx');
|
|
95
99
|
|
|
96
|
-
await
|
|
100
|
+
await writeFile(
|
|
97
101
|
filePath,
|
|
98
102
|
`
|
|
99
103
|
import { FooterModel, HeaderModel } from '@_types/organisms';
|
|
@@ -128,7 +132,7 @@ const formatFiles = async (root: string) => {
|
|
|
128
132
|
// src/organisms/header/Header.tsx
|
|
129
133
|
filePath = path.join(root, 'src/organisms/header/Header.tsx');
|
|
130
134
|
|
|
131
|
-
await
|
|
135
|
+
await writeFile(
|
|
132
136
|
filePath,
|
|
133
137
|
`
|
|
134
138
|
import { getModifiers } from '@helpers/functions';
|
|
@@ -153,12 +157,12 @@ const formatFiles = async (root: string) => {
|
|
|
153
157
|
// src/organisms/header/Header.scss
|
|
154
158
|
filePath = path.join(root, 'src/organisms/header/Header.scss');
|
|
155
159
|
|
|
156
|
-
await
|
|
160
|
+
await writeFile(filePath, '');
|
|
157
161
|
|
|
158
162
|
// src/organisms/footer/Footer.tsx
|
|
159
163
|
filePath = path.join(root, 'src/organisms/footer/Footer.tsx');
|
|
160
164
|
|
|
161
|
-
await
|
|
165
|
+
await writeFile(
|
|
162
166
|
filePath,
|
|
163
167
|
`
|
|
164
168
|
import { getModifiers } from '@helpers/functions';
|
|
@@ -183,7 +187,7 @@ const formatFiles = async (root: string) => {
|
|
|
183
187
|
// src/organisms/footer/Footer.scss
|
|
184
188
|
filePath = path.join(root, 'src/organisms/footer/Footer.scss');
|
|
185
189
|
|
|
186
|
-
await
|
|
190
|
+
await writeFile(filePath, '');
|
|
187
191
|
|
|
188
192
|
return ['xxx'];
|
|
189
193
|
};
|
package/cli/install-template.ts
CHANGED
|
@@ -9,6 +9,7 @@ import chalk from 'chalk';
|
|
|
9
9
|
import { copy } from './helpers/copy.js';
|
|
10
10
|
import { install } from './helpers/install.js';
|
|
11
11
|
import { formatFiles } from './helpers/format-files.js';
|
|
12
|
+
import packageJson_ from '../package.json';
|
|
12
13
|
|
|
13
14
|
export const filename = fileURLToPath(import.meta.url);
|
|
14
15
|
export const dirname = path.dirname(filename);
|
|
@@ -32,30 +33,30 @@ const installTemplate = async (model: Props) => {
|
|
|
32
33
|
|
|
33
34
|
await formatFiles(root);
|
|
34
35
|
|
|
35
|
-
const packageJson =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
36
|
+
const packageJson = {
|
|
37
|
+
name: appName,
|
|
38
|
+
description: '',
|
|
39
|
+
version: '0.1.0',
|
|
40
|
+
type: 'module',
|
|
41
|
+
private: true,
|
|
42
|
+
scripts: {
|
|
43
|
+
start: 'buner dev',
|
|
44
|
+
dev: 'buner dev',
|
|
45
|
+
serve: 'buner serve',
|
|
46
|
+
build: 'buner build',
|
|
47
|
+
generate: 'buner generate',
|
|
48
|
+
eshn: 'buner eshn',
|
|
49
|
+
inte: 'buner inte',
|
|
50
|
+
styles: 'buner styles',
|
|
51
|
+
prerender: 'buner prerender',
|
|
52
|
+
},
|
|
53
|
+
dependencies: {
|
|
54
|
+
buner: `^${packageJson_.version}`,
|
|
55
|
+
react: '^19.0.0',
|
|
56
|
+
'react-dom': '^19.0.0',
|
|
57
|
+
'react-router-dom': '^7.0.0',
|
|
58
|
+
},
|
|
59
|
+
};
|
|
59
60
|
|
|
60
61
|
await fs.writeFile(path.join(root, 'package.json'), JSON.stringify(packageJson, null, 2) + os.EOL);
|
|
61
62
|
|
|
@@ -65,12 +66,6 @@ const installTemplate = async (model: Props) => {
|
|
|
65
66
|
console.log(`- ${cyan(dependency)}`);
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
if (devDeps) {
|
|
69
|
-
console.log('\nInstalling devDependencies:');
|
|
70
|
-
|
|
71
|
-
for (const dependency in packageJson.devDependencies) console.log(`- ${cyan(dependency)}`);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
69
|
await install();
|
|
75
70
|
};
|
|
76
71
|
|
package/package.json
CHANGED