@jackie_qian/create-vue-app 1.0.6 → 1.0.7
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/cli.js +187 -166
- package/dist/scaffold.js +9 -2
- package/dist/templates/index.js +1 -0
- package/dist/templates/renderMainJs.js +1 -0
- package/dist/templates/renderProjectStructure.js +81 -0
- package/dist/utils/util.js +27 -9
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -32,6 +32,7 @@ import {
|
|
|
32
32
|
renderEnv,
|
|
33
33
|
renderHomeView,
|
|
34
34
|
renderPagesIndex,
|
|
35
|
+
renderProjectStructureFiles,
|
|
35
36
|
renderRouter,
|
|
36
37
|
renderStore,
|
|
37
38
|
renderUnoConfig,
|
|
@@ -139,24 +140,27 @@ export async function main() {
|
|
|
139
140
|
if (features.has("router")) features.add("pages");
|
|
140
141
|
features.add("autoImport");
|
|
141
142
|
features.add("components");
|
|
142
|
-
packageManager = await select({
|
|
143
|
-
message:
|
|
144
|
-
"Which package manager will you use? (Vue 3.6 beta requires version overrides that differ per package manager)",
|
|
145
|
-
options: [...PACKAGE_MANAGER_OPTIONS],
|
|
146
|
-
initialValue: "pnpm",
|
|
147
|
-
});
|
|
148
|
-
if (isCancel(packageManager)) exitWithCancel();
|
|
149
143
|
const installDepsRaw = await confirm({
|
|
150
|
-
message:
|
|
144
|
+
message: "生成后是否自动安装依赖?",
|
|
151
145
|
initialValue: true,
|
|
152
146
|
});
|
|
153
147
|
if (isCancel(installDepsRaw)) exitWithCancel();
|
|
154
148
|
installDeps = Boolean(installDepsRaw);
|
|
149
|
+
if (installDeps) {
|
|
150
|
+
packageManager = await select({
|
|
151
|
+
message: "您将使用哪个包管理器?",
|
|
152
|
+
options: [...PACKAGE_MANAGER_OPTIONS],
|
|
153
|
+
initialValue: "pnpm",
|
|
154
|
+
});
|
|
155
|
+
if (isCancel(packageManager)) exitWithCancel();
|
|
156
|
+
} else {
|
|
157
|
+
packageManager = "pnpm";
|
|
158
|
+
}
|
|
155
159
|
}
|
|
156
160
|
const cwd = process.cwd();
|
|
157
161
|
const targetDir = path.resolve(cwd, projectName);
|
|
158
162
|
const s = spinner();
|
|
159
|
-
s.start("
|
|
163
|
+
s.start("生成基础项目中");
|
|
160
164
|
try {
|
|
161
165
|
await ensureEmptyDir(targetDir);
|
|
162
166
|
const flags = ["--bare", "--force"];
|
|
@@ -165,13 +169,110 @@ export async function main() {
|
|
|
165
169
|
if (features.has("pinia")) flags.push("--pinia");
|
|
166
170
|
if (flags.length === 2) flags.push("--default");
|
|
167
171
|
runCreateVue([...flags, projectName], cwd);
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
172
|
+
if (language === "js") {
|
|
173
|
+
await applyExampleTemplateJs(targetDir, projectName, features);
|
|
174
|
+
await writeFileEnsureDir(
|
|
175
|
+
path.join(targetDir, ".vscode/settings.json"),
|
|
176
|
+
renderVsCodeSettings(),
|
|
177
|
+
);
|
|
178
|
+
await writeFileEnsureDir(
|
|
179
|
+
path.join(targetDir, ".vscode/extensions.json"),
|
|
180
|
+
renderVsCodeExtensions(language, features),
|
|
181
|
+
);
|
|
182
|
+
await writeEslintConfig(targetDir, language, features);
|
|
183
|
+
await writeStylelintConfig(targetDir, features);
|
|
184
|
+
const baseFiles = renderProjectStructureFiles("js");
|
|
185
|
+
for (const f of baseFiles)
|
|
186
|
+
await writeFileEnsureDir(path.join(targetDir, f.fileName), f.content);
|
|
187
|
+
if (installDeps) {
|
|
188
|
+
const s2 = spinner();
|
|
189
|
+
s2.start("安装依赖");
|
|
190
|
+
try {
|
|
191
|
+
const { cmd, args } = installCommand(packageManager);
|
|
192
|
+
run(cmd, args, targetDir);
|
|
193
|
+
s2.stop("依赖已安装");
|
|
194
|
+
} catch (e) {
|
|
195
|
+
s2.stop("依赖安装失败");
|
|
196
|
+
throw e;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
s.stop("基础项目已生成");
|
|
200
|
+
const nextSteps = installDeps
|
|
201
|
+
? `\n cd ${projectName}\n ${devCommand(packageManager)}`
|
|
202
|
+
: `\n cd ${projectName}\n\n pnpm install\n pnpm dev\n\n 或\n\n npm install\n npm run dev`;
|
|
203
|
+
outro(
|
|
204
|
+
`${pc.green("完成")}:${pc.cyan(projectName)}\n\n${pc.dim("下一步:")}${nextSteps}`,
|
|
205
|
+
);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
const projectPkgPath = path.join(targetDir, "package.json");
|
|
209
|
+
const pkg = await loadPackageJson(projectPkgPath);
|
|
210
|
+
pkg.name = pkg.name || projectName;
|
|
211
|
+
if (features.has("router"))
|
|
212
|
+
addDep(pkg.dependencies, "vue-router", "^4.5.1");
|
|
213
|
+
if (features.has("pinia")) addDep(pkg.dependencies, "pinia", "^3.0.3");
|
|
214
|
+
if (features.has("piniaPersist"))
|
|
215
|
+
addDep(pkg.dependencies, "pinia-plugin-persistedstate", "^4.2.0");
|
|
216
|
+
if (features.has("vant")) addDep(pkg.dependencies, "vant", "^4.9.22");
|
|
217
|
+
if (features.has("elementPlus"))
|
|
218
|
+
addDep(pkg.dependencies, "element-plus", "^2.7.6");
|
|
219
|
+
if (features.has("pages"))
|
|
220
|
+
addDep(pkg.devDependencies, "vite-plugin-pages", "^0.33.0");
|
|
221
|
+
if (features.has("autoImport"))
|
|
222
|
+
addDep(pkg.devDependencies, "unplugin-auto-import", "^0.19.0");
|
|
223
|
+
if (features.has("components"))
|
|
224
|
+
addDep(pkg.devDependencies, "unplugin-vue-components", "^0.28.0");
|
|
225
|
+
if (features.has("vant"))
|
|
226
|
+
addDep(pkg.devDependencies, "@vant/auto-import-resolver", "^1.3.0");
|
|
227
|
+
if (features.has("unocss"))
|
|
228
|
+
addDep(pkg.devDependencies, "unocss", "^0.64.0");
|
|
229
|
+
if (features.has("eslintAntfu")) {
|
|
230
|
+
addDep(pkg.devDependencies, "eslint", "^9.0.0");
|
|
231
|
+
addDep(pkg.devDependencies, "@antfu/eslint-config", "^4.0.0");
|
|
232
|
+
}
|
|
233
|
+
if (features.has("stylelint")) {
|
|
234
|
+
addDep(pkg.devDependencies, "stylelint", "^16.0.0");
|
|
235
|
+
addDep(pkg.devDependencies, "@stylistic/stylelint-config", "^3.0.0");
|
|
236
|
+
addDep(pkg.devDependencies, "stylelint-config-recess-order", "^6.0.0");
|
|
237
|
+
addDep(pkg.devDependencies, "stylelint-config-standard-scss", "^14.0.0");
|
|
238
|
+
addDep(pkg.devDependencies, "stylelint-config-standard-vue", "^1.0.0");
|
|
239
|
+
addDep(pkg.devDependencies, "stylelint-scss", "^6.0.0");
|
|
240
|
+
}
|
|
241
|
+
if (features.has("gitHooks")) {
|
|
242
|
+
addDep(pkg.devDependencies, "simple-git-hooks", "^2.11.1");
|
|
243
|
+
addDep(pkg.devDependencies, "lint-staged", "^15.2.0");
|
|
244
|
+
}
|
|
245
|
+
if (features.has("sassEmbedded"))
|
|
246
|
+
addDep(pkg.devDependencies, "sass-embedded", "^1.77.0");
|
|
247
|
+
if (features.has("eslintAntfu") && features.has("stylelint")) {
|
|
248
|
+
addDep(pkg.devDependencies, "npm-run-all2", "^7.0.2");
|
|
249
|
+
pkg.scripts.lint = "npm-run-all -s lint:eslint lint:stylelint";
|
|
250
|
+
pkg.scripts["lint:eslint"] = "eslint --fix";
|
|
251
|
+
pkg.scripts["lint:stylelint"] =
|
|
252
|
+
'stylelint "src/**/*.{css,scss,vue}" --fix';
|
|
253
|
+
} else if (features.has("eslintAntfu")) {
|
|
254
|
+
pkg.scripts.lint = "eslint";
|
|
255
|
+
pkg.scripts["lint:fix"] = "eslint --fix";
|
|
256
|
+
} else if (features.has("stylelint")) {
|
|
257
|
+
pkg.scripts.lint = "stylelint";
|
|
258
|
+
pkg.scripts["lint:stylelint"] =
|
|
259
|
+
'stylelint "src/**/*.{css,scss,vue}" --fix';
|
|
260
|
+
}
|
|
261
|
+
if (features.has("gitHooks")) {
|
|
262
|
+
pkg.scripts.prepare = "simple-git-hooks";
|
|
263
|
+
pkg["simple-git-hooks"] = {
|
|
264
|
+
"pre-commit": "pnpm lint-staged",
|
|
265
|
+
preserveUnused: true,
|
|
266
|
+
};
|
|
267
|
+
pkg["lint-staged"] = { "*.{js,ts,vue}": "pnpm lint" };
|
|
268
|
+
}
|
|
269
|
+
await finalizePackageJson(pkg, targetDir);
|
|
270
|
+
await writePackageJson(projectPkgPath, pkg);
|
|
271
|
+
const viteConfigPath = path.join(targetDir, "vite.config.ts");
|
|
272
|
+
await writeFileEnsureDir(
|
|
273
|
+
viteConfigPath,
|
|
274
|
+
renderViteConfig(language, features),
|
|
275
|
+
);
|
|
175
276
|
await writeFileEnsureDir(
|
|
176
277
|
path.join(targetDir, ".vscode/settings.json"),
|
|
177
278
|
renderVsCodeSettings(),
|
|
@@ -180,8 +281,70 @@ export async function main() {
|
|
|
180
281
|
path.join(targetDir, ".vscode/extensions.json"),
|
|
181
282
|
renderVsCodeExtensions(language, features),
|
|
182
283
|
);
|
|
284
|
+
await writeFileEnsureDir(
|
|
285
|
+
path.join(targetDir, ".editorconfig"),
|
|
286
|
+
renderEditorConfig(),
|
|
287
|
+
);
|
|
288
|
+
await writeFileEnsureDir(
|
|
289
|
+
path.join(targetDir, ".env.development"),
|
|
290
|
+
renderEnv(projectName),
|
|
291
|
+
);
|
|
292
|
+
await writeFileEnsureDir(
|
|
293
|
+
path.join(targetDir, ".env.production"),
|
|
294
|
+
renderEnv(projectName),
|
|
295
|
+
);
|
|
296
|
+
await patchTsconfigApp(targetDir);
|
|
297
|
+
if (features.has("unocss")) {
|
|
298
|
+
const unoPath = path.join(targetDir, "uno.config.ts");
|
|
299
|
+
await writeFileEnsureDir(unoPath, renderUnoConfig(language));
|
|
300
|
+
}
|
|
301
|
+
const mainPath = path.join(targetDir, "src/main.ts");
|
|
302
|
+
const appPath = path.join(targetDir, "src/App.vue");
|
|
303
|
+
if (features.has("router")) {
|
|
304
|
+
const router = renderRouter(language, features.has("pages"));
|
|
305
|
+
await writeFileEnsureDir(
|
|
306
|
+
path.join(targetDir, router.fileName),
|
|
307
|
+
router.content,
|
|
308
|
+
);
|
|
309
|
+
await writeFileEnsureDir(appPath, renderAppWithRouter());
|
|
310
|
+
if (features.has("pages")) {
|
|
311
|
+
const pagesDir = "src/pages";
|
|
312
|
+
await writeFileEnsureDir(
|
|
313
|
+
path.join(targetDir, pagesDir, "index.vue"),
|
|
314
|
+
renderPagesIndex(),
|
|
315
|
+
);
|
|
316
|
+
await updateTsconfigTypes(targetDir, ["vite-plugin-pages/client"]);
|
|
317
|
+
} else {
|
|
318
|
+
await writeFileEnsureDir(
|
|
319
|
+
path.join(targetDir, "src/views/HomeView.vue"),
|
|
320
|
+
renderHomeView(),
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
if (features.has("pinia")) {
|
|
325
|
+
const store = renderStore(language, features.has("piniaPersist"));
|
|
326
|
+
await writeFileEnsureDir(
|
|
327
|
+
path.join(targetDir, store.fileName),
|
|
328
|
+
store.content,
|
|
329
|
+
);
|
|
330
|
+
await ensureCounterStoreInModules(targetDir, language);
|
|
331
|
+
}
|
|
332
|
+
if (await pathExists(mainPath)) {
|
|
333
|
+
const mainRaw = await readTextFile(mainPath);
|
|
334
|
+
const patched = patchMain(mainRaw, {
|
|
335
|
+
useRouter: features.has("router"),
|
|
336
|
+
useStore: features.has("pinia"),
|
|
337
|
+
useVant: features.has("vant"),
|
|
338
|
+
useElementPlus: features.has("elementPlus"),
|
|
339
|
+
useUno: features.has("unocss"),
|
|
340
|
+
});
|
|
341
|
+
await writeTextFile(mainPath, patched);
|
|
342
|
+
}
|
|
183
343
|
await writeEslintConfig(targetDir, language, features);
|
|
184
344
|
await writeStylelintConfig(targetDir, features);
|
|
345
|
+
const baseFiles = renderProjectStructureFiles(language);
|
|
346
|
+
for (const f of baseFiles)
|
|
347
|
+
await writeFileEnsureDir(path.join(targetDir, f.fileName), f.content);
|
|
185
348
|
if (installDeps) {
|
|
186
349
|
const s2 = spinner();
|
|
187
350
|
s2.start("安装依赖");
|
|
@@ -194,157 +357,15 @@ export async function main() {
|
|
|
194
357
|
throw e;
|
|
195
358
|
}
|
|
196
359
|
}
|
|
360
|
+
s.stop("基础项目已生成");
|
|
361
|
+
const nextSteps = installDeps
|
|
362
|
+
? `\n cd ${projectName}\n ${devCommand(packageManager)}`
|
|
363
|
+
: `\n cd ${projectName}\n\n pnpm install\n pnpm dev\n\n 或\n\n npm install\n npm run dev`;
|
|
197
364
|
outro(
|
|
198
|
-
`${pc.green("完成")}:${pc.cyan(projectName)}\n\n${pc.dim("下一步:")}
|
|
199
|
-
);
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
const projectPkgPath = path.join(targetDir, "package.json");
|
|
203
|
-
const pkg = await loadPackageJson(projectPkgPath);
|
|
204
|
-
pkg.name = pkg.name || projectName;
|
|
205
|
-
if (features.has("router")) addDep(pkg.dependencies, "vue-router", "^4.5.1");
|
|
206
|
-
if (features.has("pinia")) addDep(pkg.dependencies, "pinia", "^3.0.3");
|
|
207
|
-
if (features.has("piniaPersist"))
|
|
208
|
-
addDep(pkg.dependencies, "pinia-plugin-persistedstate", "^4.2.0");
|
|
209
|
-
if (features.has("vant")) addDep(pkg.dependencies, "vant", "^4.9.22");
|
|
210
|
-
if (features.has("elementPlus"))
|
|
211
|
-
addDep(pkg.dependencies, "element-plus", "^2.7.6");
|
|
212
|
-
if (features.has("pages"))
|
|
213
|
-
addDep(pkg.devDependencies, "vite-plugin-pages", "^0.33.0");
|
|
214
|
-
if (features.has("autoImport"))
|
|
215
|
-
addDep(pkg.devDependencies, "unplugin-auto-import", "^0.19.0");
|
|
216
|
-
if (features.has("components"))
|
|
217
|
-
addDep(pkg.devDependencies, "unplugin-vue-components", "^0.28.0");
|
|
218
|
-
if (features.has("vant"))
|
|
219
|
-
addDep(pkg.devDependencies, "@vant/auto-import-resolver", "^1.3.0");
|
|
220
|
-
if (features.has("unocss")) addDep(pkg.devDependencies, "unocss", "^0.64.0");
|
|
221
|
-
if (features.has("eslintAntfu")) {
|
|
222
|
-
addDep(pkg.devDependencies, "eslint", "^9.0.0");
|
|
223
|
-
addDep(pkg.devDependencies, "@antfu/eslint-config", "^4.0.0");
|
|
224
|
-
}
|
|
225
|
-
if (features.has("stylelint")) {
|
|
226
|
-
addDep(pkg.devDependencies, "stylelint", "^16.0.0");
|
|
227
|
-
addDep(pkg.devDependencies, "@stylistic/stylelint-config", "^3.0.0");
|
|
228
|
-
addDep(pkg.devDependencies, "stylelint-config-recess-order", "^6.0.0");
|
|
229
|
-
addDep(pkg.devDependencies, "stylelint-config-standard-scss", "^14.0.0");
|
|
230
|
-
addDep(pkg.devDependencies, "stylelint-config-standard-vue", "^1.0.0");
|
|
231
|
-
addDep(pkg.devDependencies, "stylelint-scss", "^6.0.0");
|
|
232
|
-
}
|
|
233
|
-
if (features.has("gitHooks")) {
|
|
234
|
-
addDep(pkg.devDependencies, "simple-git-hooks", "^2.11.1");
|
|
235
|
-
addDep(pkg.devDependencies, "lint-staged", "^15.2.0");
|
|
236
|
-
}
|
|
237
|
-
if (features.has("sassEmbedded"))
|
|
238
|
-
addDep(pkg.devDependencies, "sass-embedded", "^1.77.0");
|
|
239
|
-
if (features.has("eslintAntfu") && features.has("stylelint")) {
|
|
240
|
-
addDep(pkg.devDependencies, "npm-run-all2", "^7.0.2");
|
|
241
|
-
pkg.scripts.lint = "npm-run-all -s lint:eslint lint:stylelint";
|
|
242
|
-
pkg.scripts["lint:eslint"] = "eslint --fix";
|
|
243
|
-
pkg.scripts["lint:stylelint"] = 'stylelint "src/**/*.{css,scss,vue}" --fix';
|
|
244
|
-
} else if (features.has("eslintAntfu")) {
|
|
245
|
-
pkg.scripts.lint = "eslint";
|
|
246
|
-
pkg.scripts["lint:fix"] = "eslint --fix";
|
|
247
|
-
} else if (features.has("stylelint")) {
|
|
248
|
-
pkg.scripts.lint = "stylelint";
|
|
249
|
-
pkg.scripts["lint:stylelint"] = 'stylelint "src/**/*.{css,scss,vue}" --fix';
|
|
250
|
-
}
|
|
251
|
-
if (features.has("gitHooks")) {
|
|
252
|
-
pkg.scripts.prepare = "simple-git-hooks";
|
|
253
|
-
pkg["simple-git-hooks"] = {
|
|
254
|
-
"pre-commit": "pnpm lint-staged",
|
|
255
|
-
preserveUnused: true,
|
|
256
|
-
};
|
|
257
|
-
pkg["lint-staged"] = { "*.{js,ts,vue}": "pnpm lint" };
|
|
258
|
-
}
|
|
259
|
-
await finalizePackageJson(pkg, targetDir);
|
|
260
|
-
await writePackageJson(projectPkgPath, pkg);
|
|
261
|
-
const viteConfigPath = path.join(targetDir, "vite.config.ts");
|
|
262
|
-
await writeFileEnsureDir(
|
|
263
|
-
viteConfigPath,
|
|
264
|
-
renderViteConfig(language, features),
|
|
265
|
-
);
|
|
266
|
-
await writeFileEnsureDir(
|
|
267
|
-
path.join(targetDir, ".vscode/settings.json"),
|
|
268
|
-
renderVsCodeSettings(),
|
|
269
|
-
);
|
|
270
|
-
await writeFileEnsureDir(
|
|
271
|
-
path.join(targetDir, ".vscode/extensions.json"),
|
|
272
|
-
renderVsCodeExtensions(language, features),
|
|
273
|
-
);
|
|
274
|
-
await writeFileEnsureDir(
|
|
275
|
-
path.join(targetDir, ".editorconfig"),
|
|
276
|
-
renderEditorConfig(),
|
|
277
|
-
);
|
|
278
|
-
await writeFileEnsureDir(
|
|
279
|
-
path.join(targetDir, ".env.development"),
|
|
280
|
-
renderEnv(projectName),
|
|
281
|
-
);
|
|
282
|
-
await writeFileEnsureDir(
|
|
283
|
-
path.join(targetDir, ".env.production"),
|
|
284
|
-
renderEnv(projectName),
|
|
285
|
-
);
|
|
286
|
-
await patchTsconfigApp(targetDir);
|
|
287
|
-
if (features.has("unocss")) {
|
|
288
|
-
const unoPath = path.join(targetDir, "uno.config.ts");
|
|
289
|
-
await writeFileEnsureDir(unoPath, renderUnoConfig(language));
|
|
290
|
-
}
|
|
291
|
-
const mainPath = path.join(targetDir, "src/main.ts");
|
|
292
|
-
const appPath = path.join(targetDir, "src/App.vue");
|
|
293
|
-
if (features.has("router")) {
|
|
294
|
-
const router = renderRouter(language, features.has("pages"));
|
|
295
|
-
await writeFileEnsureDir(
|
|
296
|
-
path.join(targetDir, router.fileName),
|
|
297
|
-
router.content,
|
|
365
|
+
`${pc.green("完成")}:${pc.cyan(projectName)}\n\n${pc.dim("下一步:")}${nextSteps}`,
|
|
298
366
|
);
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
await writeFileEnsureDir(
|
|
303
|
-
path.join(targetDir, pagesDir, "index.vue"),
|
|
304
|
-
renderPagesIndex(),
|
|
305
|
-
);
|
|
306
|
-
await updateTsconfigTypes(targetDir, ["vite-plugin-pages/client"]);
|
|
307
|
-
} else {
|
|
308
|
-
await writeFileEnsureDir(
|
|
309
|
-
path.join(targetDir, "src/views/HomeView.vue"),
|
|
310
|
-
renderHomeView(),
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
if (features.has("pinia")) {
|
|
315
|
-
const store = renderStore(language, features.has("piniaPersist"));
|
|
316
|
-
await writeFileEnsureDir(
|
|
317
|
-
path.join(targetDir, store.fileName),
|
|
318
|
-
store.content,
|
|
319
|
-
);
|
|
320
|
-
await ensureCounterStoreInModules(targetDir, language);
|
|
321
|
-
}
|
|
322
|
-
if (await pathExists(mainPath)) {
|
|
323
|
-
const mainRaw = await readTextFile(mainPath);
|
|
324
|
-
const patched = patchMain(mainRaw, {
|
|
325
|
-
useRouter: features.has("router"),
|
|
326
|
-
useStore: features.has("pinia"),
|
|
327
|
-
useVant: features.has("vant"),
|
|
328
|
-
useElementPlus: features.has("elementPlus"),
|
|
329
|
-
useUno: features.has("unocss"),
|
|
330
|
-
});
|
|
331
|
-
await writeTextFile(mainPath, patched);
|
|
332
|
-
}
|
|
333
|
-
await writeEslintConfig(targetDir, language, features);
|
|
334
|
-
await writeStylelintConfig(targetDir, features);
|
|
335
|
-
if (installDeps) {
|
|
336
|
-
const s2 = spinner();
|
|
337
|
-
s2.start("安装依赖");
|
|
338
|
-
try {
|
|
339
|
-
const { cmd, args } = installCommand(packageManager);
|
|
340
|
-
run(cmd, args, targetDir);
|
|
341
|
-
s2.stop("依赖已安装");
|
|
342
|
-
} catch (e) {
|
|
343
|
-
s2.stop("依赖安装失败");
|
|
344
|
-
throw e;
|
|
345
|
-
}
|
|
367
|
+
} catch (e) {
|
|
368
|
+
s.stop("生成失败");
|
|
369
|
+
throw e;
|
|
346
370
|
}
|
|
347
|
-
outro(
|
|
348
|
-
`${pc.green("完成")}:${pc.cyan(projectName)}\n\n${pc.dim("下一步:")}\n cd ${projectName}\n ${devCommand(packageManager)}`,
|
|
349
|
-
);
|
|
350
371
|
}
|
package/dist/scaffold.js
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
renderRouter,
|
|
19
19
|
renderStore,
|
|
20
20
|
renderStylelintConfig,
|
|
21
|
+
renderUnoConfig,
|
|
21
22
|
renderViteConfig,
|
|
22
23
|
} from "./templates/index.js";
|
|
23
24
|
export function getExampleTemplateDir() {
|
|
@@ -256,8 +257,14 @@ export async function applyExampleTemplateJs(targetDir, projectName, features) {
|
|
|
256
257
|
path.join(targetDir, "jsconfig.json"),
|
|
257
258
|
renderJsConfig(),
|
|
258
259
|
);
|
|
259
|
-
if (!features.has("unocss"))
|
|
260
|
+
if (!features.has("unocss")) {
|
|
260
261
|
await removePath(path.join(targetDir, "uno.config.js"));
|
|
262
|
+
} else {
|
|
263
|
+
await writeFileEnsureDir(
|
|
264
|
+
path.join(targetDir, "uno.config.js"),
|
|
265
|
+
renderUnoConfig("js"),
|
|
266
|
+
);
|
|
267
|
+
}
|
|
261
268
|
if (!features.has("router")) {
|
|
262
269
|
await removePath(path.join(targetDir, "src/router"));
|
|
263
270
|
await writeFileEnsureDir(
|
|
@@ -295,7 +302,7 @@ export async function applyExampleTemplateJs(targetDir, projectName, features) {
|
|
|
295
302
|
if (!features.has("components"))
|
|
296
303
|
await removePath(path.join(targetDir, "src/types/components.d.ts"));
|
|
297
304
|
if (!features.has("sassEmbedded"))
|
|
298
|
-
await removePath(path.join(targetDir, "src/assets/styles"));
|
|
305
|
+
await removePath(path.join(targetDir, "src/assets/styles/main.scss"));
|
|
299
306
|
}
|
|
300
307
|
export async function writeEslintConfig(targetDir, language, features) {
|
|
301
308
|
if (!features.has("eslintAntfu")) return;
|
package/dist/templates/index.js
CHANGED
|
@@ -10,6 +10,7 @@ export {
|
|
|
10
10
|
export { renderJsConfig } from "./renderJsConfig.js";
|
|
11
11
|
export { renderMainJs } from "./renderMainJs.js";
|
|
12
12
|
export { renderPagesIndex } from "./renderPagesIndex.js";
|
|
13
|
+
export { renderProjectStructureFiles } from "./renderProjectStructure.js";
|
|
13
14
|
export { renderRouter } from "./renderRouter.js";
|
|
14
15
|
export { renderStore } from "./renderStore.js";
|
|
15
16
|
export { renderStylelintConfig } from "./renderStylelintConfig.js";
|
|
@@ -5,6 +5,7 @@ export function renderMainJs(featureSet) {
|
|
|
5
5
|
lines.push(`import App from './App.vue'`);
|
|
6
6
|
if (featureSet.has("router")) lines.push(`import Router from './router'`);
|
|
7
7
|
if (featureSet.has("pinia")) lines.push(`import Pinia from './stores/index'`);
|
|
8
|
+
if (featureSet.has("unocss")) lines.push(`import 'virtual:uno.css'`);
|
|
8
9
|
if (featureSet.has("vant")) lines.push(`import 'vant/lib/index.css'`);
|
|
9
10
|
if (featureSet.has("elementPlus"))
|
|
10
11
|
lines.push(`import 'element-plus/dist/index.css'`);
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export function renderProjectStructureFiles(language) {
|
|
2
|
+
const ext = language === "ts" ? "ts" : "js";
|
|
3
|
+
const mainScss = `@use './reset.scss';
|
|
4
|
+
@use './variables.scss';
|
|
5
|
+
@use './mixins.scss';
|
|
6
|
+
@use './components.scss';
|
|
7
|
+
`;
|
|
8
|
+
const resetScss = `*,
|
|
9
|
+
*::before,
|
|
10
|
+
*::after {
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
html {
|
|
15
|
+
-webkit-text-size-adjust: 100%;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
html,
|
|
19
|
+
body,
|
|
20
|
+
#app {
|
|
21
|
+
height: 100%;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
body {
|
|
25
|
+
line-height: 1.5;
|
|
26
|
+
margin: 0;
|
|
27
|
+
color: var(--color-text);
|
|
28
|
+
background: var(--color-bg);
|
|
29
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', 'Liberation Sans', sans-serif;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
img,
|
|
33
|
+
svg,
|
|
34
|
+
video,
|
|
35
|
+
canvas,
|
|
36
|
+
audio,
|
|
37
|
+
iframe,
|
|
38
|
+
embed,
|
|
39
|
+
object {
|
|
40
|
+
display: block;
|
|
41
|
+
max-width: 100%;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
a {
|
|
45
|
+
color: inherit;
|
|
46
|
+
text-decoration: none;
|
|
47
|
+
}
|
|
48
|
+
`;
|
|
49
|
+
const variablesScss = `:root {
|
|
50
|
+
--color-text: #111827;
|
|
51
|
+
--color-bg: #ffffff;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@media (prefers-color-scheme: dark) {
|
|
55
|
+
:root {
|
|
56
|
+
--color-text: #f9fafb;
|
|
57
|
+
--color-bg: #0b1220;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
`;
|
|
61
|
+
const mixinsScss = `@mixin ellipsis($lines: 1) {
|
|
62
|
+
overflow: hidden;
|
|
63
|
+
display: -webkit-box;
|
|
64
|
+
-webkit-box-orient: vertical;
|
|
65
|
+
-webkit-line-clamp: $lines;
|
|
66
|
+
}
|
|
67
|
+
`;
|
|
68
|
+
const componentsScss = "// 此文件放置 UI 组件的样式";
|
|
69
|
+
return [
|
|
70
|
+
{ fileName: `src/apis/index.${ext}`, content: "" },
|
|
71
|
+
{ fileName: `src/constants/index.${ext}`, content: "" },
|
|
72
|
+
{ fileName: `src/hooks/index.${ext}`, content: "" },
|
|
73
|
+
{ fileName: "src/assets/icons/icon-1.png", content: "" },
|
|
74
|
+
{ fileName: "src/assets/images/image-1.png", content: "" },
|
|
75
|
+
{ fileName: "src/assets/styles/components.scss", content: componentsScss },
|
|
76
|
+
{ fileName: "src/assets/styles/main.scss", content: mainScss },
|
|
77
|
+
{ fileName: "src/assets/styles/reset.scss", content: resetScss },
|
|
78
|
+
{ fileName: "src/assets/styles/variables.scss", content: variablesScss },
|
|
79
|
+
{ fileName: "src/assets/styles/mixins.scss", content: mixinsScss },
|
|
80
|
+
];
|
|
81
|
+
}
|
package/dist/utils/util.js
CHANGED
|
@@ -28,6 +28,18 @@ export function runCapture(cmd, args, cwd) {
|
|
|
28
28
|
}
|
|
29
29
|
return `${result.stdout ?? ""}`.trim();
|
|
30
30
|
}
|
|
31
|
+
export function runCaptureOptional(cmd, args, cwd) {
|
|
32
|
+
const result = spawnSyncCrossPlatform(cmd, args, { cwd, encoding: "utf8" });
|
|
33
|
+
const stdout = `${result.stdout ?? ""}`.trim();
|
|
34
|
+
const stderr = `${result.stderr ?? ""}`.trim();
|
|
35
|
+
const output = [stdout, stderr].filter(Boolean).join("\n");
|
|
36
|
+
return {
|
|
37
|
+
ok: result.status === 0,
|
|
38
|
+
status: result.status,
|
|
39
|
+
errorMessage: result.error ? result.error.message : "",
|
|
40
|
+
output,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
31
43
|
export function run(cmd, args, cwd) {
|
|
32
44
|
const result = spawnSyncCrossPlatform(cmd, args, { cwd, stdio: "inherit" });
|
|
33
45
|
if (result.status !== 0) {
|
|
@@ -192,13 +204,19 @@ export async function applyLatestStableRanges(pkg, cwd) {
|
|
|
192
204
|
}
|
|
193
205
|
}
|
|
194
206
|
export function runCreateVue(flags, cwd) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
207
|
+
const attempts = [
|
|
208
|
+
{ cmd: "pnpm", args: ["dlx", "create-vue@latest", ...flags] },
|
|
209
|
+
{ cmd: "npm", args: ["create", "vue@latest", "--", ...flags] },
|
|
210
|
+
{ cmd: "npx", args: ["--yes", "create-vue@latest", "--", ...flags] },
|
|
211
|
+
];
|
|
212
|
+
const results = [];
|
|
213
|
+
for (const a of attempts) {
|
|
214
|
+
const r = runCaptureOptional(a.cmd, a.args, cwd);
|
|
215
|
+
results.push({ cmd: a.cmd, args: a.args, ...r });
|
|
216
|
+
if (r.ok) return;
|
|
217
|
+
}
|
|
218
|
+
const last = results[results.length - 1];
|
|
219
|
+
const detail = last.errorMessage ? `: ${last.errorMessage}` : "";
|
|
220
|
+
const out = last.output ? `\n\n${last.output}` : "";
|
|
221
|
+
throw new Error(`${last.cmd} ${last.args.join(" ")} 执行失败${detail}${out}`);
|
|
204
222
|
}
|