create-banana 1.0.0 → 1.0.1

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/bin/index.js CHANGED
@@ -1,30 +1,63 @@
1
1
  #!/usr/bin/env node
2
- import printString from '../utils/figletPrint.js'
3
- import rainbowGradient from '../utils/rainbow.js'
2
+ import printString from '#utils/figletPrint.js'
3
+ import rainbowGradient from '#utils/rainbow.js'
4
4
  import { input } from '@inquirer/prompts'
5
- import createBaseProject from '../utils/template/base.js'
5
+ import createBaseProject from '#utils/template/base/base.js'
6
6
  import { checkbox } from '@inquirer/prompts'
7
- import addEslint from '../utils/template/eslint.js'
8
- import addPrettier from '../utils/template/prettier.js'
9
- import addEslintConfig from '../template/eslint/eslintConfig/index.js'
7
+ import addEslint from '#utils/template/eslint/eslint.js'
8
+ import addPrettier from '#utils/template/prettier.js'
9
+ import addEslintConfig from '#utils/template/eslint/eslintConfig.js'
10
+ import addPinia from '#utils/template/pinia/pinia.js'
11
+ import addAppVue from '#utils/template/base/appVue.js'
12
+ import path from 'path'
13
+ import confirmPathExists from '#utils/pathExists.js'
14
+ import addMain from '#utils/template/base/main.js'
15
+ import { select } from '@inquirer/prompts'
16
+ import addPiniaPluginPersistedstate from '#utils/template/pinia/piniaPluginPersistedstate.js'
10
17
 
11
18
  // print BANANA in rainbow colors
12
19
  console.log(rainbowGradient(await printString('BANANA')))
13
20
 
14
21
  const projectName = await input({ message: 'Enter your project name:', required: true })
15
22
 
23
+ // 确认路径存在
24
+ await confirmPathExists(projectName, path.join(process.cwd(), projectName))
25
+
16
26
  const feats = await checkbox({
17
27
  message: 'Please select the features to include:',
18
28
  choices: [
19
29
  { name: 'Eslint', value: 'eslint' },
20
30
  { name: 'Prettier', value: 'prettier' },
31
+ { name: 'Pinia', value: 'pinia' },
21
32
  ],
22
33
  })
23
34
 
24
35
  const useEslint = feats.includes('eslint')
25
36
  const usePrettier = feats.includes('prettier')
37
+ const usePinia = feats.includes('pinia')
38
+
39
+ let usePiniaPluginPersistedstate = false
40
+ if (usePinia) {
41
+ usePiniaPluginPersistedstate = await select({
42
+ message: `Do you want to use pinia-plugin-persistedstate for Pinia state persistence?`,
43
+ choices: [
44
+ { name: 'Yes', value: true },
45
+ { name: 'No', value: false },
46
+ ],
47
+ })
48
+ }
26
49
 
50
+ // TODO: 把一类型的功能整合到一起
27
51
  await createBaseProject(projectName)
52
+ await addAppVue(projectName, usePinia, usePiniaPluginPersistedstate)
53
+ await addMain(projectName, usePinia, usePiniaPluginPersistedstate)
54
+
55
+ await addPinia(projectName, usePinia, usePiniaPluginPersistedstate)
56
+ await addPiniaPluginPersistedstate(projectName, usePiniaPluginPersistedstate)
57
+
28
58
  await addEslint(projectName, useEslint)
29
- await addPrettier(projectName, useEslint, usePrettier)
30
59
  await addEslintConfig(projectName, usePrettier, useEslint)
60
+
61
+ await addPrettier(projectName, useEslint, usePrettier)
62
+
63
+ // TODO: 输出后续操作,例如lint,git
package/package.json CHANGED
@@ -1,10 +1,17 @@
1
1
  {
2
2
  "name": "create-banana",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/TMname1/create-banana.git"
7
+ },
4
8
  "type": "module",
5
9
  "description": "TMname1's CLI tool to create customized templates",
6
10
  "main": "index.js",
7
11
  "bin": "./bin/index.js",
12
+ "imports": {
13
+ "#utils/*": "./utils/*"
14
+ },
8
15
  "lint-staged": {
9
16
  "*": [
10
17
  "eslint . --fix",
@@ -0,0 +1,75 @@
1
+ <script setup>
2
+ import HelloWorld from './components/HelloWorld.vue'
3
+ import TheWelcome from './components/TheWelcome.vue'
4
+ <% if(usePinia) { %>import { useCounterStore } from './stores/counter' <% } %>
5
+ <% if(usePiniaPluginPersistedstate) { %>import { useKeyStore } from './stores/key' <% } %>
6
+
7
+ <% if(usePinia) { %>const counterStore = useCounterStore()<% } %>
8
+ <% if(usePiniaPluginPersistedstate) { %>const keyStore = useKeyStore()<% } %>
9
+ </script>
10
+
11
+ <template>
12
+ <header>
13
+ <img alt="Vue logo" class="logo" src="./assets/logo.svg" width="125" height="125" />
14
+
15
+ <div class="wrapper">
16
+ <HelloWorld msg="You did it!" />
17
+ <% if(usePinia) { %><button class="piniaBtn" @click="counterStore.increment">Count is: {{ counterStore.count }}</button><% } %>
18
+ <% if(usePiniaPluginPersistedstate) { %><input class="persistInp" v-model="keyStore.key" placeholder="Enter a key to persist" /><% } %>
19
+ </div>
20
+ </header>
21
+
22
+ <main>
23
+ <TheWelcome />
24
+ </main>
25
+ </template>
26
+
27
+ <style scoped>
28
+ header {
29
+ line-height: 1.5;
30
+ }
31
+
32
+ .logo {
33
+ display: block;
34
+ margin: 0 auto 2rem;
35
+ }
36
+
37
+ <% if(usePinia) { %>.piniaBtn {
38
+ margin-top: 1rem;
39
+ padding: 0.5rem 1rem;
40
+ font-size: 1rem;
41
+ border: none;
42
+ border-radius: 4px;
43
+ background-color: #42b983;
44
+ color: white;
45
+ cursor: pointer;
46
+ }<% } %>
47
+
48
+ <% if(usePiniaPluginPersistedstate) { %>.persistInp {
49
+ margin-top: 1rem;
50
+ padding: 0.5rem;
51
+ font-size: 1rem;
52
+ border: 1px solid #ccc;
53
+ border-radius: 4px;
54
+ width: 100%;
55
+ max-width: 300px;
56
+ }<% } %>
57
+
58
+ @media (min-width: 1024px) {
59
+ header {
60
+ display: flex;
61
+ place-items: center;
62
+ padding-right: calc(var(--section-gap) / 2);
63
+ }
64
+
65
+ .logo {
66
+ margin: 0 2rem 0 0;
67
+ }
68
+
69
+ header .wrapper {
70
+ display: flex;
71
+ place-items: flex-start;
72
+ flex-wrap: wrap;
73
+ }
74
+ }
75
+ </style>
@@ -0,0 +1,7 @@
1
+ import './assets/main.css'
2
+ import { createApp } from 'vue'
3
+ import App from './App.vue'
4
+ <% if(usePinia) { %>import { createPinia } from 'pinia'<% } %>
5
+ <% if(usePiniaPluginPersistedstate) { %>import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'<% } %>
6
+
7
+ createApp(App)<% if(usePinia) { %>.use(createPinia()<% if(usePiniaPluginPersistedstate) { %>.use(piniaPluginPersistedstate)<% } %>)<% } %>.mount('#app')
@@ -7,12 +7,5 @@ export const useCounterStore = defineStore('counter', () => {
7
7
  function increment() {
8
8
  count.value++
9
9
  }
10
-
11
10
  return { count, doubleCount, increment }
12
11
  })
13
-
14
- // TODO: 添加pinia 的模板
15
-
16
- // TODO: main.js要用ejs来调整
17
-
18
- // TODO: 添加是否选择pinia持久化的功能
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "pinia": "^3.0.4"
4
+ }
5
+ }
@@ -0,0 +1,11 @@
1
+ import { ref } from 'vue'
2
+ import { defineStore } from 'pinia'
3
+
4
+ export const useKeyStore = defineStore(
5
+ 'key',
6
+ () => {
7
+ const key = ref('')
8
+ return { key }
9
+ },
10
+ { persist: true },
11
+ )
@@ -0,0 +1,5 @@
1
+ {
2
+ "dependencies": {
3
+ "pinia-plugin-persistedstate": "^4.7.1"
4
+ }
5
+ }
package/utils/URL.js CHANGED
@@ -3,13 +3,11 @@ import path from 'path'
3
3
  import { fileURLToPath } from 'url'
4
4
 
5
5
  // 拼接相对路径
6
- const relativePath = (fileURL, targetURL) => {
6
+ export const relativePath = (fileURL, targetURL) => {
7
7
  const __filename = fileURLToPath(fileURL)
8
8
  const __dirname = path.dirname(__filename)
9
9
  return path.join(__dirname, targetURL)
10
10
  }
11
- export { relativePath }
12
11
 
13
12
  // 获取模板目录路径
14
- const templatePath = fileURLToPath(new URL('../template', import.meta.url))
15
- export { templatePath }
13
+ export const templatePath = fileURLToPath(new URL('../template', import.meta.url))
@@ -1,5 +1,4 @@
1
1
  // print BANANA in big money-se font using figlet
2
-
3
2
  import figlet from 'figlet'
4
3
 
5
4
  const printString = async (str) => {
@@ -0,0 +1,18 @@
1
+ // 渲染App.vue,通过模板匹配pinia的使用情况
2
+ import ejs from 'ejs'
3
+ import { templatePath } from '#utils/URL.js'
4
+ import fs from 'fs-extra'
5
+ import path from 'path'
6
+
7
+ const addAppVue = async (projectName, usePinia, usePiniaPluginPersistedstate) => {
8
+ await fs.writeFile(
9
+ path.join(process.cwd(), projectName, 'src', 'App.vue'),
10
+ ejs.render(await fs.readFile(path.join(templatePath, 'base', 'src', 'App.vue.ejs'), 'utf-8'), {
11
+ usePinia,
12
+ usePiniaPluginPersistedstate,
13
+ }),
14
+ )
15
+ await fs.remove(path.join(process.cwd(), projectName, 'src', 'App.vue.ejs'))
16
+ }
17
+
18
+ export default addAppVue
@@ -1,22 +1,16 @@
1
1
  // 获取base模板
2
2
  import path from 'path'
3
- import { templatePath } from '../URL.js'
3
+ import { templatePath } from '#utils/URL.js'
4
4
  import fs from 'fs-extra'
5
- import confirmPathExists from '../pathExists.js'
6
-
7
- const basePath = path.join(templatePath, 'base')
8
5
 
9
6
  const createBaseProject = async (projectName) => {
7
+ const basePath = path.join(templatePath, 'base')
10
8
  const projectDir = path.join(process.cwd(), projectName)
11
- // 确认路径存在
12
- await confirmPathExists(projectName, projectDir)
13
9
  // 复制模板文件到目标目录
14
10
  fs.copySync(basePath, projectDir)
15
- // 读取package.json文件路径
11
+
16
12
  const packageJsonPath = path.join(projectDir, 'package.json')
17
- // 读取package.json内容
18
13
  const packageJson = await fs.readJson(packageJsonPath)
19
- // 修改name字段
20
14
  packageJson.name = projectName
21
15
  // 写回package.json文件
22
16
  await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 })
@@ -0,0 +1,18 @@
1
+ // 渲染main.js,通过模板匹配pinia的使用情况
2
+ import ejs from 'ejs'
3
+ import { templatePath } from '#utils/URL.js'
4
+ import fs from 'fs-extra'
5
+ import path from 'path'
6
+
7
+ const addMain = async (projectName, usePinia, usePiniaPluginPersistedstate) => {
8
+ await fs.writeFile(
9
+ path.join(process.cwd(), projectName, 'src', 'main.js'),
10
+ ejs.render(await fs.readFile(path.join(templatePath, 'base', 'src', 'main.js.ejs'), 'utf-8'), {
11
+ usePinia,
12
+ usePiniaPluginPersistedstate,
13
+ }),
14
+ )
15
+ await fs.remove(path.join(process.cwd(), projectName, 'src', 'main.js.ejs'))
16
+ }
17
+
18
+ export default addMain
@@ -1,10 +1,9 @@
1
1
  // 添加Eslint功能
2
2
  import path from 'path'
3
3
  import fs from 'fs-extra'
4
- import { templatePath } from '../URL.js'
4
+ import { templatePath } from '../../URL.js'
5
5
 
6
6
  // TODO: 优化变量名长度,提高可读性
7
- // TODO: 文件的变量名不要path
8
7
  const addEslint = async (projectName, flag) => {
9
8
  // 没有选择Eslint则直接返回
10
9
  if (!flag) return
@@ -1,7 +1,7 @@
1
1
  // 渲染eslint.config.js文件
2
2
  // 通过模板匹配prettier的选择情况
3
3
  import ejs from 'ejs'
4
- import { relativePath } from '../../../utils/URL.js'
4
+ import { templatePath } from '#utils/URL.js'
5
5
  import fs from 'fs-extra'
6
6
  import path from 'path'
7
7
 
@@ -10,7 +10,7 @@ const addEslintConfig = async (projectName, usePrettier, flag) => {
10
10
  await fs.writeFile(
11
11
  path.join(process.cwd(), projectName, 'eslint.config.js'),
12
12
  ejs.render(
13
- await fs.readFile(relativePath(import.meta.url, './eslint.config.js.ejs'), 'utf-8'),
13
+ await fs.readFile(path.join(templatePath, 'eslint', 'eslint.config.js.ejs'), 'utf-8'),
14
14
  { usePrettier },
15
15
  ),
16
16
  )
@@ -0,0 +1,25 @@
1
+ // 添加pinia功能
2
+ import path from 'path'
3
+ import fs from 'fs-extra'
4
+ import { templatePath } from '#utils/URL.js'
5
+
6
+ const addPinia = async (projectName, flag) => {
7
+ if (!flag) return
8
+ const targetPkg = fs.readJsonSync(path.join(process.cwd(), projectName, 'package.json'))
9
+ const piniaPkg = fs.readJsonSync(path.join(templatePath, 'pinia', 'package.json'))
10
+
11
+ // package.json的配置
12
+ targetPkg.dependencies = {
13
+ ...targetPkg.dependencies,
14
+ ...piniaPkg.dependencies,
15
+ }
16
+
17
+ fs.writeJSONSync(path.join(process.cwd(), projectName, 'package.json'), targetPkg, { spaces: 2 })
18
+
19
+ fs.copySync(
20
+ path.join(templatePath, 'pinia', 'counter.js'),
21
+ path.join(process.cwd(), projectName, 'src', 'stores', 'counter.js'),
22
+ )
23
+ }
24
+
25
+ export default addPinia
@@ -0,0 +1,27 @@
1
+ // 添加pinia自动持久化功能
2
+ import fs from 'fs-extra'
3
+ import path from 'path'
4
+ import { templatePath } from '#utils/URL.js'
5
+
6
+ const addPiniaPluginPersistedstate = async (projectName, flag) => {
7
+ if (!flag) return
8
+ const targetPkg = fs.readJsonSync(path.join(process.cwd(), projectName, 'package.json'))
9
+ const persistPkg = fs.readJsonSync(
10
+ path.join(templatePath, 'pinia', 'pinia-plugin-persistedstate', 'package.json'),
11
+ )
12
+
13
+ // package.json的配置
14
+ targetPkg.dependencies = {
15
+ ...targetPkg.dependencies,
16
+ ...persistPkg.dependencies,
17
+ }
18
+
19
+ fs.writeJSONSync(path.join(process.cwd(), projectName, 'package.json'), targetPkg, { spaces: 2 })
20
+
21
+ fs.copySync(
22
+ path.join(templatePath, 'pinia', 'pinia-plugin-persistedstate', 'key.js'),
23
+ path.join(process.cwd(), projectName, 'src', 'stores', 'key.js'),
24
+ )
25
+ }
26
+
27
+ export default addPiniaPluginPersistedstate
@@ -2,16 +2,16 @@ import { templatePath } from '../URL.js'
2
2
  import path from 'path'
3
3
  import fs from 'fs-extra'
4
4
 
5
- const addPrettier = async (projectName, useEslint, flag) => {
5
+ const addPrettier = async (projectName, flag) => {
6
6
  // 没有选择Prettier则直接返回
7
7
  if (!flag) return
8
8
  // 路径
9
9
  const templatePrettierPath = path.join(templatePath, 'prettier')
10
10
  const targetPath = path.join(process.cwd(), projectName)
11
- const targetPackageJson = path.join(targetPath, 'package.json')
11
+ const targetPackageJsonPath = path.join(targetPath, 'package.json')
12
12
 
13
13
  // 文件
14
- const targetPkg = await fs.readJson(targetPackageJson)
14
+ const targetPkg = await fs.readJson(targetPackageJsonPath)
15
15
  const prettierPkg = await fs.readJson(path.join(templatePrettierPath, 'package.json'))
16
16
 
17
17
  // 添加package.json的内容
@@ -25,12 +25,11 @@ const addPrettier = async (projectName, useEslint, flag) => {
25
25
  ...prettierPkg.devDependencies,
26
26
  }
27
27
 
28
- await fs.writeJson(targetPackageJson, targetPkg, { spaces: 2 })
28
+ await fs.writeJson(targetPackageJsonPath, targetPkg, { spaces: 2 })
29
29
 
30
30
  // 复制.prettierignore文件
31
- const prettierignore = path.join(templatePrettierPath, '.prettierignore')
32
- fs.copy(prettierignore, path.join(targetPath, '.prettierignore'))
33
-
31
+ const prettierignorePath = path.join(templatePrettierPath, '.prettierignore')
32
+ fs.copy(prettierignorePath, path.join(targetPath, '.prettierignore'))
34
33
  // 复制.prettierrc.js文件
35
34
  const prettierrc = path.join(templatePrettierPath, '.prettierrc')
36
35
  fs.copy(prettierrc, path.join(targetPath, '.prettierrc.js'))
@@ -1,47 +0,0 @@
1
- <script setup>
2
- import HelloWorld from './components/HelloWorld.vue'
3
- import TheWelcome from './components/TheWelcome.vue'
4
- </script>
5
-
6
- <template>
7
- <header>
8
- <img alt="Vue logo" class="logo" src="./assets/logo.svg" width="125" height="125" />
9
-
10
- <div class="wrapper">
11
- <HelloWorld msg="You did it!" />
12
- </div>
13
- </header>
14
-
15
- <main>
16
- <TheWelcome />
17
- </main>
18
- </template>
19
-
20
- <style scoped>
21
- header {
22
- line-height: 1.5;
23
- }
24
-
25
- .logo {
26
- display: block;
27
- margin: 0 auto 2rem;
28
- }
29
-
30
- @media (min-width: 1024px) {
31
- header {
32
- display: flex;
33
- place-items: center;
34
- padding-right: calc(var(--section-gap) / 2);
35
- }
36
-
37
- .logo {
38
- margin: 0 2rem 0 0;
39
- }
40
-
41
- header .wrapper {
42
- display: flex;
43
- place-items: flex-start;
44
- flex-wrap: wrap;
45
- }
46
- }
47
- </style>
@@ -1,6 +0,0 @@
1
- import './assets/main.css'
2
-
3
- import { createApp } from 'vue'
4
- import App from './App.vue'
5
-
6
- createApp(App).mount('#app')