bin.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. #!/usr/bin/env node
  2. import fs from 'fs-extra';
  3. import path from 'node:path';
  4. import * as p from '@clack/prompts';
  5. import { bold, cyan, grey, red, blue } from 'kleur/colors';
  6. import * as langAll from './lang/index.mjs';
  7. const { version } = JSON.parse(fs.readFileSync(new URL('./package.json', import.meta.url), 'utf-8'));
  8. console.log(`
  9. ${grey(`create-stdf@${version}
  10. `)}`);
  11. const spinner = p.spinner();
  12. p.intro('Welcome to use STDF!');
  13. // 选择一种语言
  14. // Select a language
  15. const languageType = await p.select({
  16. message: bold('Please select your preferred language(请选择你习惯的语言)'),
  17. options: [
  18. { value: 'en_US', label: 'English' },
  19. { value: 'zh_CN', label: '简体中文' },
  20. ],
  21. });
  22. const lang = langAll[languageType] || langAll['en_US'];
  23. if (p.isCancel(languageType)) {
  24. p.cancel(red('⛔ ') + lang.oc);
  25. process.exit(0);
  26. }
  27. const templateOptions = [
  28. { value: 'vt', label: 'Vite + Tailwind', template: './templates/vite-tailwind' },
  29. { value: 'vu', label: `Vite + UnoCSS(${lang.hnay})`, template: './templates/vite-uno' },
  30. { value: 'skt', label: `SvelteKit + Tailwind(${lang.hnay})`, template: './templates/sveltekit-tailwind' },
  31. { value: 'sku', label: `SvelteKit + UnoCSS(${lang.hnay})`, template: './templates/sveltekit-uno' },
  32. { value: 'vtt', label: `Vite + Tailwind + TypeScript(${lang.hnay})`, template: './templates/vite-tailwind-typescript' },
  33. { value: 'vut', label: `Vite + UnoCSS+TypeScript(${lang.hnay})`, template: './templates/vite-uno-typescript' },
  34. { value: 'sktt', label: `SvelteKit + Tailwind + TypeScript(${lang.hnay})`, template: './templates/sveltekit-tailwind-typescript' },
  35. { value: 'skut', label: `SvelteKit + UnoCSS + TypeScript(${lang.hnay})`, template: './templates/sveltekit-uno-typescript' },
  36. ];
  37. // 选择一个模板
  38. // Select a template
  39. let template = await p.select({
  40. message: bold(lang.psat),
  41. options: templateOptions,
  42. });
  43. // 直到选择的 template 是 vt 为止,否则一直重新选择
  44. // Until the selected template is vt or vu, otherwise keep reselecting
  45. while (template !== 'vt') {
  46. if (p.isCancel(template)) {
  47. p.cancel(red('⛔ ') + lang.oc);
  48. process.exit(0);
  49. }
  50. p.intro(red(templateOptions.find(item => item.value === template).label + ' ' + lang.pca));
  51. template = await p.select({
  52. message: bold(lang.psat),
  53. options: templateOptions,
  54. });
  55. }
  56. if (p.isCancel(template)) {
  57. p.cancel(red('⛔ ') + lang.oc);
  58. process.exit(0);
  59. }
  60. // 输入项目名称
  61. // Enter the project name
  62. const projectName = await p.text({
  63. message: bold(lang.pn),
  64. initialValue: 'stdf-project',
  65. validate: value => {
  66. if (!value) {
  67. // 判断是否为空,提示 “项目名称不能为空”
  68. // Determine whether it is empty, prompt "Project name cannot be empty"
  69. return lang.pncbne;
  70. }
  71. if (fs.existsSync(value)) {
  72. // 判断是否已存在,提示 “项目名称已存在”
  73. // Determine whether it already exists, prompt "Project name already exists"
  74. return lang.pane;
  75. }
  76. },
  77. });
  78. if (p.isCancel(projectName)) {
  79. p.cancel(red('⛔ ') + lang.oc);
  80. process.exit(0);
  81. }
  82. // 项目目录
  83. // Project directory
  84. const projectDir = path.join(path.resolve(), projectName);
  85. spinner.start('🚀 ' + lang.cfsing);
  86. // 根据 template 的值,复制对应目录下的所有文件到当前目录
  87. // According to the value of template, copy all files under the corresponding directory to the current directory
  88. templateOptions.forEach(async item => {
  89. if (item.value === template) {
  90. fs.mkdirSync(projectDir);
  91. // 获取模板目录的绝对路径
  92. // Get the absolute path of the template directory
  93. const filePath = new URL(item.template, import.meta.url).pathname;
  94. // 将 filePath 目录下的所有文件复制到 projectDir 目录下
  95. // Copy all files under the filePath directory to the projectDir directory\
  96. fs.copy(filePath, projectDir)
  97. .then(() => {
  98. spinner.stop();
  99. console.log(`🎉 ${lang.pcsucc}
  100. `);
  101. // 读取 package.json 文件,获得 vite svelte tailwind stdf 的版本号
  102. // Read the package.json file to get the version number of vite svelte tailwind stdf
  103. const packageJson = JSON.parse(fs.readFileSync(`${projectDir}/package.json`, 'utf-8'));
  104. const versions = {
  105. vite: packageJson.devDependencies.vite,
  106. svelte: packageJson.devDependencies.svelte,
  107. tailwindcss: packageJson.devDependencies.tailwindcss,
  108. stdf: packageJson.devDependencies.stdf,
  109. };
  110. // 显示版本号
  111. // Display version number
  112. console.log(
  113. `📦 ${bold('Vite:')} ${cyan(versions.vite)} ${bold('Svelte:')} ${cyan(versions.svelte)} ${bold('Tailwind:')} ${cyan(
  114. versions.tailwindcss
  115. )} ${bold('STDF:')} ${cyan(versions.stdf)}
  116. `
  117. );
  118. // 显示提示信息
  119. // Display prompt information
  120. console.log(
  121. `👉 ${bold(lang.tgs)}
  122. ${blue(`cd ${projectName}`)}
  123. ${blue('pnpm i / npm i / yarn')}
  124. ${blue('npm run dev')}
  125. `
  126. );
  127. // 显示配置主题色
  128. // Display configuration theme color
  129. console.log(
  130. `🎨 ${bold(lang.pcyt)}
  131. `
  132. );
  133. })
  134. .catch(err => {
  135. spinner.stop();
  136. console.error(111, err);
  137. });
  138. }
  139. });