buner 1.0.3 → 1.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/bin/buner.js +91 -73
- package/cli/buner.ts +60 -30
- package/cli/helpers/copy.ts +15 -16
- package/cli/install-template.ts +25 -30
- package/package.json +2 -1
package/bin/buner.js
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
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.5";
|
|
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";
|
|
20
20
|
const repository = { "type": "git", "url": "https://github.com/precise-alloy/buner.git" };
|
|
21
21
|
const homepage = "https://www.npmjs.com/package/buner";
|
|
22
22
|
const keywords = ["vite", "react", "ssr", "scss", "prerender", "frontend", "build-tool", "cli"];
|
|
23
|
-
const bin = { "buner": "./bin/buner.js" };
|
|
23
|
+
const bin$1 = { "buner": "./bin/buner.js" };
|
|
24
24
|
const files = ["bin", "cli", "xpack", "public", "server.ts", "prerender.ts", "integration.ts", "styles.ts", "scripts.ts", "states.ts", "migrate-scss.ts", "vite.config.ts", "index.html", "tsconfig.json", "eslint.config.mjs", "types.d.ts", ".env", ".env.development", ".env.eshn", "README.md"];
|
|
25
25
|
const scripts = { "start": "bun run dev", "predev": "bun upgrade", "dev": 'concurrently --kill-others "bun styles.ts --watch" "bun states.ts --watch" "cross-env scriptOnly=true vite build --mode development --watch" "bun server.ts --mode development"', "serve": "bun server.ts", "watch": "bun server.ts", "build": "bun run build:static && bun run build:server", "build:eshn": "bun run build:static:eshn && bun run build:server:eshn", "preview": "vite preview", "build:server": "vite build --ssr src/entry-server.tsx --outDir dist/server", "build:server:eshn": "vite build --ssr src/entry-server.tsx --outDir dist/server --mode eshn", "build:static": "vite build --outDir dist/static", "build:static:eshn": "vite build --outDir dist/static --mode eshn", "generate": "bun states.ts && bun run styles && bun run build && bun prerender.ts --add-hash", "eshn": "bun states.ts && bun run styles && bun run build:eshn && bun prerender.ts --add-hash --mode eshn", "inte": "bun run styles && bun run build && bun prerender.ts && bun integration.ts", "styles": "bun styles.ts", "format": "prettier --write .", "lint": "eslint --fix", "cli:start": "vite build -c vite.cli.config.ts --watch", "cli:build": "vite build -c vite.cli.config.ts" };
|
|
26
26
|
const engines = { "node": ">=20.0.0" };
|
|
27
|
-
const dependencies = { "@vitejs/plugin-react": "^5.1.4", "autoprefixer": "^10.4.27", "chalk": "^5.5.0", "cheerio": "^1.2.0", "chokidar": "^4.0.3", "commander": "^14.0.3", "concurrently": "^9.2.0", "cross-env": "^10.1.0", "cssnano": "^7.1.0", "debounce": "^3.0.0", "express": "^5.2.1", "glob": "^13.0.6", "globby": "^16.1.1", "js-beautify": "^1.15.4", "lodash": "^4.17.21", "magic-string": "^0.30.17", "node-fetch": "^3.3.2", "postcss": "^8.5.8", "prompts": "^2.4.2", "sass": "^1.89.2", "slash": "^5.1.0", "validate-npm-package-name": "^7.0.0", "vite": "^7.0.6" };
|
|
27
|
+
const dependencies = { "@vitejs/plugin-react": "^5.1.4", "autoprefixer": "^10.4.27", "chalk": "^5.5.0", "cheerio": "^1.2.0", "chokidar": "^4.0.3", "commander": "^14.0.3", "concurrently": "^9.2.0", "cross-env": "^10.1.0", "cssnano": "^7.1.0", "debounce": "^3.0.0", "express": "^5.2.1", "glob": "^13.0.6", "globby": "^16.1.1", "js-beautify": "^1.15.4", "lodash": "^4.17.21", "magic-string": "^0.30.17", "node-fetch": "^3.3.2", "postcss": "^8.5.8", "prompts": "^2.4.2", "sass": "^1.89.2", "slash": "^5.1.0", "tsx": "^4.19.0", "validate-npm-package-name": "^7.0.0", "vite": "^7.0.6" };
|
|
28
28
|
const peerDependencies = { "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0", "react-router-dom": "^6.0.0 || ^7.0.0" };
|
|
29
29
|
const devDependencies = { "@eslint/compat": "^2.0.0", "@next/eslint-plugin-next": "^16.0.8", "@types/css": "^0.0.38", "@types/debounce": "^1.2.4", "@types/express": "^5.0.6", "@types/js-beautify": "^1.14.3", "@types/lodash": "^4.17.24", "@types/node": "^24.11.0", "@types/prettier": "^3.0.0", "@types/prompts": "^2.4.9", "@types/react": "^19.2.14", "@types/react-dom": "^19.1.7", "@types/validate-npm-package-name": "^4.0.2", "@typescript-eslint/eslint-plugin": "^8.50.0", "@typescript-eslint/parser": "^8.50.0", "css": "^3.0.0", "eslint": "^9.39.2", "eslint-config-next": "^16.0.8", "eslint-config-prettier": "10.1.8", "eslint-plugin-import": "2.32.0", "eslint-plugin-jsx-a11y": "6.10.2", "eslint-plugin-node": "11.1.0", "eslint-plugin-prettier": "^5.5.5", "eslint-plugin-react": "7.37.5", "eslint-plugin-react-hooks": "7.0.1", "eslint-plugin-react-refresh": "^0.5.2", "eslint-plugin-unused-imports": "^4.4.1", "globals": "^16.3.0", "msw": "^2.12.10", "postcss-scss": "^4.0.9", "prettier": "^3.6.2", "react": "^19.2.4", "react-dom": "^19.2.4", "react-router-dom": "^7.13.1", "rollup": "^4.59.0", "svgo": "^4.0.0" };
|
|
30
30
|
const msw = { "workerDirectory": "public" };
|
|
@@ -37,7 +37,7 @@ const packageJson = {
|
|
|
37
37
|
repository,
|
|
38
38
|
homepage,
|
|
39
39
|
keywords,
|
|
40
|
-
bin,
|
|
40
|
+
bin: bin$1,
|
|
41
41
|
files,
|
|
42
42
|
scripts,
|
|
43
43
|
engines,
|
|
@@ -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);
|
|
@@ -356,32 +356,35 @@ const installTemplate = async (model) => {
|
|
|
356
356
|
cwd: path.join(dirname, "..")
|
|
357
357
|
});
|
|
358
358
|
await formatFiles(root);
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
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"
|
|
372
381
|
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
if (!devDeps) delete packageJson2.devDependencies;
|
|
376
|
-
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);
|
|
377
384
|
console.log("\nInstalling dependencies:");
|
|
378
|
-
for (const dependency in
|
|
385
|
+
for (const dependency in packageJson$1.dependencies) {
|
|
379
386
|
console.log(`- ${cyan$1(dependency)}`);
|
|
380
387
|
}
|
|
381
|
-
if (devDeps) {
|
|
382
|
-
console.log("\nInstalling devDependencies:");
|
|
383
|
-
for (const dependency in packageJson2.devDependencies) console.log(`- ${cyan$1(dependency)}`);
|
|
384
|
-
}
|
|
385
388
|
await install();
|
|
386
389
|
};
|
|
387
390
|
const { green: green$1 } = chalk;
|
|
@@ -427,6 +430,22 @@ function validateNpmName(name2) {
|
|
|
427
430
|
}
|
|
428
431
|
const { green, yellow, bold, cyan, red } = chalk;
|
|
429
432
|
const packageName = "buner";
|
|
433
|
+
const packageDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
434
|
+
const pkg = (file) => path.join(packageDir, file);
|
|
435
|
+
const bin = (name2) => {
|
|
436
|
+
const ext = process.platform === "win32" ? ".cmd" : "";
|
|
437
|
+
const local = path.join(packageDir, "node_modules", ".bin", name2 + ext);
|
|
438
|
+
try {
|
|
439
|
+
if (require("fs").existsSync(local)) return local;
|
|
440
|
+
} catch {
|
|
441
|
+
}
|
|
442
|
+
const consumerBin = path.join(process.cwd(), "node_modules", ".bin", name2 + ext);
|
|
443
|
+
try {
|
|
444
|
+
if (require("fs").existsSync(consumerBin)) return consumerBin;
|
|
445
|
+
} catch {
|
|
446
|
+
}
|
|
447
|
+
return name2;
|
|
448
|
+
};
|
|
430
449
|
const run = (cmd, args = [], options = {}) => {
|
|
431
450
|
return new Promise((resolve, reject) => {
|
|
432
451
|
const child = spawn(cmd, args, {
|
|
@@ -510,58 +529,57 @@ For example:
|
|
|
510
529
|
await notifyUpdate();
|
|
511
530
|
});
|
|
512
531
|
program.command("dev").description("Start development mode with all watchers").action(async () => {
|
|
513
|
-
await run("
|
|
514
|
-
"concurrently",
|
|
532
|
+
await run(bin("concurrently"), [
|
|
515
533
|
"--kill-others",
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
534
|
+
`"${bin("tsx")} ${pkg("styles.ts")} --watch"`,
|
|
535
|
+
`"${bin("tsx")} ${pkg("states.ts")} --watch"`,
|
|
536
|
+
`"${bin("cross-env")} scriptOnly=true ${bin("vite")} build --config ${pkg("vite.config.ts")} --mode development --watch"`,
|
|
537
|
+
`"${bin("tsx")} ${pkg("server.ts")} --mode development"`
|
|
520
538
|
]);
|
|
521
539
|
});
|
|
522
540
|
program.command("serve").description("Start the SSR dev server").option("--mode <mode>", "server mode", "development").action(async (opts) => {
|
|
523
|
-
await run("
|
|
541
|
+
await run(bin("tsx"), [pkg("server.ts"), "--mode", opts.mode]);
|
|
524
542
|
});
|
|
525
543
|
program.command("build").description("Build the project (static + SSR)").action(async () => {
|
|
526
|
-
runSync("
|
|
527
|
-
runSync("
|
|
544
|
+
runSync(`${bin("vite")} build --config ${pkg("vite.config.ts")} --outDir dist/static`);
|
|
545
|
+
runSync(`${bin("vite")} build --config ${pkg("vite.config.ts")} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
528
546
|
});
|
|
529
547
|
program.command("generate").description("Full static site generation (states + styles + build + prerender)").option("--mode <mode>", "build mode", "production").action(async (opts) => {
|
|
530
|
-
runSync("
|
|
531
|
-
runSync("
|
|
548
|
+
runSync(`${bin("tsx")} ${pkg("states.ts")}`);
|
|
549
|
+
runSync(`${bin("tsx")} ${pkg("styles.ts")}`);
|
|
532
550
|
if (opts.mode === "production") {
|
|
533
|
-
runSync("
|
|
534
|
-
runSync("
|
|
551
|
+
runSync(`${bin("vite")} build --config ${pkg("vite.config.ts")} --outDir dist/static`);
|
|
552
|
+
runSync(`${bin("vite")} build --config ${pkg("vite.config.ts")} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
535
553
|
} else {
|
|
536
|
-
runSync(
|
|
537
|
-
runSync(
|
|
554
|
+
runSync(`${bin("vite")} build --config ${pkg("vite.config.ts")} --outDir dist/static --mode ${opts.mode}`);
|
|
555
|
+
runSync(`${bin("vite")} build --config ${pkg("vite.config.ts")} --ssr src/entry-server.tsx --outDir dist/server --mode ${opts.mode}`);
|
|
538
556
|
}
|
|
539
|
-
runSync(
|
|
557
|
+
runSync(`${bin("tsx")} ${pkg("prerender.ts")} --add-hash --mode ${opts.mode}`);
|
|
540
558
|
});
|
|
541
559
|
program.command("eshn").description("Generate with --mode eshn").action(async () => {
|
|
542
|
-
runSync("
|
|
543
|
-
runSync("
|
|
544
|
-
runSync("
|
|
545
|
-
runSync("
|
|
546
|
-
runSync("
|
|
560
|
+
runSync(`${bin("tsx")} ${pkg("states.ts")}`);
|
|
561
|
+
runSync(`${bin("tsx")} ${pkg("styles.ts")}`);
|
|
562
|
+
runSync(`${bin("vite")} build --config ${pkg("vite.config.ts")} --outDir dist/static --mode eshn`);
|
|
563
|
+
runSync(`${bin("vite")} build --config ${pkg("vite.config.ts")} --ssr src/entry-server.tsx --outDir dist/server --mode eshn`);
|
|
564
|
+
runSync(`${bin("tsx")} ${pkg("prerender.ts")} --add-hash --mode eshn`);
|
|
547
565
|
});
|
|
548
566
|
program.command("inte").description("Build and integrate with backend (styles + build + prerender + integration)").action(async () => {
|
|
549
|
-
runSync("
|
|
550
|
-
runSync("
|
|
551
|
-
runSync("
|
|
552
|
-
runSync("
|
|
553
|
-
runSync("
|
|
567
|
+
runSync(`${bin("tsx")} ${pkg("styles.ts")}`);
|
|
568
|
+
runSync(`${bin("vite")} build --config ${pkg("vite.config.ts")} --outDir dist/static`);
|
|
569
|
+
runSync(`${bin("vite")} build --config ${pkg("vite.config.ts")} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
570
|
+
runSync(`${bin("tsx")} ${pkg("prerender.ts")}`);
|
|
571
|
+
runSync(`${bin("tsx")} ${pkg("integration.ts")}`);
|
|
554
572
|
});
|
|
555
573
|
program.command("styles").description("Compile SCSS").option("--watch", "Watch for changes").action(async (opts) => {
|
|
556
|
-
const args = ["styles.ts"];
|
|
574
|
+
const args = [pkg("styles.ts")];
|
|
557
575
|
if (opts.watch) args.push("--watch");
|
|
558
|
-
await run("
|
|
576
|
+
await run(bin("tsx"), args);
|
|
559
577
|
});
|
|
560
578
|
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) => {
|
|
561
|
-
const args = ["prerender.ts"];
|
|
579
|
+
const args = [pkg("prerender.ts")];
|
|
562
580
|
if (opts.addHash) args.push("--add-hash");
|
|
563
581
|
args.push("--mode", opts.mode);
|
|
564
|
-
await run("
|
|
582
|
+
await run(bin("tsx"), args);
|
|
565
583
|
});
|
|
566
584
|
program.parseAsync(process.argv).catch(async (error) => {
|
|
567
585
|
console.log(red(error));
|
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,36 @@ 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
|
+
|
|
26
|
+
/** Resolve a binary from buner's own node_modules */
|
|
27
|
+
const bin = (name: string) => {
|
|
28
|
+
const ext = process.platform === 'win32' ? '.cmd' : '';
|
|
29
|
+
const local = path.join(packageDir, 'node_modules', '.bin', name + ext);
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
if (require('fs').existsSync(local)) return local;
|
|
33
|
+
} catch {
|
|
34
|
+
// ignore
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Fallback: try to find it in the consumer's node_modules
|
|
38
|
+
const consumerBin = path.join(process.cwd(), 'node_modules', '.bin', name + ext);
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
if (require('fs').existsSync(consumerBin)) return consumerBin;
|
|
42
|
+
} catch {
|
|
43
|
+
// ignore
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Last resort: rely on PATH
|
|
47
|
+
return name;
|
|
48
|
+
};
|
|
49
|
+
|
|
19
50
|
const run = (cmd: string, args: string[] = [], options: SpawnOptions = {}) => {
|
|
20
51
|
return new Promise<void>((resolve, reject) => {
|
|
21
52
|
const child = spawn(cmd, args, {
|
|
@@ -129,13 +160,12 @@ program
|
|
|
129
160
|
.command('dev')
|
|
130
161
|
.description('Start development mode with all watchers')
|
|
131
162
|
.action(async () => {
|
|
132
|
-
await run('
|
|
133
|
-
'concurrently',
|
|
163
|
+
await run(bin('concurrently'), [
|
|
134
164
|
'--kill-others',
|
|
135
|
-
'
|
|
136
|
-
'
|
|
137
|
-
'
|
|
138
|
-
'
|
|
165
|
+
`"${bin('tsx')} ${pkg('styles.ts')} --watch"`,
|
|
166
|
+
`"${bin('tsx')} ${pkg('states.ts')} --watch"`,
|
|
167
|
+
`"${bin('cross-env')} scriptOnly=true ${bin('vite')} build --config ${pkg('vite.config.ts')} --mode development --watch"`,
|
|
168
|
+
`"${bin('tsx')} ${pkg('server.ts')} --mode development"`,
|
|
139
169
|
]);
|
|
140
170
|
});
|
|
141
171
|
|
|
@@ -145,7 +175,7 @@ program
|
|
|
145
175
|
.description('Start the SSR dev server')
|
|
146
176
|
.option('--mode <mode>', 'server mode', 'development')
|
|
147
177
|
.action(async (opts) => {
|
|
148
|
-
await run('
|
|
178
|
+
await run(bin('tsx'), [pkg('server.ts'), '--mode', opts.mode]);
|
|
149
179
|
});
|
|
150
180
|
|
|
151
181
|
// buner build
|
|
@@ -153,8 +183,8 @@ program
|
|
|
153
183
|
.command('build')
|
|
154
184
|
.description('Build the project (static + SSR)')
|
|
155
185
|
.action(async () => {
|
|
156
|
-
runSync('
|
|
157
|
-
runSync('
|
|
186
|
+
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --outDir dist/static`);
|
|
187
|
+
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
158
188
|
});
|
|
159
189
|
|
|
160
190
|
// buner generate
|
|
@@ -163,16 +193,16 @@ program
|
|
|
163
193
|
.description('Full static site generation (states + styles + build + prerender)')
|
|
164
194
|
.option('--mode <mode>', 'build mode', 'production')
|
|
165
195
|
.action(async (opts) => {
|
|
166
|
-
runSync('
|
|
167
|
-
runSync('
|
|
196
|
+
runSync(`${bin('tsx')} ${pkg('states.ts')}`);
|
|
197
|
+
runSync(`${bin('tsx')} ${pkg('styles.ts')}`);
|
|
168
198
|
if (opts.mode === 'production') {
|
|
169
|
-
runSync('
|
|
170
|
-
runSync('
|
|
199
|
+
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --outDir dist/static`);
|
|
200
|
+
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
171
201
|
} else {
|
|
172
|
-
runSync(
|
|
173
|
-
runSync(
|
|
202
|
+
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --outDir dist/static --mode ${opts.mode}`);
|
|
203
|
+
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server --mode ${opts.mode}`);
|
|
174
204
|
}
|
|
175
|
-
runSync(
|
|
205
|
+
runSync(`${bin('tsx')} ${pkg('prerender.ts')} --add-hash --mode ${opts.mode}`);
|
|
176
206
|
});
|
|
177
207
|
|
|
178
208
|
// buner eshn
|
|
@@ -180,11 +210,11 @@ program
|
|
|
180
210
|
.command('eshn')
|
|
181
211
|
.description('Generate with --mode eshn')
|
|
182
212
|
.action(async () => {
|
|
183
|
-
runSync('
|
|
184
|
-
runSync('
|
|
185
|
-
runSync('
|
|
186
|
-
runSync('
|
|
187
|
-
runSync('
|
|
213
|
+
runSync(`${bin('tsx')} ${pkg('states.ts')}`);
|
|
214
|
+
runSync(`${bin('tsx')} ${pkg('styles.ts')}`);
|
|
215
|
+
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --outDir dist/static --mode eshn`);
|
|
216
|
+
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server --mode eshn`);
|
|
217
|
+
runSync(`${bin('tsx')} ${pkg('prerender.ts')} --add-hash --mode eshn`);
|
|
188
218
|
});
|
|
189
219
|
|
|
190
220
|
// buner inte
|
|
@@ -192,11 +222,11 @@ program
|
|
|
192
222
|
.command('inte')
|
|
193
223
|
.description('Build and integrate with backend (styles + build + prerender + integration)')
|
|
194
224
|
.action(async () => {
|
|
195
|
-
runSync('
|
|
196
|
-
runSync('
|
|
197
|
-
runSync('
|
|
198
|
-
runSync('
|
|
199
|
-
runSync('
|
|
225
|
+
runSync(`${bin('tsx')} ${pkg('styles.ts')}`);
|
|
226
|
+
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --outDir dist/static`);
|
|
227
|
+
runSync(`${bin('vite')} build --config ${pkg('vite.config.ts')} --ssr src/entry-server.tsx --outDir dist/server`);
|
|
228
|
+
runSync(`${bin('tsx')} ${pkg('prerender.ts')}`);
|
|
229
|
+
runSync(`${bin('tsx')} ${pkg('integration.ts')}`);
|
|
200
230
|
});
|
|
201
231
|
|
|
202
232
|
// buner styles
|
|
@@ -205,10 +235,10 @@ program
|
|
|
205
235
|
.description('Compile SCSS')
|
|
206
236
|
.option('--watch', 'Watch for changes')
|
|
207
237
|
.action(async (opts) => {
|
|
208
|
-
const args = ['styles.ts'];
|
|
238
|
+
const args = [pkg('styles.ts')];
|
|
209
239
|
|
|
210
240
|
if (opts.watch) args.push('--watch');
|
|
211
|
-
await run('
|
|
241
|
+
await run(bin('tsx'), args);
|
|
212
242
|
});
|
|
213
243
|
|
|
214
244
|
// buner prerender
|
|
@@ -218,11 +248,11 @@ program
|
|
|
218
248
|
.option('--add-hash', 'Add content hashes to asset URLs')
|
|
219
249
|
.option('--mode <mode>', 'build mode', 'production')
|
|
220
250
|
.action(async (opts) => {
|
|
221
|
-
const args = ['prerender.ts'];
|
|
251
|
+
const args = [pkg('prerender.ts')];
|
|
222
252
|
|
|
223
253
|
if (opts.addHash) args.push('--add-hash');
|
|
224
254
|
args.push('--mode', opts.mode);
|
|
225
|
-
await run('
|
|
255
|
+
await run(bin('tsx'), args);
|
|
226
256
|
});
|
|
227
257
|
|
|
228
258
|
program.parseAsync(process.argv).catch(async (error) => {
|
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);
|
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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "buner",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Frontend build toolkit for Vite + React SSR projects — SCSS pipeline, prerender, SSR dev server, and backend integration.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -91,6 +91,7 @@
|
|
|
91
91
|
"prompts": "^2.4.2",
|
|
92
92
|
"sass": "^1.89.2",
|
|
93
93
|
"slash": "^5.1.0",
|
|
94
|
+
"tsx": "^4.19.0",
|
|
94
95
|
"validate-npm-package-name": "^7.0.0",
|
|
95
96
|
"vite": "^7.0.6"
|
|
96
97
|
},
|