@jackie_qian/create-vue-app 1.0.0

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.
@@ -0,0 +1,435 @@
1
+ export function renderViteConfigJs(featureSet) {
2
+ const usePages = featureSet.has("pages");
3
+ const useAutoImport = featureSet.has("autoImport");
4
+ const useComponents = featureSet.has("components");
5
+ const useUno = featureSet.has("unocss");
6
+ const useVant = featureSet.has("vant");
7
+ const useElementPlus = featureSet.has("elementPlus");
8
+ const externalImports = [];
9
+ externalImports.push({
10
+ source: "@vitejs/plugin-vue",
11
+ line: `import vue from '@vitejs/plugin-vue'`,
12
+ });
13
+ externalImports.push({
14
+ source: "vite",
15
+ line: `import { defineConfig } from 'vite'`,
16
+ });
17
+ externalImports.push({
18
+ source: "vite-plugin-vue-devtools",
19
+ line: `import vueDevTools from 'vite-plugin-vue-devtools'`,
20
+ });
21
+ if (useVant)
22
+ externalImports.push({
23
+ source: "@vant/auto-import-resolver",
24
+ line: `import { VantResolver } from '@vant/auto-import-resolver'`,
25
+ });
26
+ if (useUno)
27
+ externalImports.push({
28
+ source: "unocss/vite",
29
+ line: `import UnoCSS from 'unocss/vite'`,
30
+ });
31
+ if (useAutoImport)
32
+ externalImports.push({
33
+ source: "unplugin-auto-import/vite",
34
+ line: `import AutoImport from 'unplugin-auto-import/vite'`,
35
+ });
36
+ if (useElementPlus)
37
+ externalImports.push({
38
+ source: "unplugin-vue-components/resolvers",
39
+ line: `import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'`,
40
+ });
41
+ if (useComponents)
42
+ externalImports.push({
43
+ source: "unplugin-vue-components/vite",
44
+ line: `import Components from 'unplugin-vue-components/vite'`,
45
+ });
46
+ if (usePages)
47
+ externalImports.push({
48
+ source: "vite-plugin-pages",
49
+ line: `import Pages from 'vite-plugin-pages'`,
50
+ });
51
+ externalImports.sort((a, b) => a.source.localeCompare(b.source));
52
+ const importLines = [
53
+ `import { fileURLToPath, URL } from 'node:url'`,
54
+ ...externalImports.map((i) => i.line),
55
+ ];
56
+ const plugins = [];
57
+ const resolverItems = [];
58
+ if (useVant) resolverItems.push("VantResolver()");
59
+ if (useElementPlus) resolverItems.push("ElementPlusResolver()");
60
+ const resolvers = resolverItems.length
61
+ ? `[${resolverItems.join(", ")}]`
62
+ : "[]";
63
+ if (usePages) {
64
+ plugins.push(`Pages({
65
+ dirs: 'src/views',
66
+ extensions: ['vue', 'ts'],
67
+ importMode: 'async'
68
+ })`);
69
+ }
70
+ if (useComponents) {
71
+ plugins.push(`Components({
72
+ resolvers: ${resolvers},
73
+ dts: 'src/types/components.d.ts',
74
+ dirs: ['src/components']
75
+ })`);
76
+ }
77
+ if (useAutoImport) {
78
+ const imports = featureSet.has("pinia") ? `['vue', 'pinia']` : `['vue']`;
79
+ plugins.push(`AutoImport({
80
+ resolvers: ${resolvers},
81
+ imports: ${imports},
82
+ dts: 'src/types/auto-import.d.ts',
83
+ dirs: ['src/hooks'],
84
+ vueTemplate: true
85
+ })`);
86
+ }
87
+ if (useUno) plugins.push(`UnoCSS()`);
88
+ plugins.push(`vue()`);
89
+ plugins.push(`vueDevTools()`);
90
+ return `${importLines.join("\n")}
91
+
92
+ // https://vite.dev/config/
93
+ export default defineConfig({
94
+ plugins: [
95
+ ${plugins.join(",\n ")}
96
+ ],
97
+ resolve: {
98
+ alias: {
99
+ '@': fileURLToPath(new URL('./src', import.meta.url))
100
+ }
101
+ }
102
+ })
103
+ `;
104
+ }
105
+ export function renderViteConfig(language, featureSet) {
106
+ if (language === "js") return renderViteConfigJs(featureSet);
107
+ const isTs = true;
108
+ const usePages = featureSet.has("pages");
109
+ const useAutoImport = featureSet.has("autoImport");
110
+ const useComponents = featureSet.has("components");
111
+ const useVant = featureSet.has("vant");
112
+ const useElementPlus = featureSet.has("elementPlus");
113
+ const useUno = featureSet.has("unocss");
114
+ const useEslint = featureSet.has("eslintAntfu");
115
+ const externalImports = [];
116
+ externalImports.push({
117
+ source: "@vitejs/plugin-vue",
118
+ line: `import vue from '@vitejs/plugin-vue'`,
119
+ });
120
+ externalImports.push({
121
+ source: "vite",
122
+ line: `import { defineConfig } from 'vite'`,
123
+ });
124
+ if (useVant)
125
+ externalImports.push({
126
+ source: "@vant/auto-import-resolver",
127
+ line: `import { VantResolver } from '@vant/auto-import-resolver'`,
128
+ });
129
+ if (useUno)
130
+ externalImports.push({
131
+ source: "unocss/vite",
132
+ line: `import UnoCSS from 'unocss/vite'`,
133
+ });
134
+ if (useAutoImport)
135
+ externalImports.push({
136
+ source: "unplugin-auto-import/vite",
137
+ line: `import AutoImport from 'unplugin-auto-import/vite'`,
138
+ });
139
+ if (useElementPlus)
140
+ externalImports.push({
141
+ source: "unplugin-vue-components/resolvers",
142
+ line: `import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'`,
143
+ });
144
+ if (useComponents)
145
+ externalImports.push({
146
+ source: "unplugin-vue-components/vite",
147
+ line: `import Components from 'unplugin-vue-components/vite'`,
148
+ });
149
+ if (usePages)
150
+ externalImports.push({
151
+ source: "vite-plugin-pages",
152
+ line: `import Pages from 'vite-plugin-pages'`,
153
+ });
154
+ externalImports.sort((a, b) => a.source.localeCompare(b.source));
155
+ const importLines = [
156
+ `import { fileURLToPath, URL } from 'node:url'`,
157
+ ...externalImports.map((i) => i.line),
158
+ ];
159
+ const plugins = [];
160
+ if (usePages) {
161
+ const dirs = isTs ? "src/pages" : "src/views";
162
+ const extensions = isTs ? `['vue', 'ts']` : `['vue', 'js']`;
163
+ plugins.push(
164
+ `Pages({ dirs: '${dirs}', extensions: ${extensions}, importMode: 'async' })`,
165
+ );
166
+ }
167
+ const resolverItems = [];
168
+ if (useVant) resolverItems.push("VantResolver()");
169
+ if (useElementPlus) resolverItems.push("ElementPlusResolver()");
170
+ const resolvers = resolverItems.length
171
+ ? `[${resolverItems.join(", ")}]`
172
+ : `[]`;
173
+ if (useAutoImport) {
174
+ const imports = ["vue"];
175
+ if (featureSet.has("router")) imports.push("vue-router");
176
+ if (featureSet.has("pinia")) imports.push("pinia");
177
+ const eslintrc = useEslint ? `, eslintrc: { enabled: true }` : "";
178
+ plugins.push(
179
+ `AutoImport({ resolvers: ${resolvers}, imports: ${JSON.stringify(imports)}, dts: 'src/types/auto-import.d.ts', vueTemplate: true${eslintrc} })`,
180
+ );
181
+ }
182
+ if (useComponents) {
183
+ plugins.push(
184
+ `Components({ resolvers: ${resolvers}, dts: 'src/types/components.d.ts' })`,
185
+ );
186
+ }
187
+ if (useUno) plugins.push(`UnoCSS()`);
188
+ plugins.push("vue()");
189
+ return `${importLines.join("\n")}
190
+
191
+ export default defineConfig({
192
+ plugins: [
193
+ ${plugins.join(",\n ")}
194
+ ],
195
+ resolve: {
196
+ alias: {
197
+ '@': fileURLToPath(new URL('./src', import.meta.url))
198
+ }
199
+ }
200
+ })
201
+ `;
202
+ }
203
+ export function renderUnoConfig(language) {
204
+ return `import { defineConfig, presetAttributify, presetWind3, transformerDirectives } from 'unocss'
205
+
206
+ export default defineConfig({
207
+ presets: [
208
+ presetAttributify(),
209
+ presetWind3()
210
+ ],
211
+ transformers: [
212
+ transformerDirectives()
213
+ ],
214
+ layers: {
215
+ components: -1,
216
+ default: 1,
217
+ utilities: 2
218
+ }
219
+ })
220
+ `;
221
+ }
222
+ export function renderVsCodeSettings() {
223
+ return `{
224
+ "eslint.useFlatConfig": true,
225
+ "prettier.enable": false,
226
+ "editor.formatOnSave": false,
227
+ "editor.codeActionsOnSave": {
228
+ "source.fixAll.eslint": "explicit",
229
+ "source.fixAll.stylelint": "explicit",
230
+ "source.organizeImports": "never"
231
+ },
232
+ "stylelint.validate": [
233
+ "css",
234
+ "postcss",
235
+ "scss",
236
+ "vue"
237
+ ],
238
+ "eslint.validate": [
239
+ "javascript",
240
+ "typescript",
241
+ "vue",
242
+ "html",
243
+ "markdown",
244
+ "json",
245
+ "jsonc",
246
+ "yaml"
247
+ ],
248
+ "css.lint.unknownAtRules": "ignore",
249
+ "scss.lint.unknownAtRules": "ignore",
250
+ "scss.lint.unknownProperties": "ignore",
251
+ "cSpell.enabled": false
252
+ }
253
+ `;
254
+ }
255
+ export function renderEditorConfig() {
256
+ return `root = true
257
+
258
+ [*]
259
+ charset = utf-8
260
+ indent_style = space
261
+ indent_size = 2
262
+ end_of_line = lf
263
+ trim_trailing_whitespace = true
264
+ insert_final_newline = true
265
+
266
+ [*.md]
267
+ max_line_length = off
268
+ trim_trailing_whitespace = false
269
+ `;
270
+ }
271
+ export function renderEnv(title) {
272
+ return `# 页面标题
273
+ VITE_APP_TITLE = ${title}
274
+
275
+ # 接口请求地址,会设置到 axios 的 baseURL 参数上
276
+ VITE_APP_API_BASEURL = /
277
+ `;
278
+ }
279
+ export function renderJsConfig() {
280
+ return `{
281
+ "compilerOptions": {
282
+ "target": "ESNext",
283
+ "baseUrl": "./",
284
+ "module": "ESNext",
285
+ "moduleResolution": "Bundler",
286
+ "paths": {
287
+ "@/*": ["src/*"]
288
+ },
289
+ "allowJs": true
290
+ },
291
+ "include": ["src/*.js", "src/**/*.js", "src/**/*.vue", "src/**/*.d.ts"],
292
+ "exclude": ["node_modules"]
293
+ }
294
+ `;
295
+ }
296
+ export function renderMainJs(featureSet) {
297
+ const lines = [];
298
+ lines.push(`import { createApp } from 'vue'`);
299
+ lines.push("");
300
+ lines.push(`import App from './App.vue'`);
301
+ if (featureSet.has("router")) lines.push(`import router from './router'`);
302
+ if (featureSet.has("pinia")) lines.push(`import Pinia from './stores/index'`);
303
+ if (featureSet.has("vant")) lines.push(`import 'vant/lib/index.css'`);
304
+ if (featureSet.has("elementPlus"))
305
+ lines.push(`import 'element-plus/dist/index.css'`);
306
+ if (featureSet.has("sassEmbedded"))
307
+ lines.push(`import './assets/styles/main.scss'`);
308
+ lines.push("");
309
+ lines.push(`const app = createApp(App)`);
310
+ lines.push("");
311
+ if (featureSet.has("router")) lines.push(`app.use(router)`);
312
+ if (featureSet.has("pinia")) lines.push(`app.use(Pinia)`);
313
+ lines.push("");
314
+ lines.push(`app.mount('#app')`);
315
+ lines.push("");
316
+ return `${lines.join("\n")}`;
317
+ }
318
+ export function renderRouter(language, usePages) {
319
+ const ext = language === "ts" ? "ts" : "js";
320
+ if (usePages) {
321
+ return {
322
+ fileName: `src/router/index.${ext}`,
323
+ content: `import { createRouter, createWebHistory } from 'vue-router'
324
+ import routes from '~pages'
325
+
326
+ const router = createRouter({
327
+ history: createWebHistory(),
328
+ routes
329
+ })
330
+
331
+ export default router
332
+ `,
333
+ };
334
+ }
335
+ const importRoutes = `import IndexView from '../views/index.vue'`;
336
+ const routesDecl = `[
337
+ { name: 'Index', path: '/', component: IndexView }
338
+ ]`;
339
+ return {
340
+ fileName: `src/router/index.${ext}`,
341
+ content: `import { createRouter, createWebHistory } from 'vue-router'
342
+ ${importRoutes}
343
+
344
+ const router = createRouter({
345
+ history: createWebHistory(),
346
+ routes: ${routesDecl}
347
+ })
348
+
349
+ export default router
350
+ `,
351
+ };
352
+ }
353
+ export function renderStore(language, persisted) {
354
+ const ext = language === "ts" ? "ts" : "js";
355
+ const lines = [];
356
+ lines.push(`import { createPinia } from 'pinia'`);
357
+ if (persisted)
358
+ lines.push(
359
+ `import { createPersistedState } from 'pinia-plugin-persistedstate'`,
360
+ );
361
+ lines.push("");
362
+ lines.push("const store = createPinia()");
363
+ if (persisted) lines.push("store.use(createPersistedState())");
364
+ lines.push("");
365
+ lines.push("export default store");
366
+ lines.push("");
367
+ return {
368
+ fileName: `src/stores/index.${ext}`,
369
+ content: `${lines.join("\n")}`,
370
+ };
371
+ }
372
+ export function renderHomeView() {
373
+ return `<template>
374
+ <div class="page">
375
+ <h1>Home</h1>
376
+ </div>
377
+ </template>
378
+ `;
379
+ }
380
+ export function renderPagesIndex() {
381
+ return `<template>
382
+ <div class="page">
383
+ <h1>Home</h1>
384
+ </div>
385
+ </template>
386
+ `;
387
+ }
388
+ export function renderAppWithRouter() {
389
+ return `<template>
390
+ <RouterView />
391
+ </template>
392
+ `;
393
+ }
394
+ export function patchMain(content, options) {
395
+ const mainImports = [];
396
+ const usesCreateApp = content.includes("createApp(");
397
+ if (!usesCreateApp) return content;
398
+ if (options.useUno && !content.includes("virtual:uno.css"))
399
+ mainImports.push(`import 'virtual:uno.css'`);
400
+ if (options.useVant && !content.includes("vant/lib/index.css"))
401
+ mainImports.push(`import 'vant/lib/index.css'`);
402
+ if (
403
+ options.useElementPlus &&
404
+ !content.includes("element-plus/dist/index.css")
405
+ )
406
+ mainImports.push(`import 'element-plus/dist/index.css'`);
407
+ if (options.useRouter && !content.includes("from './router'"))
408
+ mainImports.push(`import router from './router'`);
409
+ if (options.useStore && !content.includes("from './stores'"))
410
+ mainImports.push(`import store from './stores'`);
411
+ const importBlock = mainImports.length ? `${mainImports.join("\n")}\n` : "";
412
+ const useBlock = [
413
+ options.useStore ? "app.use(store)" : "",
414
+ options.useRouter ? "app.use(router)" : "",
415
+ ]
416
+ .filter(Boolean)
417
+ .join("\n");
418
+ const withUse = useBlock ? `\n${useBlock}\n` : "\n";
419
+ const replaced = content.replace(
420
+ /import\s+\{\s*createApp\s*\}\s+from\s+'vue'\s*\n/,
421
+ (match) => `${match}${importBlock}`,
422
+ );
423
+ if (useBlock) {
424
+ return replaced
425
+ .replace(/app\.mount\('#app'\)\s*\n?/, `app.mount('#app')\n`)
426
+ .replace(
427
+ /const\s+app\s*=\s*createApp\(App\)\s*\n([\s\S]*?)app\.mount\('#app'\)/,
428
+ (m, between) => {
429
+ if (between.includes("app.use(")) return m;
430
+ return m.replace("app.mount('#app')", `${withUse}app.mount('#app')`);
431
+ },
432
+ );
433
+ }
434
+ return replaced;
435
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ export const FEATURES_OPTIONS = [
2
+ { value: "router", label: "Router (SPA 开发)" },
3
+ { value: "pinia", label: "Pinia (状态管理)" },
4
+ { value: "piniaPersist", label: "Pinia 状态持久化" },
5
+ { value: "sassEmbedded", label: "SassEmbedded" },
6
+ { value: "eslintAntfu", label: "ESLint (Antfu 风格)" },
7
+ { value: "stylelint", label: "Stylelint" },
8
+ { value: "gitHooks", label: "GitHooks (simple-git-hooks + lint-staged)" },
9
+ ];
10
+ export const UI_LIBRARY_OPTIONS = [
11
+ { value: "vant", label: "Vant" },
12
+ { value: "elementPlus", label: "Element Plus" },
13
+ { value: "none", label: "不使用" },
14
+ ];
15
+ export const PACKAGE_MANAGER_OPTIONS = [
16
+ { value: "pnpm", label: "pnpm" },
17
+ { value: "npm", label: "npm" },
18
+ { value: "yarn", label: "yarn" },
19
+ { value: "bun", label: "bun" },
20
+ ];
@@ -0,0 +1,168 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { promises as fs } from "node:fs";
3
+ import path from "node:path";
4
+ export function runCapture(cmd, args, cwd) {
5
+ const result = spawnSync(cmd, args, { cwd, encoding: "utf8" });
6
+ if (result.status !== 0) throw new Error(`${cmd} ${args.join(" ")} 执行失败`);
7
+ return `${result.stdout ?? ""}`.trim();
8
+ }
9
+ export function run(cmd, args, cwd) {
10
+ const result = spawnSync(cmd, args, { cwd, stdio: "inherit" });
11
+ if (result.status !== 0) throw new Error(`${cmd} ${args.join(" ")} 执行失败`);
12
+ }
13
+ export function installCommand(pm) {
14
+ if (pm === "pnpm") return { cmd: "pnpm", args: ["install"] };
15
+ if (pm === "npm") return { cmd: "npm", args: ["install"] };
16
+ if (pm === "yarn") return { cmd: "yarn", args: [] };
17
+ return { cmd: "bun", args: ["install"] };
18
+ }
19
+ export function devCommand(pm) {
20
+ if (pm === "pnpm") return "pnpm dev";
21
+ if (pm === "npm") return "npm run dev";
22
+ if (pm === "yarn") return "yarn dev";
23
+ return "bun dev";
24
+ }
25
+ export function sortObjectKeys(obj) {
26
+ return Object.fromEntries(
27
+ Object.entries(obj).sort(([a], [b]) => a.localeCompare(b)),
28
+ );
29
+ }
30
+ export async function pathExists(p) {
31
+ try {
32
+ await fs.access(p);
33
+ return true;
34
+ } catch {
35
+ return false;
36
+ }
37
+ }
38
+ export async function ensureEmptyDir(dir) {
39
+ if (!(await pathExists(dir))) return;
40
+ const items = await fs.readdir(dir);
41
+ if (items.length > 0) throw new Error(`目录已存在且非空: ${dir}`);
42
+ }
43
+ export async function writeFileEnsureDir(filePath, content) {
44
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
45
+ await fs.writeFile(filePath, content, "utf8");
46
+ }
47
+ export async function removePath(targetPath) {
48
+ await fs.rm(targetPath, { recursive: true, force: true });
49
+ }
50
+ export async function copyDir(srcDir, destDir, options) {
51
+ const skip = options?.skip;
52
+ const root = srcDir;
53
+ async function walk(currentSrc, currentDest) {
54
+ await fs.mkdir(currentDest, { recursive: true });
55
+ const entries = await fs.readdir(currentSrc, { withFileTypes: true });
56
+ for (const entry of entries) {
57
+ const srcPath = path.join(currentSrc, entry.name);
58
+ const destPath = path.join(currentDest, entry.name);
59
+ const rel = path.relative(root, srcPath);
60
+ if (skip?.(rel)) continue;
61
+ if (entry.isDirectory()) {
62
+ await walk(srcPath, destPath);
63
+ continue;
64
+ }
65
+ if (entry.isSymbolicLink()) {
66
+ const link = await fs.readlink(srcPath);
67
+ await fs.symlink(link, destPath);
68
+ continue;
69
+ }
70
+ await fs.copyFile(srcPath, destPath);
71
+ }
72
+ }
73
+ await walk(srcDir, destDir);
74
+ }
75
+ export function stripJsonc(input) {
76
+ const s = input.replace(/^\uFEFF/, "");
77
+ let out = "";
78
+ let i = 0;
79
+ let inString = false;
80
+ let stringQuote = null;
81
+ let escaped = false;
82
+ while (i < s.length) {
83
+ const ch = s[i];
84
+ const next = s[i + 1];
85
+ if (inString) {
86
+ out += ch;
87
+ if (escaped) {
88
+ escaped = false;
89
+ } else if (ch === "\\") {
90
+ escaped = true;
91
+ } else if (stringQuote && ch === stringQuote) {
92
+ inString = false;
93
+ stringQuote = null;
94
+ }
95
+ i += 1;
96
+ continue;
97
+ }
98
+ if (ch === '"' || ch === "'") {
99
+ inString = true;
100
+ stringQuote = ch;
101
+ out += ch;
102
+ i += 1;
103
+ continue;
104
+ }
105
+ if (ch === "/" && next === "/") {
106
+ i += 2;
107
+ while (i < s.length && s[i] !== "\n") i += 1;
108
+ continue;
109
+ }
110
+ if (ch === "/" && next === "*") {
111
+ i += 2;
112
+ while (i < s.length) {
113
+ if (s[i] === "*" && s[i + 1] === "/") {
114
+ i += 2;
115
+ break;
116
+ }
117
+ i += 1;
118
+ }
119
+ continue;
120
+ }
121
+ out += ch;
122
+ i += 1;
123
+ }
124
+ let cleaned = out;
125
+ for (let round = 0; round < 5; round += 1) {
126
+ const next = cleaned.replace(/,\s*([}\]])/g, "$1");
127
+ if (next === cleaned) break;
128
+ cleaned = next;
129
+ }
130
+ return cleaned;
131
+ }
132
+ export function parseJsonLike(raw) {
133
+ try {
134
+ return JSON.parse(raw);
135
+ } catch {
136
+ return JSON.parse(stripJsonc(raw));
137
+ }
138
+ }
139
+ export async function readJson(filePath) {
140
+ const raw = await fs.readFile(filePath, "utf8");
141
+ return parseJsonLike(raw);
142
+ }
143
+ export async function writeJson(filePath, data) {
144
+ await fs.writeFile(filePath, `${JSON.stringify(data, null, 2)}\n`, "utf8");
145
+ }
146
+ export async function resolveLatestStableVersion(pkgName, cwd) {
147
+ const raw = runCapture("npm", ["view", pkgName, "version", "--json"], cwd);
148
+ const v = parseJsonLike(raw);
149
+ const version = typeof v === "string" ? v : String(v);
150
+ if (version.includes("-"))
151
+ throw new Error(`无法解析 ${pkgName} 的稳定版本:${version}`);
152
+ return version;
153
+ }
154
+ export async function applyLatestStableRanges(pkg, cwd) {
155
+ const cache = new Map();
156
+ const sections = ["dependencies", "devDependencies"];
157
+ for (const section of sections) {
158
+ const deps = pkg[section];
159
+ if (!deps) continue;
160
+ for (const name of Object.keys(deps)) {
161
+ const current = deps[name];
162
+ if (!current || current.startsWith("workspace:")) continue;
163
+ if (!cache.has(name))
164
+ cache.set(name, await resolveLatestStableVersion(name, cwd));
165
+ deps[name] = `^${cache.get(name)}`;
166
+ }
167
+ }
168
+ }
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@jackie_qian/create-vue-app",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "create-vue-app": "bin/index.mjs"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public",
12
+ "registry": "https://registry.npmjs.org/"
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "bin"
17
+ ],
18
+ "scripts": {
19
+ "dev": "tsx src/index.ts",
20
+ "build": "tsc -p tsconfig.cli.json",
21
+ "typecheck": "tsc -p tsconfig.cli.json --noEmit",
22
+ "format:dist": "prettier --write \"dist/**/*.js\" --tab-width 2 --use-tabs false",
23
+ "prepublishOnly": "pnpm build && pnpm format:dist"
24
+ },
25
+ "keywords": [],
26
+ "author": "Jackie_Qian",
27
+ "license": "ISC",
28
+ "packageManager": "pnpm@10.13.1",
29
+ "dependencies": {
30
+ "@clack/prompts": "^1.1.0",
31
+ "picocolors": "^1.1.1"
32
+ },
33
+ "devDependencies": {
34
+ "@types/node": "^24.0.0",
35
+ "prettier": "^3.3.3",
36
+ "tsx": "^4.21.0",
37
+ "typescript": "^5.9.3"
38
+ }
39
+ }