@jackie_qian/create-vue-app 1.0.6 → 1.0.8
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 +189 -166
- package/dist/scaffold.js +16 -4
- 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,112 @@ 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
|
+
addDep(pkg.devDependencies, "@unocss/eslint-plugin", "^0.64.0");
|
|
230
|
+
}
|
|
231
|
+
if (features.has("eslintAntfu")) {
|
|
232
|
+
addDep(pkg.devDependencies, "eslint", "^9.0.0");
|
|
233
|
+
addDep(pkg.devDependencies, "@antfu/eslint-config", "^4.0.0");
|
|
234
|
+
}
|
|
235
|
+
if (features.has("stylelint")) {
|
|
236
|
+
addDep(pkg.devDependencies, "stylelint", "^16.0.0");
|
|
237
|
+
addDep(pkg.devDependencies, "@stylistic/stylelint-config", "^3.0.0");
|
|
238
|
+
addDep(pkg.devDependencies, "stylelint-config-recess-order", "^6.0.0");
|
|
239
|
+
addDep(pkg.devDependencies, "stylelint-config-standard-scss", "^14.0.0");
|
|
240
|
+
addDep(pkg.devDependencies, "stylelint-config-standard-vue", "^1.0.0");
|
|
241
|
+
addDep(pkg.devDependencies, "stylelint-scss", "^6.0.0");
|
|
242
|
+
}
|
|
243
|
+
if (features.has("gitHooks")) {
|
|
244
|
+
addDep(pkg.devDependencies, "simple-git-hooks", "^2.11.1");
|
|
245
|
+
addDep(pkg.devDependencies, "lint-staged", "^15.2.0");
|
|
246
|
+
}
|
|
247
|
+
if (features.has("sassEmbedded"))
|
|
248
|
+
addDep(pkg.devDependencies, "sass-embedded", "^1.77.0");
|
|
249
|
+
if (features.has("eslintAntfu") && features.has("stylelint")) {
|
|
250
|
+
addDep(pkg.devDependencies, "npm-run-all2", "^7.0.2");
|
|
251
|
+
pkg.scripts.lint = "npm-run-all -s lint:eslint lint:stylelint";
|
|
252
|
+
pkg.scripts["lint:eslint"] = "eslint --fix";
|
|
253
|
+
pkg.scripts["lint:stylelint"] =
|
|
254
|
+
'stylelint "src/**/*.{css,scss,vue}" --fix';
|
|
255
|
+
} else if (features.has("eslintAntfu")) {
|
|
256
|
+
pkg.scripts.lint = "eslint";
|
|
257
|
+
pkg.scripts["lint:fix"] = "eslint --fix";
|
|
258
|
+
} else if (features.has("stylelint")) {
|
|
259
|
+
pkg.scripts.lint = "stylelint";
|
|
260
|
+
pkg.scripts["lint:stylelint"] =
|
|
261
|
+
'stylelint "src/**/*.{css,scss,vue}" --fix';
|
|
262
|
+
}
|
|
263
|
+
if (features.has("gitHooks")) {
|
|
264
|
+
pkg.scripts.prepare = "simple-git-hooks";
|
|
265
|
+
pkg["simple-git-hooks"] = {
|
|
266
|
+
"pre-commit": "pnpm lint-staged",
|
|
267
|
+
preserveUnused: true,
|
|
268
|
+
};
|
|
269
|
+
pkg["lint-staged"] = { "*.{js,ts,vue}": "pnpm lint" };
|
|
270
|
+
}
|
|
271
|
+
await finalizePackageJson(pkg, targetDir);
|
|
272
|
+
await writePackageJson(projectPkgPath, pkg);
|
|
273
|
+
const viteConfigPath = path.join(targetDir, "vite.config.ts");
|
|
274
|
+
await writeFileEnsureDir(
|
|
275
|
+
viteConfigPath,
|
|
276
|
+
renderViteConfig(language, features),
|
|
277
|
+
);
|
|
175
278
|
await writeFileEnsureDir(
|
|
176
279
|
path.join(targetDir, ".vscode/settings.json"),
|
|
177
280
|
renderVsCodeSettings(),
|
|
@@ -180,8 +283,70 @@ export async function main() {
|
|
|
180
283
|
path.join(targetDir, ".vscode/extensions.json"),
|
|
181
284
|
renderVsCodeExtensions(language, features),
|
|
182
285
|
);
|
|
286
|
+
await writeFileEnsureDir(
|
|
287
|
+
path.join(targetDir, ".editorconfig"),
|
|
288
|
+
renderEditorConfig(),
|
|
289
|
+
);
|
|
290
|
+
await writeFileEnsureDir(
|
|
291
|
+
path.join(targetDir, ".env.development"),
|
|
292
|
+
renderEnv(projectName),
|
|
293
|
+
);
|
|
294
|
+
await writeFileEnsureDir(
|
|
295
|
+
path.join(targetDir, ".env.production"),
|
|
296
|
+
renderEnv(projectName),
|
|
297
|
+
);
|
|
298
|
+
await patchTsconfigApp(targetDir);
|
|
299
|
+
if (features.has("unocss")) {
|
|
300
|
+
const unoPath = path.join(targetDir, "uno.config.ts");
|
|
301
|
+
await writeFileEnsureDir(unoPath, renderUnoConfig(language));
|
|
302
|
+
}
|
|
303
|
+
const mainPath = path.join(targetDir, "src/main.ts");
|
|
304
|
+
const appPath = path.join(targetDir, "src/App.vue");
|
|
305
|
+
if (features.has("router")) {
|
|
306
|
+
const router = renderRouter(language, features.has("pages"));
|
|
307
|
+
await writeFileEnsureDir(
|
|
308
|
+
path.join(targetDir, router.fileName),
|
|
309
|
+
router.content,
|
|
310
|
+
);
|
|
311
|
+
await writeFileEnsureDir(appPath, renderAppWithRouter());
|
|
312
|
+
if (features.has("pages")) {
|
|
313
|
+
const pagesDir = "src/pages";
|
|
314
|
+
await writeFileEnsureDir(
|
|
315
|
+
path.join(targetDir, pagesDir, "index.vue"),
|
|
316
|
+
renderPagesIndex(),
|
|
317
|
+
);
|
|
318
|
+
await updateTsconfigTypes(targetDir, ["vite-plugin-pages/client"]);
|
|
319
|
+
} else {
|
|
320
|
+
await writeFileEnsureDir(
|
|
321
|
+
path.join(targetDir, "src/views/HomeView.vue"),
|
|
322
|
+
renderHomeView(),
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
if (features.has("pinia")) {
|
|
327
|
+
const store = renderStore(language, features.has("piniaPersist"));
|
|
328
|
+
await writeFileEnsureDir(
|
|
329
|
+
path.join(targetDir, store.fileName),
|
|
330
|
+
store.content,
|
|
331
|
+
);
|
|
332
|
+
await ensureCounterStoreInModules(targetDir, language);
|
|
333
|
+
}
|
|
334
|
+
if (await pathExists(mainPath)) {
|
|
335
|
+
const mainRaw = await readTextFile(mainPath);
|
|
336
|
+
const patched = patchMain(mainRaw, {
|
|
337
|
+
useRouter: features.has("router"),
|
|
338
|
+
useStore: features.has("pinia"),
|
|
339
|
+
useVant: features.has("vant"),
|
|
340
|
+
useElementPlus: features.has("elementPlus"),
|
|
341
|
+
useUno: features.has("unocss"),
|
|
342
|
+
});
|
|
343
|
+
await writeTextFile(mainPath, patched);
|
|
344
|
+
}
|
|
183
345
|
await writeEslintConfig(targetDir, language, features);
|
|
184
346
|
await writeStylelintConfig(targetDir, features);
|
|
347
|
+
const baseFiles = renderProjectStructureFiles(language);
|
|
348
|
+
for (const f of baseFiles)
|
|
349
|
+
await writeFileEnsureDir(path.join(targetDir, f.fileName), f.content);
|
|
185
350
|
if (installDeps) {
|
|
186
351
|
const s2 = spinner();
|
|
187
352
|
s2.start("安装依赖");
|
|
@@ -194,157 +359,15 @@ export async function main() {
|
|
|
194
359
|
throw e;
|
|
195
360
|
}
|
|
196
361
|
}
|
|
362
|
+
s.stop("基础项目已生成");
|
|
363
|
+
const nextSteps = installDeps
|
|
364
|
+
? `\n cd ${projectName}\n ${devCommand(packageManager)}`
|
|
365
|
+
: `\n cd ${projectName}\n\n pnpm install\n pnpm dev\n\n 或\n\n npm install\n npm run dev`;
|
|
197
366
|
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,
|
|
367
|
+
`${pc.green("完成")}:${pc.cyan(projectName)}\n\n${pc.dim("下一步:")}${nextSteps}`,
|
|
298
368
|
);
|
|
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
|
-
}
|
|
369
|
+
} catch (e) {
|
|
370
|
+
s.stop("生成失败");
|
|
371
|
+
throw e;
|
|
346
372
|
}
|
|
347
|
-
outro(
|
|
348
|
-
`${pc.green("完成")}:${pc.cyan(projectName)}\n\n${pc.dim("下一步:")}\n cd ${projectName}\n ${devCommand(packageManager)}`,
|
|
349
|
-
);
|
|
350
373
|
}
|
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() {
|
|
@@ -135,8 +136,10 @@ export async function applyExampleTemplateJs(targetDir, projectName, features) {
|
|
|
135
136
|
ensureDep(pkg.devDependencies, "unplugin-auto-import", "^0.19.0");
|
|
136
137
|
if (features.has("components"))
|
|
137
138
|
ensureDep(pkg.devDependencies, "unplugin-vue-components", "^0.28.0");
|
|
138
|
-
if (features.has("unocss"))
|
|
139
|
+
if (features.has("unocss")) {
|
|
139
140
|
ensureDep(pkg.devDependencies, "unocss", "^0.64.0");
|
|
141
|
+
ensureDep(pkg.devDependencies, "@unocss/eslint-plugin", "^0.64.0");
|
|
142
|
+
}
|
|
140
143
|
if (features.has("eslintAntfu")) {
|
|
141
144
|
ensureDep(pkg.devDependencies, "eslint", "^9.0.0");
|
|
142
145
|
ensureDep(pkg.devDependencies, "@antfu/eslint-config", "^4.0.0");
|
|
@@ -177,7 +180,10 @@ export async function applyExampleTemplateJs(targetDir, projectName, features) {
|
|
|
177
180
|
removeDep(pkg.devDependencies, "unplugin-vue-components");
|
|
178
181
|
if (features.has("vant"))
|
|
179
182
|
pkg.devDependencies["@vant/auto-import-resolver"] ??= "^1.3.0";
|
|
180
|
-
if (!features.has("unocss"))
|
|
183
|
+
if (!features.has("unocss")) {
|
|
184
|
+
removeDep(pkg.devDependencies, "unocss");
|
|
185
|
+
removeDep(pkg.devDependencies, "@unocss/eslint-plugin");
|
|
186
|
+
}
|
|
181
187
|
if (!features.has("eslintAntfu")) {
|
|
182
188
|
removeDep(pkg.devDependencies, "eslint");
|
|
183
189
|
removeDep(pkg.devDependencies, "@antfu/eslint-config");
|
|
@@ -256,8 +262,14 @@ export async function applyExampleTemplateJs(targetDir, projectName, features) {
|
|
|
256
262
|
path.join(targetDir, "jsconfig.json"),
|
|
257
263
|
renderJsConfig(),
|
|
258
264
|
);
|
|
259
|
-
if (!features.has("unocss"))
|
|
265
|
+
if (!features.has("unocss")) {
|
|
260
266
|
await removePath(path.join(targetDir, "uno.config.js"));
|
|
267
|
+
} else {
|
|
268
|
+
await writeFileEnsureDir(
|
|
269
|
+
path.join(targetDir, "uno.config.js"),
|
|
270
|
+
renderUnoConfig("js"),
|
|
271
|
+
);
|
|
272
|
+
}
|
|
261
273
|
if (!features.has("router")) {
|
|
262
274
|
await removePath(path.join(targetDir, "src/router"));
|
|
263
275
|
await writeFileEnsureDir(
|
|
@@ -295,7 +307,7 @@ export async function applyExampleTemplateJs(targetDir, projectName, features) {
|
|
|
295
307
|
if (!features.has("components"))
|
|
296
308
|
await removePath(path.join(targetDir, "src/types/components.d.ts"));
|
|
297
309
|
if (!features.has("sassEmbedded"))
|
|
298
|
-
await removePath(path.join(targetDir, "src/assets/styles"));
|
|
310
|
+
await removePath(path.join(targetDir, "src/assets/styles/main.scss"));
|
|
299
311
|
}
|
|
300
312
|
export async function writeEslintConfig(targetDir, language, features) {
|
|
301
313
|
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
|
}
|