create-vue3-enterprise 1.0.0 → 1.0.21
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/dist/index.js +291 -130
- package/package.json +2 -4
- package/template/.husky/commit-msg +35 -0
- package/template/.husky/pre-commit +30 -0
- package/template/commitlint.config.js +28 -0
- package/template/lint-staged.config.js +8 -0
package/dist/index.js
CHANGED
|
@@ -1,48 +1,57 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import fs from
|
|
3
|
-
import path from
|
|
4
|
-
import { fileURLToPath } from
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { execSync } from "node:child_process";
|
|
6
|
+
import minimist from "minimist";
|
|
7
|
+
import prompts from "prompts";
|
|
8
|
+
import { red, green, cyan, yellow } from "kolorist";
|
|
8
9
|
const argv = minimist(process.argv.slice(2), {
|
|
9
|
-
string: [
|
|
10
|
-
boolean: [
|
|
10
|
+
string: ["_"],
|
|
11
|
+
boolean: ["help", "template", "force"],
|
|
11
12
|
alias: {
|
|
12
|
-
h:
|
|
13
|
-
t:
|
|
14
|
-
f:
|
|
15
|
-
}
|
|
13
|
+
h: "help",
|
|
14
|
+
t: "template",
|
|
15
|
+
f: "force",
|
|
16
|
+
},
|
|
16
17
|
});
|
|
17
18
|
const cwd = process.cwd();
|
|
18
19
|
const __filename = fileURLToPath(import.meta.url);
|
|
19
20
|
const __dirname = path.dirname(__filename);
|
|
20
21
|
function printHelp() {
|
|
21
22
|
console.log(`
|
|
22
|
-
${cyan(
|
|
23
|
+
${cyan("create-vue3-enterprise")}
|
|
23
24
|
|
|
24
|
-
${green(
|
|
25
|
-
npm create vue3-enterprise
|
|
25
|
+
${green("用法:")}
|
|
26
|
+
npm create vue3-enterprise <项目名称> [选项]
|
|
26
27
|
|
|
27
|
-
${green(
|
|
28
|
-
-h, --help
|
|
29
|
-
-
|
|
28
|
+
${green("选项:")}
|
|
29
|
+
-h, --help 显示帮助信息
|
|
30
|
+
-t, --template 指定模板(vue3-ts)
|
|
31
|
+
-f, --force 强制覆盖已存在的目录
|
|
30
32
|
|
|
31
|
-
${green(
|
|
33
|
+
${green("示例:")}
|
|
32
34
|
npm create vue3-enterprise my-project
|
|
35
|
+
npm create vue3-enterprise my-project --force
|
|
33
36
|
`);
|
|
34
37
|
}
|
|
35
38
|
function isValidPackageName(projectName) {
|
|
36
39
|
return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(projectName);
|
|
37
40
|
}
|
|
38
41
|
function toValidPackageName(projectName) {
|
|
39
|
-
return projectName
|
|
42
|
+
return projectName
|
|
43
|
+
.trim()
|
|
44
|
+
.toLowerCase()
|
|
45
|
+
.replace(/\s+/g, "-")
|
|
46
|
+
.replace(/^[._]/, "")
|
|
47
|
+
.replace(/[^a-z0-9-~]+/g, "-");
|
|
40
48
|
}
|
|
41
49
|
function emptyDir(dir) {
|
|
42
50
|
if (!fs.existsSync(dir))
|
|
43
51
|
return;
|
|
44
52
|
for (const file of fs.readdirSync(dir)) {
|
|
45
|
-
|
|
53
|
+
const filePath = path.resolve(dir, file);
|
|
54
|
+
fs.rmSync(filePath, { recursive: true, force: true });
|
|
46
55
|
}
|
|
47
56
|
}
|
|
48
57
|
function copyDir(srcDir, destDir) {
|
|
@@ -51,166 +60,318 @@ function copyDir(srcDir, destDir) {
|
|
|
51
60
|
const srcFile = path.resolve(srcDir, file);
|
|
52
61
|
const destFile = path.resolve(destDir, file);
|
|
53
62
|
const stat = fs.statSync(srcFile);
|
|
54
|
-
if (stat.isDirectory())
|
|
63
|
+
if (stat.isDirectory()) {
|
|
55
64
|
copyDir(srcFile, destFile);
|
|
56
|
-
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
57
67
|
fs.copyFileSync(srcFile, destFile);
|
|
68
|
+
}
|
|
58
69
|
}
|
|
59
70
|
}
|
|
60
|
-
function
|
|
61
|
-
const name = isValidPackageName(targetDir) ? targetDir : toValidPackageName(targetDir);
|
|
71
|
+
async function generatePackageJson(targetDir, options) {
|
|
62
72
|
const pkg = {
|
|
63
|
-
name
|
|
64
|
-
|
|
73
|
+
name: isValidPackageName(targetDir)
|
|
74
|
+
? targetDir
|
|
75
|
+
: toValidPackageName(targetDir),
|
|
76
|
+
version: "0.0.0",
|
|
65
77
|
private: true,
|
|
66
|
-
type:
|
|
78
|
+
type: "module",
|
|
67
79
|
scripts: {
|
|
68
|
-
dev:
|
|
69
|
-
build:
|
|
70
|
-
preview:
|
|
71
|
-
test:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
lint:
|
|
75
|
-
format:
|
|
76
|
-
|
|
80
|
+
dev: "vite",
|
|
81
|
+
build: "vue-tsc && vite build",
|
|
82
|
+
preview: "vite preview",
|
|
83
|
+
test: "vitest",
|
|
84
|
+
"test:e2e": "playwright test",
|
|
85
|
+
"test:perf": "playwright test --config=playwright.config.perf.ts",
|
|
86
|
+
lint: "eslint . --ext .vue,.ts,.tsx --fix",
|
|
87
|
+
format: "prettier --write .",
|
|
88
|
+
"type-check": "vue-tsc --noEmit",
|
|
89
|
+
prepare: "husky install",
|
|
90
|
+
"lint-staged": "lint-staged",
|
|
91
|
+
},
|
|
92
|
+
dependencies: {
|
|
93
|
+
vue: "^3.4.0",
|
|
77
94
|
},
|
|
78
|
-
dependencies: { vue: '^3.4.0' },
|
|
79
95
|
devDependencies: {
|
|
80
|
-
|
|
81
|
-
typescript:
|
|
82
|
-
vite:
|
|
83
|
-
|
|
84
|
-
}
|
|
96
|
+
"@vitejs/plugin-vue": "^5.0.0",
|
|
97
|
+
typescript: "^5.3.0",
|
|
98
|
+
vite: "^5.0.0",
|
|
99
|
+
"vue-tsc": "^1.8.0",
|
|
100
|
+
},
|
|
85
101
|
};
|
|
86
|
-
if (
|
|
87
|
-
pkg.dependencies[
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
pkg.devDependencies[
|
|
110
|
-
}
|
|
111
|
-
if (features
|
|
112
|
-
pkg.devDependencies[
|
|
113
|
-
}
|
|
114
|
-
if (features
|
|
115
|
-
pkg.devDependencies[
|
|
102
|
+
if (options.needsRouter) {
|
|
103
|
+
pkg.dependencies["vue-router"] = "^4.2.0";
|
|
104
|
+
}
|
|
105
|
+
if (options.needsPinia) {
|
|
106
|
+
pkg.dependencies["pinia"] = "^2.1.0";
|
|
107
|
+
}
|
|
108
|
+
if (options.features?.includes("lint")) {
|
|
109
|
+
pkg.devDependencies["@typescript-eslint/eslint-plugin"] = "^6.21.0";
|
|
110
|
+
pkg.devDependencies["@typescript-eslint/parser"] = "^6.21.0";
|
|
111
|
+
pkg.devDependencies["@vue/eslint-config-prettier"] = "^9.0.0";
|
|
112
|
+
pkg.devDependencies["@vue/eslint-config-typescript"] = "^12.0.0";
|
|
113
|
+
pkg.devDependencies["eslint"] = "^8.57.0";
|
|
114
|
+
pkg.devDependencies["eslint-plugin-vue"] = "^9.21.0";
|
|
115
|
+
pkg.devDependencies["prettier"] = "^3.2.0";
|
|
116
|
+
// Git hooks
|
|
117
|
+
pkg.devDependencies["husky"] = "^9.0.0";
|
|
118
|
+
pkg.devDependencies["lint-staged"] = "^15.2.0";
|
|
119
|
+
pkg.devDependencies["@commitlint/cli"] = "^19.0.0";
|
|
120
|
+
pkg.devDependencies["@commitlint/config-conventional"] = "^19.0.0";
|
|
121
|
+
}
|
|
122
|
+
if (options.features?.includes("vitest")) {
|
|
123
|
+
pkg.devDependencies["@vue/test-utils"] = "^2.4.0";
|
|
124
|
+
pkg.devDependencies["happy-dom"] = "^13.0.0";
|
|
125
|
+
pkg.devDependencies["vitest"] = "^1.2.0";
|
|
126
|
+
}
|
|
127
|
+
if (options.features?.includes("playwright")) {
|
|
128
|
+
pkg.devDependencies["@playwright/test"] = "^1.41.0";
|
|
129
|
+
}
|
|
130
|
+
if (options.features?.includes("mcp")) {
|
|
131
|
+
pkg.devDependencies["vue3-enterprise-mcp"] = "^1.0.0";
|
|
132
|
+
}
|
|
133
|
+
if (options.features?.includes("ci")) {
|
|
134
|
+
pkg.devDependencies["vue3-enterprise-ci"] = "^1.0.0";
|
|
116
135
|
}
|
|
117
136
|
return pkg;
|
|
118
137
|
}
|
|
119
138
|
async function main() {
|
|
120
|
-
console.log(`\n${cyan(
|
|
139
|
+
console.log(`\n${cyan("Vue3 Enterprise Toolchain")}\n`);
|
|
121
140
|
if (argv.help) {
|
|
122
141
|
printHelp();
|
|
123
142
|
return;
|
|
124
143
|
}
|
|
125
144
|
let targetDir = argv._[0];
|
|
126
|
-
const
|
|
145
|
+
const promptResult = await prompts([
|
|
127
146
|
{
|
|
128
|
-
type: targetDir ? null :
|
|
129
|
-
name:
|
|
130
|
-
message:
|
|
131
|
-
initial:
|
|
132
|
-
onState: (
|
|
147
|
+
type: targetDir ? null : "text",
|
|
148
|
+
name: "projectName",
|
|
149
|
+
message: "项目名称:",
|
|
150
|
+
initial: "vue3-enterprise-project",
|
|
151
|
+
onState: (state) => {
|
|
152
|
+
targetDir = String(state.value).trim() || "vue3-enterprise-project";
|
|
153
|
+
},
|
|
133
154
|
},
|
|
134
155
|
{
|
|
135
|
-
type:
|
|
156
|
+
type: "select",
|
|
157
|
+
name: "template",
|
|
158
|
+
message: "选择模板:",
|
|
136
159
|
choices: [
|
|
137
|
-
{ title:
|
|
138
|
-
{ title:
|
|
139
|
-
{
|
|
140
|
-
|
|
160
|
+
{ title: "Vue3 + TypeScript + Vite (推荐)", value: "vue3-ts" },
|
|
161
|
+
{ title: "Vue3 + TypeScript + Vite + Pinia", value: "vue3-ts-pinia" },
|
|
162
|
+
{
|
|
163
|
+
title: "Vue3 + TypeScript + Vite + Pinia + Vue Router",
|
|
164
|
+
value: "vue3-ts-full",
|
|
165
|
+
},
|
|
166
|
+
],
|
|
141
167
|
},
|
|
142
168
|
{
|
|
143
|
-
type:
|
|
169
|
+
type: "multiselect",
|
|
170
|
+
name: "features",
|
|
171
|
+
message: "选择功能 (空格选择,回车确认):",
|
|
144
172
|
choices: [
|
|
145
|
-
{ title:
|
|
146
|
-
{ title:
|
|
147
|
-
{
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
173
|
+
{ title: "ESLint + Prettier", value: "lint", selected: true },
|
|
174
|
+
{ title: "Vitest (单元测试)", value: "vitest", selected: true },
|
|
175
|
+
{
|
|
176
|
+
title: "Playwright (E2E 测试)",
|
|
177
|
+
value: "playwright",
|
|
178
|
+
selected: true,
|
|
179
|
+
},
|
|
180
|
+
{ title: "Vue3 Enterprise MCP", value: "mcp", selected: true },
|
|
181
|
+
{ title: "CI/CD 工作流", value: "ci", selected: true },
|
|
182
|
+
{ title: "性能基准测试", value: "perf", selected: true },
|
|
183
|
+
],
|
|
152
184
|
},
|
|
153
185
|
{
|
|
154
|
-
type:
|
|
186
|
+
type: "confirm",
|
|
187
|
+
name: "needsTypeScript",
|
|
188
|
+
message: "使用 TypeScript?",
|
|
189
|
+
initial: true,
|
|
155
190
|
},
|
|
156
191
|
{
|
|
157
|
-
type:
|
|
192
|
+
type: "confirm",
|
|
193
|
+
name: "needsRouter",
|
|
194
|
+
message: "添加 Vue Router?",
|
|
195
|
+
initial: true,
|
|
158
196
|
},
|
|
159
197
|
{
|
|
160
|
-
type:
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
initial:
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
198
|
+
type: "confirm",
|
|
199
|
+
name: "needsPinia",
|
|
200
|
+
message: "添加 Pinia (状态管理)?",
|
|
201
|
+
initial: true,
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
type: "confirm",
|
|
205
|
+
name: "overwrite",
|
|
206
|
+
message: targetDir &&
|
|
207
|
+
fs.existsSync(targetDir) &&
|
|
208
|
+
fs.readdirSync(targetDir).length > 0
|
|
209
|
+
? `目录 "${targetDir}" 已存在且不为空。是否覆盖?`
|
|
210
|
+
: "",
|
|
211
|
+
initial: false,
|
|
212
|
+
},
|
|
213
|
+
], {
|
|
214
|
+
onCancel: () => {
|
|
215
|
+
console.log(red("✖ 操作已取消"));
|
|
216
|
+
process.exit(1);
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
if (promptResult.overwrite === false) {
|
|
220
|
+
console.log(red("✖ 操作已取消"));
|
|
168
221
|
process.exit(1);
|
|
169
222
|
}
|
|
170
223
|
const root = path.join(cwd, targetDir);
|
|
171
224
|
if (fs.existsSync(root)) {
|
|
172
|
-
if (argv.force ||
|
|
225
|
+
if (argv.force || promptResult.overwrite) {
|
|
173
226
|
emptyDir(root);
|
|
227
|
+
}
|
|
174
228
|
else {
|
|
175
|
-
console.log(red(`✖
|
|
229
|
+
console.log(red(`✖ 目录 "${targetDir}" 已存在`));
|
|
230
|
+
console.log(yellow("提示: 使用 --force 强制覆盖"));
|
|
176
231
|
process.exit(1);
|
|
177
232
|
}
|
|
178
233
|
}
|
|
179
|
-
else
|
|
234
|
+
else {
|
|
180
235
|
fs.mkdirSync(root, { recursive: true });
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
236
|
+
}
|
|
237
|
+
console.log(`\n${cyan("正在创建项目...")}\n`);
|
|
238
|
+
const templateDir = path.resolve(__dirname, "../template");
|
|
239
|
+
copyDir(templateDir, root);
|
|
240
|
+
const pkg = await generatePackageJson(targetDir, {
|
|
241
|
+
features: promptResult.features || [],
|
|
242
|
+
needsRouter: promptResult.needsRouter,
|
|
243
|
+
needsPinia: promptResult.needsPinia,
|
|
244
|
+
});
|
|
245
|
+
fs.writeFileSync(path.join(root, "package.json"), JSON.stringify(pkg, null, 2));
|
|
246
|
+
const featureDescriptions = {
|
|
247
|
+
lint: "- 🧹 ESLint + Prettier 代码规范 + Git Hooks 自动检查",
|
|
248
|
+
vitest: "- 🧪 Vitest 单元测试",
|
|
249
|
+
playwright: "- 🎭 Playwright E2E 测试",
|
|
250
|
+
mcp: "- 🔍 Vue3 Enterprise MCP 代码审查",
|
|
251
|
+
ci: "- ⚡ CI/CD 自动化",
|
|
252
|
+
perf: "- 📊 性能基准测试",
|
|
192
253
|
};
|
|
193
254
|
const readme = `# ${pkg.name}
|
|
194
255
|
|
|
195
|
-
|
|
256
|
+
使用 Vue3 Enterprise Toolchain 创建的项目
|
|
257
|
+
|
|
258
|
+
## 功能特性
|
|
196
259
|
|
|
197
|
-
|
|
198
|
-
|
|
260
|
+
${(promptResult.features || [])
|
|
261
|
+
.map((f) => featureDescriptions[f] || "")
|
|
262
|
+
.filter(Boolean)
|
|
263
|
+
.join("\n")}
|
|
264
|
+
|
|
265
|
+
## 快速开始
|
|
199
266
|
|
|
200
|
-
## Quick Start
|
|
201
267
|
\`\`\`bash
|
|
268
|
+
# 安装依赖
|
|
202
269
|
npm install
|
|
270
|
+
|
|
271
|
+
# 启动开发服务器
|
|
203
272
|
npm run dev
|
|
273
|
+
|
|
274
|
+
# 运行测试
|
|
275
|
+
npm test
|
|
276
|
+
|
|
277
|
+
# 构建生产版本
|
|
278
|
+
npm run build
|
|
204
279
|
\`\`\`
|
|
205
280
|
|
|
206
|
-
##
|
|
207
|
-
|
|
208
|
-
- \`npm run
|
|
209
|
-
- \`npm
|
|
281
|
+
## 可用脚本
|
|
282
|
+
|
|
283
|
+
- \`npm run dev\` - 启动开发服务器
|
|
284
|
+
- \`npm run build\` - 构建生产版本
|
|
285
|
+
- \`npm run preview\` - 预览生产版本
|
|
286
|
+
- \`npm test\` - 运行单元测试
|
|
287
|
+
- \`npm run test:e2e\` - 运行 E2E 测试
|
|
288
|
+
- \`npm run test:perf\` - 运行性能测试
|
|
289
|
+
- \`npm run lint\` - 运行 ESLint
|
|
290
|
+
- \`npm run format\` - 运行 Prettier
|
|
291
|
+
|
|
292
|
+
## 文档
|
|
293
|
+
|
|
294
|
+
- [Vue3 Enterprise MCP 使用指南](https://github.com/your-org/vue3-enterprise-toolchain/blob/main/docs/mcp.md)
|
|
295
|
+
- [CI 集成指南](https://github.com/your-org/vue3-enterprise-toolchain/blob/main/docs/ci.md)
|
|
210
296
|
`;
|
|
211
|
-
fs.writeFileSync(path.join(root,
|
|
212
|
-
const gitignore =
|
|
213
|
-
|
|
214
|
-
|
|
297
|
+
fs.writeFileSync(path.join(root, "README.md"), readme);
|
|
298
|
+
const gitignore = `# Logs
|
|
299
|
+
logs
|
|
300
|
+
*.log
|
|
301
|
+
npm-debug.log*
|
|
302
|
+
yarn-debug.log*
|
|
303
|
+
yarn-error.log*
|
|
304
|
+
pnpm-debug.log*
|
|
305
|
+
lerna-debug.log*
|
|
306
|
+
|
|
307
|
+
node_modules
|
|
308
|
+
.DS_Store
|
|
309
|
+
dist
|
|
310
|
+
dist-ssr
|
|
311
|
+
*.local
|
|
312
|
+
|
|
313
|
+
# Editor directories and files
|
|
314
|
+
.vscode/*
|
|
315
|
+
!.vscode/extensions.json
|
|
316
|
+
.idea
|
|
317
|
+
*.suo
|
|
318
|
+
*.ntvs*
|
|
319
|
+
*.njsproj
|
|
320
|
+
*.sln
|
|
321
|
+
*.sw?
|
|
322
|
+
|
|
323
|
+
# Testing
|
|
324
|
+
coverage
|
|
325
|
+
|
|
326
|
+
# Playwright
|
|
327
|
+
test-results/
|
|
328
|
+
playwright-report/
|
|
329
|
+
playwright/.cache/
|
|
330
|
+
|
|
331
|
+
# Performance baseline
|
|
332
|
+
.perf-baseline.json
|
|
333
|
+
`;
|
|
334
|
+
fs.writeFileSync(path.join(root, ".gitignore"), gitignore);
|
|
335
|
+
// Initialize git and husky if lint feature is enabled
|
|
336
|
+
if (promptResult.features?.includes("lint")) {
|
|
337
|
+
try {
|
|
338
|
+
execSync("git init", { cwd: root, stdio: "ignore" });
|
|
339
|
+
execSync("npm run prepare", { cwd: root, stdio: "ignore" });
|
|
340
|
+
}
|
|
341
|
+
catch (e) {
|
|
342
|
+
// Git may not be installed
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
console.log(`${green("✔")} 项目创建成功!\n`);
|
|
346
|
+
console.log(` cd ${cyan(targetDir)}`);
|
|
347
|
+
console.log(` npm install`);
|
|
348
|
+
console.log(` npm run dev\n`);
|
|
349
|
+
// Git hooks info
|
|
350
|
+
if (promptResult.features?.includes("lint")) {
|
|
351
|
+
console.log(`${cyan("Git Hooks 配置:")}`);
|
|
352
|
+
console.log(` • pre-commit: 自动检查格式和类型`);
|
|
353
|
+
console.log(` • commit-msg: 验证提交信息格式`);
|
|
354
|
+
console.log(` 提交时自动运行检查,无需手动触发\n`);
|
|
355
|
+
}
|
|
356
|
+
if (promptResult.features?.includes("mcp")) {
|
|
357
|
+
console.log(`${cyan("MCP Server 配置:")}`);
|
|
358
|
+
console.log(` 在 Claude Desktop 的 claude_desktop_config.json 中添加:\n`);
|
|
359
|
+
console.log(` {
|
|
360
|
+
"mcpServers": {
|
|
361
|
+
"vue3-enterprise": {
|
|
362
|
+
"command": "npx",
|
|
363
|
+
"args": ["-y", "vue3-enterprise-mcp", "${targetDir}"]
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}\n`);
|
|
367
|
+
}
|
|
368
|
+
if (promptResult.features?.includes("ci")) {
|
|
369
|
+
console.log(`${cyan("CI 配置:")}`);
|
|
370
|
+
console.log(` 已配置 GitHub Actions 工作流`);
|
|
371
|
+
console.log(` 提交代码后会自动运行测试和性能检查\n`);
|
|
372
|
+
}
|
|
215
373
|
}
|
|
216
|
-
main().catch((
|
|
374
|
+
main().catch((err) => {
|
|
375
|
+
console.error(err);
|
|
376
|
+
process.exit(1);
|
|
377
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-vue3-enterprise",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.21",
|
|
4
4
|
"description": "Vue3 + TypeScript + Vite 企业级项目脚手架",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -13,9 +13,7 @@
|
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "tsc",
|
|
15
15
|
"dev": "tsc --watch",
|
|
16
|
-
"prepublishOnly": "npm run build"
|
|
17
|
-
"test": "node ./dist/index.js --help",
|
|
18
|
-
"test:create": "node ./dist/index.js test-project --force"
|
|
16
|
+
"prepublishOnly": "npm run build"
|
|
19
17
|
},
|
|
20
18
|
"dependencies": {
|
|
21
19
|
"kolorist": "^1.8.0",
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
. "$(dirname -- "$0")/_/husky.sh"
|
|
3
|
+
|
|
4
|
+
# ============================================
|
|
5
|
+
# 📝 Commit Message Validation
|
|
6
|
+
# Uses Conventional Commits format
|
|
7
|
+
# ============================================
|
|
8
|
+
|
|
9
|
+
echo ""
|
|
10
|
+
echo "📝 Validating commit message..."
|
|
11
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
12
|
+
|
|
13
|
+
# Run commitlint
|
|
14
|
+
if ! npx commitlint --edit ${1}; then
|
|
15
|
+
echo ""
|
|
16
|
+
echo "❌ Commit message validation FAILED"
|
|
17
|
+
echo ""
|
|
18
|
+
echo "📖 Correct format:"
|
|
19
|
+
echo " <type>(<scope>): <subject>"
|
|
20
|
+
echo ""
|
|
21
|
+
echo " Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert"
|
|
22
|
+
echo ""
|
|
23
|
+
echo " Examples:"
|
|
24
|
+
echo " • feat: add user login button"
|
|
25
|
+
echo " • fix: resolve memory leak in component"
|
|
26
|
+
echo " • docs: update API documentation"
|
|
27
|
+
echo ""
|
|
28
|
+
echo " Run 'npm run commit' for interactive commit"
|
|
29
|
+
echo ""
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
echo ""
|
|
34
|
+
echo "✅ Commit message validated!"
|
|
35
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
. "$(dirname -- "$0")/_/husky.sh"
|
|
3
|
+
|
|
4
|
+
# ============================================
|
|
5
|
+
# 🧹 Pre-commit Checks
|
|
6
|
+
# - Code formatting (Prettier)
|
|
7
|
+
# - Type checking (vue-tsc)
|
|
8
|
+
# - Linting (ESLint)
|
|
9
|
+
# ============================================
|
|
10
|
+
|
|
11
|
+
echo ""
|
|
12
|
+
echo "🔍 Running pre-commit checks..."
|
|
13
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
14
|
+
|
|
15
|
+
# Run lint-staged
|
|
16
|
+
if ! npx lint-staged; then
|
|
17
|
+
echo ""
|
|
18
|
+
echo "❌ Pre-commit checks FAILED"
|
|
19
|
+
echo ""
|
|
20
|
+
echo "📖 Fix suggestions:"
|
|
21
|
+
echo " • Run 'npm run format' to fix formatting"
|
|
22
|
+
echo " • Run 'npm run lint' to fix linting errors"
|
|
23
|
+
echo " • Fix TypeScript errors manually"
|
|
24
|
+
echo ""
|
|
25
|
+
exit 1
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
echo ""
|
|
29
|
+
echo "✅ Pre-commit checks passed!"
|
|
30
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
extends: ['@commitlint/config-conventional'],
|
|
3
|
+
rules: {
|
|
4
|
+
// Type envelope: build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test
|
|
5
|
+
'type-enum': [
|
|
6
|
+
2,
|
|
7
|
+
'always',
|
|
8
|
+
[
|
|
9
|
+
'feat', // New feature
|
|
10
|
+
'fix', // Bug fix
|
|
11
|
+
'docs', // Documentation only changes
|
|
12
|
+
'style', // Changes that do not affect the meaning of the code (formatting)
|
|
13
|
+
'refactor', // Code change that neither fixes a bug nor adds a feature
|
|
14
|
+
'perf', // Performance improvement
|
|
15
|
+
'test', // Adding or correcting tests
|
|
16
|
+
'build', // Changes to build system or dependencies
|
|
17
|
+
'ci', // Changes to CI configuration
|
|
18
|
+
'chore', // Other changes that don't modify src or test files
|
|
19
|
+
'revert', // Reverts a previous commit
|
|
20
|
+
],
|
|
21
|
+
],
|
|
22
|
+
'type-case': [2, 'always', 'lower-case'],
|
|
23
|
+
'type-empty': [2, 'never'],
|
|
24
|
+
'subject-empty': [2, 'never'],
|
|
25
|
+
'subject-full-stop': [2, 'never', '.'],
|
|
26
|
+
'header-max-length': [2, 'always', 100],
|
|
27
|
+
},
|
|
28
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
// TypeScript and Vue files - check types
|
|
3
|
+
'*.ts': ['vue-tsc --noEmit', 'eslint --fix'],
|
|
4
|
+
'*.tsx': ['vue-tsc --noEmit', 'eslint --fix'],
|
|
5
|
+
'*.vue': ['vue-tsc --noEmit', 'eslint --fix'],
|
|
6
|
+
// Format all staged files
|
|
7
|
+
'**/*': ['prettier --write --ignore-unknown'],
|
|
8
|
+
}
|