create-lve 0.2.3 → 0.2.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/index.js +114 -109
- package/package.json +1 -1
- package/template-react/package.json +1 -3
- package/template-react/src/main.tsx +0 -1
- package/template-react/src/style.css +0 -0
- package/template-react/vite.config.ts +1 -3
- package/template-vue/package.json +0 -4
- package/template-vue/src/main.ts +0 -1
- package/template-vue/src/style.css +0 -1
- package/template-vue/vite.config.ts +1 -2
- package/template-react/src/index.css +0 -1
package/index.js
CHANGED
|
@@ -11,151 +11,156 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
11
11
|
async function main() {
|
|
12
12
|
console.clear();
|
|
13
13
|
const logo = `
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
${pc.cyan("█ █ █ █▀▀▀")}
|
|
15
|
+
${pc.cyan("█ █ █ █▀▀ ")}
|
|
16
|
+
${pc.cyan("█▄▄▄ ▀▄▀ █▄▄▄")} ${pc.gray("THE ULTRA-FAST FRONTEND STACK")}
|
|
17
17
|
`;
|
|
18
18
|
|
|
19
19
|
console.log(logo);
|
|
20
|
-
p.intro(
|
|
21
|
-
`${pc.bgCyan(pc.black(" LVE-CLI "))} ` +
|
|
22
|
-
pc.gray("The Ultra-Fast Frontend Stack (") +
|
|
23
|
-
pc.blue("Vite") +
|
|
24
|
-
pc.gray(" + ") +
|
|
25
|
-
pc.yellow("Oxc") +
|
|
26
|
-
pc.gray(" + ") +
|
|
27
|
-
pc.cyan("Tailwind") +
|
|
28
|
-
pc.gray(")"),
|
|
29
|
-
);
|
|
20
|
+
p.intro(`${pc.bgCyan(pc.black(" LVE-CLI "))}`);
|
|
30
21
|
|
|
31
22
|
const project = await p.group(
|
|
32
23
|
{
|
|
33
|
-
path: () =>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}),
|
|
24
|
+
path: () => p.text({
|
|
25
|
+
message: "项目名称",
|
|
26
|
+
placeholder: "my-app",
|
|
27
|
+
defaultValue: "my-app",
|
|
28
|
+
validate: (value) => {
|
|
29
|
+
if (!value || value.length === 0) return;
|
|
30
|
+
if (value.match(/[<>:"|?*]/)) return "路径包含非法字符";
|
|
31
|
+
},
|
|
32
|
+
}),
|
|
43
33
|
shouldOverwrite: ({ results }) => {
|
|
44
34
|
const targetDir = path.resolve(process.cwd(), results.path);
|
|
45
35
|
if (fs.existsSync(targetDir) && fs.readdirSync(targetDir).length > 0) {
|
|
46
|
-
return p.confirm({
|
|
47
|
-
message: `⚠️ 目录 ${pc.yellow(results.path)} 已存在且不为空,是否清空?`,
|
|
48
|
-
initialValue: false,
|
|
49
|
-
});
|
|
36
|
+
return p.confirm({ message: `目录已存在,是否清空?`, initialValue: false });
|
|
50
37
|
}
|
|
51
38
|
},
|
|
52
|
-
framework: () =>
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
},
|
|
39
|
+
framework: () => p.select({
|
|
40
|
+
message: "选择框架",
|
|
41
|
+
options: [
|
|
42
|
+
{ value: "react", label: "React 19", hint: "VitePlus + Compiler" },
|
|
43
|
+
{ value: "vue", label: "Vue 3", hint: "VitePlus + Optimized" },
|
|
44
|
+
],
|
|
45
|
+
}),
|
|
46
|
+
cssEngine: () => p.select({
|
|
47
|
+
message: "选择 CSS 引擎",
|
|
48
|
+
options: [
|
|
49
|
+
{ value: "unocss", label: "UnoCSS", hint: "⚡️ 战机级性能:动态代码注入,实现源码级‘无感’混淆" },
|
|
50
|
+
{ value: "tailwind", label: "Tailwind v4", hint: "🛡️ 装甲级稳定:v4 引擎重构,完美适配所有主流 UI 库" },
|
|
51
|
+
],
|
|
52
|
+
}),
|
|
66
53
|
},
|
|
54
|
+
{ onCancel: () => { p.cancel("操作取消"); process.exit(0); } }
|
|
67
55
|
);
|
|
68
56
|
|
|
69
|
-
if (project.shouldOverwrite === false) {
|
|
70
|
-
p.cancel("操作终止:请更换目录名后再试");
|
|
71
|
-
process.exit(0);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
57
|
const targetDir = path.resolve(process.cwd(), project.path);
|
|
75
58
|
const templateDir = path.resolve(__dirname, `template-${project.framework}`);
|
|
76
|
-
const
|
|
59
|
+
const isUno = project.cssEngine === "unocss";
|
|
77
60
|
const s = p.spinner();
|
|
78
|
-
|
|
61
|
+
|
|
62
|
+
s.start("🛠️ 正在按需装配架构...");
|
|
79
63
|
|
|
80
64
|
try {
|
|
81
|
-
if (project.shouldOverwrite)
|
|
82
|
-
|
|
83
|
-
} else {
|
|
84
|
-
await fs.ensureDir(targetDir);
|
|
85
|
-
}
|
|
65
|
+
if (project.shouldOverwrite) await fs.emptyDir(targetDir);
|
|
66
|
+
else await fs.ensureDir(targetDir);
|
|
86
67
|
|
|
87
68
|
await fs.copy(templateDir, targetDir);
|
|
88
69
|
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
};
|
|
70
|
+
const oldGit = path.join(targetDir, "_gitignore");
|
|
71
|
+
if (fs.existsSync(oldGit)) await fs.move(oldGit, path.join(targetDir, ".gitignore"));
|
|
92
72
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
73
|
+
const pkgPath = path.join(targetDir, "package.json");
|
|
74
|
+
const pkg = await fs.readJson(pkgPath);
|
|
75
|
+
pkg.name = path.basename(targetDir);
|
|
76
|
+
|
|
77
|
+
if (isUno) {
|
|
78
|
+
pkg.devDependencies["unocss"] = "latest";
|
|
79
|
+
} else {
|
|
80
|
+
pkg.devDependencies["tailwindcss"] = "latest";
|
|
81
|
+
pkg.devDependencies["@tailwindcss/vite"] = "latest";
|
|
98
82
|
}
|
|
99
83
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (project.framework === "react") {
|
|
105
|
-
pkg.dependencies = {
|
|
106
|
-
...pkg.dependencies,
|
|
107
|
-
react: "latest",
|
|
108
|
-
"react-dom": "latest",
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
pkg.devDependencies = {
|
|
112
|
-
...pkg.devDependencies,
|
|
113
|
-
"vite-plus": "latest",
|
|
114
|
-
tailwindcss: "latest",
|
|
115
|
-
"@tailwindcss/vite": "latest",
|
|
116
|
-
"babel-plugin-react-compiler": "latest",
|
|
117
|
-
};
|
|
118
|
-
} else {
|
|
119
|
-
pkg.dependencies = {
|
|
120
|
-
...pkg.dependencies,
|
|
121
|
-
vue: "latest",
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
pkg.devDependencies = {
|
|
125
|
-
...pkg.devDependencies,
|
|
126
|
-
"vite-plus": "latest",
|
|
127
|
-
tailwindcss: "latest",
|
|
128
|
-
"@tailwindcss/vite": "latest",
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
pkg.pnpm = pkg.pnpm || {};
|
|
132
|
-
pkg.pnpm.overrides = {
|
|
133
|
-
...pkg.pnpm.overrides,
|
|
84
|
+
pkg.pnpm = {
|
|
85
|
+
...pkg.pnpm,
|
|
86
|
+
overrides: {
|
|
87
|
+
...pkg.pnpm?.overrides,
|
|
134
88
|
vite: "npm:@voidzero-dev/vite-plus-core@latest",
|
|
135
89
|
vitest: "npm:@voidzero-dev/vite-plus-test@latest",
|
|
136
|
-
}
|
|
137
|
-
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
93
|
+
|
|
94
|
+
const mainFile = project.framework === "vue" ? "src/main.ts" : "src/main.tsx";
|
|
95
|
+
const mainPath = path.join(targetDir, mainFile);
|
|
96
|
+
const viteConfigPath = path.join(targetDir, "vite.config.ts");
|
|
97
|
+
const stylePath = path.join(targetDir, "src/style.css");
|
|
98
|
+
|
|
99
|
+
let mainContent = await fs.readFile(mainPath, "utf-8");
|
|
100
|
+
let viteContent = await fs.readFile(viteConfigPath, "utf-8");
|
|
101
|
+
|
|
102
|
+
if (isUno) {
|
|
103
|
+
const unoConfig = `import { defineConfig, presetWind3, transformerCompileClass } from 'unocss'
|
|
104
|
+
|
|
105
|
+
export default defineConfig({
|
|
106
|
+
presets: [presetWind3()],
|
|
107
|
+
transformers: [
|
|
108
|
+
{
|
|
109
|
+
name: 'auto-uno-injector',
|
|
110
|
+
enforce: 'pre',
|
|
111
|
+
idFilter(id) {
|
|
112
|
+
return id.match(/\\.[tj]sx$|\\.vue$/)
|
|
113
|
+
},
|
|
114
|
+
async transform(code) {
|
|
115
|
+
const classRegex = /(?:class|className)=["']([^"']+)["']/g
|
|
116
|
+
let match
|
|
117
|
+
while ((match = classRegex.exec(code.original))) {
|
|
118
|
+
const content = match[1]
|
|
119
|
+
if (content.trim() && !content.includes(':uno:')) {
|
|
120
|
+
const insertPos = match.index + match[0].indexOf(content)
|
|
121
|
+
code.appendLeft(insertPos, ':uno: ')
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
transformerCompileClass({
|
|
127
|
+
classPrefix: 'kfc-',
|
|
128
|
+
}),
|
|
129
|
+
],
|
|
130
|
+
})\n
|
|
131
|
+
`;
|
|
132
|
+
|
|
133
|
+
await fs.writeFile(path.join(targetDir, "uno.config.ts"), unoConfig);
|
|
134
|
+
|
|
135
|
+
mainContent = `import 'virtual:uno.css'\n` + mainContent;
|
|
136
|
+
viteContent = `import UnoCSS from 'unocss/vite'\n` + viteContent;
|
|
137
|
+
viteContent = viteContent.replace(/plugins:\s*\[/, "plugins: [UnoCSS(), ");
|
|
138
|
+
|
|
139
|
+
if (fs.existsSync(stylePath)) await fs.remove(stylePath);
|
|
140
|
+
} else {
|
|
141
|
+
await fs.writeFile(stylePath, `@import "tailwindcss";`);
|
|
142
|
+
|
|
143
|
+
mainContent = `import './style.css'\n` + mainContent;
|
|
144
|
+
viteContent = `import tailwindcss from '@tailwindcss/vite'\n` + viteContent;
|
|
145
|
+
viteContent = viteContent.replace(/plugins:\s*\[/, "plugins: [tailwindcss(), ");
|
|
138
146
|
}
|
|
139
147
|
|
|
148
|
+
await fs.writeFile(mainPath, mainContent);
|
|
149
|
+
await fs.writeFile(viteConfigPath, viteContent);
|
|
150
|
+
|
|
140
151
|
const toRemove = ["pnpm-lock.yaml", "node_modules", "dist"];
|
|
141
152
|
await Promise.all(toRemove.map((file) => fs.remove(path.join(targetDir, file))));
|
|
142
153
|
|
|
143
|
-
s.stop(pc.green("
|
|
144
|
-
|
|
145
|
-
const relativePath = path.relative(process.cwd(), targetDir);
|
|
146
|
-
const cdCmd = relativePath === "" ? "" : `cd ${relativePath}\n`;
|
|
154
|
+
s.stop(pc.green("装配完成!"));
|
|
147
155
|
|
|
148
|
-
p.note(pc.cyan(
|
|
156
|
+
p.note(pc.cyan(`cd ${project.path}\nvp install\nvp dev`), "快速开始");
|
|
157
|
+
p.outro(`${pc.magenta("✨ 已经为你准备好了极致的开发环境!")}\n${pc.gray(`==== ${project.framework} + ${project.cssEngine} ====`)}`);
|
|
149
158
|
|
|
150
|
-
p.outro(
|
|
151
|
-
`${pc.magenta("✨ Happy Coding!")}\n` +
|
|
152
|
-
`${pc.gray(` ==== VitePlus + OXC + ${frameworkName} ====`)}`,
|
|
153
|
-
);
|
|
154
159
|
} catch (err) {
|
|
155
|
-
s.stop("
|
|
156
|
-
console.error(
|
|
160
|
+
s.stop(pc.red("手术失败"));
|
|
161
|
+
console.error(err);
|
|
157
162
|
process.exit(1);
|
|
158
163
|
}
|
|
159
164
|
}
|
|
160
165
|
|
|
161
|
-
main();
|
|
166
|
+
main();
|
package/package.json
CHANGED
|
File without changes
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { defineConfig } from "vite-plus"
|
|
2
2
|
import react from "@vitejs/plugin-react"
|
|
3
|
-
import tailwindcss from '@tailwindcss/vite'
|
|
4
3
|
|
|
5
4
|
// https://vite.dev/config/
|
|
6
5
|
export default defineConfig({
|
|
@@ -16,7 +15,6 @@ export default defineConfig({
|
|
|
16
15
|
["babel-plugin-react-compiler", { target: "19" }]
|
|
17
16
|
],
|
|
18
17
|
},
|
|
19
|
-
} as any),
|
|
20
|
-
tailwindcss()
|
|
18
|
+
} as any),
|
|
21
19
|
],
|
|
22
20
|
});
|
|
@@ -10,16 +10,12 @@
|
|
|
10
10
|
"prepare": "vp config"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@tailwindcss/vite": "^4.2.1",
|
|
14
|
-
"tailwindcss": "^4.2.1",
|
|
15
13
|
"vue": "latest"
|
|
16
14
|
},
|
|
17
15
|
"devDependencies": {
|
|
18
|
-
"@tailwindcss/vite": "latest",
|
|
19
16
|
"@types/node": "^24.12.2",
|
|
20
17
|
"@vitejs/plugin-vue": "^6.0.5",
|
|
21
18
|
"@vue/tsconfig": "^0.9.1",
|
|
22
|
-
"tailwindcss": "latest",
|
|
23
19
|
"typescript": "~6.0.2",
|
|
24
20
|
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
|
|
25
21
|
"vite-plus": "latest",
|
package/template-vue/src/main.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@import 'tailwindcss';
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { defineConfig } from 'vite-plus'
|
|
2
2
|
import vue from '@vitejs/plugin-vue'
|
|
3
|
-
import tailwindcss from '@tailwindcss/vite'
|
|
4
3
|
|
|
5
4
|
// https://vite.dev/config/
|
|
6
5
|
export default defineConfig({
|
|
@@ -9,5 +8,5 @@ export default defineConfig({
|
|
|
9
8
|
'*': 'vp check --fix',
|
|
10
9
|
},
|
|
11
10
|
lint: { options: { typeAware: true, typeCheck: true } },
|
|
12
|
-
plugins: [vue()
|
|
11
|
+
plugins: [vue()],
|
|
13
12
|
})
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@import 'tailwindcss';
|