unovue / shadcn-vue

Vue port of shadcn-ui
https://www.shadcn-vue.com/
MIT License
4.89k stars 280 forks source link

[Feature]: Create internal frameworks templates for the CLI #570

Open MuhammadM1998 opened 5 months ago

MuhammadM1998 commented 5 months ago

Describe the feature

After https://github.com/radix-vue/shadcn-vue/pull/528, the CLI should check in a Nuxt project If shadcn-nuxt injects the file or not and act accordingly. This requires modifying the following code.

https://github.com/radix-vue/shadcn-vue/blob/bd0a8206efa0c0f1fee735f17ab94c63b408e106/packages/cli/src/commands/init.ts#L301-L306

Similarly after https://github.com/radix-vue/shadcn-vue/pull/531.We need to check if we should install all deps or only a set of them here https://github.com/radix-vue/shadcn-vue/blob/bd0a8206efa0c0f1fee735f17ab94c63b408e106/packages/cli/src/commands/init.ts#L313-L316

This checking can get messy too quick, and that's for Nuxt-specifics alone. Adding features specific to astro for example would require adding checks for that too.

I propose refactoring the runInit command to the following

cli/src/commands/init.ts

import { runNuxtInitTemplate, runNuxtInitTemplate, runNuxtInitTemplate} from './initTempaltes'

export async function runInit(cwd: string, config: Config) {
  const spinner = ora('Initializing project...')?.start()

  const context = await getProjectInfo() // `context` has `framework` option among other useful keys
  const { framework } = context

  // Shared Inline Code

  // Running the appropriate init template based on framework
  let success, error;
  if (context.framework === 'nuxt')
    { success, error} = runNuxtInitTemplate(context)
  elseif (context.framework === 'vite')
    { success, error} = runVueInitTemplate(context) 
  elseif (context.framework === 'astro')
    { success, error} = runAstroInitTemplate(context) // Just for example. For now I think `Nuxt` and `Vue` templates would be sufficent

  if (error) return consola.error('Error while initializing.', error)
  spinner?.succeed()
}

cli/src/commands/initTempaltes.ts

export function runNuxtInitTemplate(context: ProjectContext) {
  // Specific Nuxt Things
  sharedFunction()
  // Other Specific Nuxt Things
  return { success, error }
}

export function runViteInitTemplate(context: ProjectContext) {
  // Specific Vite Setup
  sharedFunction()
  // Other Specific Vite Things
  return { success, error }
}

export function runAstroInitTemplate(context: ProjectContext) {
  // Specific Astro Setup
  sharedFunction()
  // Other Specific Astro Things
  return { success, error }
}

function sharedFunction(){
  // Stuff
}

This way is more organized and easier to understand & maintain. Also if anyone want to contribute to specific framework he won't need to understand how the other frameworks work and avoids changing unrelated code which can cause mistakes.

I opened the issue for discussion. I'm up to raise a PR once a final structure is agreed 🙏

Additional information

sadeghbarati commented 5 months ago

CC @zernonia