diff --git a/docs/content/1.get-started/1.installation.md b/docs/content/1.get-started/1.installation.md index 7454df310b..d02b50c19e 100644 --- a/docs/content/1.get-started/1.installation.md +++ b/docs/content/1.get-started/1.installation.md @@ -23,7 +23,7 @@ Recommended setup is: From visual studio code, open an [integrated terminal](https://code.visualstudio.com/docs/editor/integrated-terminal) and use the following command to create a new starter project: ```bash -npx degit "nuxt/starter#v3" my-nuxt3-project +npx nuxi my-nuxt3-project ``` Open `my-nuxt3-project` folder in visual studio code: diff --git a/packages/nuxi/package.json b/packages/nuxi/package.json index aebeb8d5fe..73372fe1be 100644 --- a/packages/nuxi/package.json +++ b/packages/nuxi/package.json @@ -34,6 +34,7 @@ "colorette": "^2.0.14", "debounce-promise": "^3.1.2", "deep-object-diff": "^1.1.0", + "degit": "^2.8.4", "destr": "^1.1.0", "flat": "^5.0.2", "jiti": "^1.12.6", @@ -42,7 +43,7 @@ "mri": "^1.2.0", "pathe": "^0.2.0", "scule": "^0.2.1", - "unbuild": "latest", - "v8-compile-cache": "^2.3.0" + "superb": "^4.0.0", + "unbuild": "latest" } } diff --git a/packages/nuxi/src/commands/index.ts b/packages/nuxi/src/commands/index.ts index 621653c745..f2c4e95396 100644 --- a/packages/nuxi/src/commands/index.ts +++ b/packages/nuxi/src/commands/index.ts @@ -7,7 +7,9 @@ export const commands = { build: () => import('./build').then(_rDefault), prepare: () => import('./prepare').then(_rDefault), usage: () => import('./usage').then(_rDefault), - info: () => import('./info').then(_rDefault) + info: () => import('./info').then(_rDefault), + init: () => import('./init').then(_rDefault), + create: () => import('./init').then(_rDefault) } export type Command = keyof typeof commands diff --git a/packages/nuxi/src/commands/init.ts b/packages/nuxi/src/commands/init.ts new file mode 100644 index 0000000000..ccd42e166d --- /dev/null +++ b/packages/nuxi/src/commands/init.ts @@ -0,0 +1,46 @@ +import { existsSync, readdirSync } from 'fs' +import createDegit from 'degit' +import { relative, resolve } from 'pathe' +import superb from 'superb' +import { warn, info, error } from '../utils/log' +import { defineNuxtCommand } from './index' + +const rpath = p => relative(process.cwd(), p) + +const knownTemplates = { + nuxt3: 'nuxt/starter#v3', + v3: 'nuxt/starter#v3', + bridge: 'nuxt/starter#bridge' +} + +export default defineNuxtCommand({ + meta: { + name: 'init', + usage: 'npx nuxi init [--verbose|-v] [--template,-t] ', + description: 'Initialize a fresh project' + }, + async invoke (args) { + // Clone template + const t = args.template || args.t + const src = knownTemplates[t] || t || 'nuxt/starter#v3' + const dstDir = resolve(process.cwd(), args._[0] || 'nuxt-app') + const degit = createDegit(src, { cache: false /* TODO: buggy */, verbose: (args.verbose || args.v) }) + if (existsSync(dstDir) && readdirSync(dstDir).length) { + error(`Directory ${dstDir} is not empty. Please pick another name or remove it first. Aborting.`) + process.exit(1) + } + const formatArgs = msg => msg.replace('options.', '--') + degit.on('warn', event => warn(formatArgs(event.message))) + degit.on('info', event => info(formatArgs(event.message))) + await degit.clone(dstDir) + + // Show neet steps + console.log(`\n 🎉 Another Nuxt project just made. ${superb.random()}! Next steps:` + [ + '', + `📁 \`cd ${rpath(dstDir)}\``, + '💿 Install dependencies with `npm install` or `yarn install`', + '🚀 Start development server with `npm run dev` or `yarn dev`', + '' + ].join('\n\n ')) + } +}) diff --git a/yarn.lock b/yarn.lock index 352b8fa9f9..6496535136 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5566,6 +5566,15 @@ __metadata: languageName: node linkType: hard +"degit@npm:^2.8.4": + version: 2.8.4 + resolution: "degit@npm:2.8.4" + bin: + degit: degit + checksum: bb58c48ff1ae3828825d7e614db703afd69905abc2d666009bb4affecb8d87be993511556395889dffc99a5eba7a058117402050c509a6e2c3dd56a579120236 + languageName: node + linkType: hard + "delayed-stream@npm:~1.0.0": version: 1.0.0 resolution: "delayed-stream@npm:1.0.0" @@ -9929,6 +9938,7 @@ fsevents@~2.3.2: colorette: ^2.0.14 debounce-promise: ^3.1.2 deep-object-diff: ^1.1.0 + degit: ^2.8.4 destr: ^1.1.0 flat: ^5.0.2 fsevents: ~2.3.2 @@ -9938,8 +9948,8 @@ fsevents@~2.3.2: mri: ^1.2.0 pathe: ^0.2.0 scule: ^0.2.1 + superb: ^4.0.0 unbuild: latest - v8-compile-cache: ^2.3.0 dependenciesMeta: fsevents: optional: true @@ -13040,6 +13050,15 @@ fsevents@~2.3.2: languageName: node linkType: hard +"superb@npm:^4.0.0": + version: 4.0.0 + resolution: "superb@npm:4.0.0" + dependencies: + unique-random-array: ^2.0.0 + checksum: b80b4d347954ac994863386f6f6ebe176b93ebe8a14258191c118d92ab78296095b8195ae23f4b21e83519ac7eec36cc553fc2672914dd5d3ee98418e93a6bdc + languageName: node + linkType: hard + "supports-color@npm:8.1.1, supports-color@npm:^8.0.0": version: 8.1.1 resolution: "supports-color@npm:8.1.1" @@ -13677,6 +13696,22 @@ fsevents@~2.3.2: languageName: node linkType: hard +"unique-random-array@npm:^2.0.0": + version: 2.0.0 + resolution: "unique-random-array@npm:2.0.0" + dependencies: + unique-random: ^2.1.0 + checksum: c983e511fe6f45b9ee9b78d26a78e94ba798a4afaa2ca289948e694bc6ad75efca0dd1944e94a010ab56dd574daf4ebcf72727c6d581693610d3b0a8192ef2e5 + languageName: node + linkType: hard + +"unique-random@npm:^2.1.0": + version: 2.1.0 + resolution: "unique-random@npm:2.1.0" + checksum: 7bc33f364f288172a948c82c0bbb7393fd175f3a78932aa3a77f070d786d5e86db869dc72f7cb9e0a26e5d3142bfd5c3c9d134a68473a3b1f4e2300d84dbf39d + languageName: node + linkType: hard + "unique-slug@npm:^2.0.0": version: 2.0.2 resolution: "unique-slug@npm:2.0.2" @@ -13838,7 +13873,7 @@ fsevents@~2.3.2: languageName: node linkType: hard -"v8-compile-cache@npm:^2.0.3, v8-compile-cache@npm:^2.3.0": +"v8-compile-cache@npm:^2.0.3": version: 2.3.0 resolution: "v8-compile-cache@npm:2.3.0" checksum: adb0a271eaa2297f2f4c536acbfee872d0dd26ec2d76f66921aa7fc437319132773483344207bdbeee169225f4739016d8d2dbf0553913a52bb34da6d0334f8e