create-vue 3.0.0-alpha.2 → 3.0.0-beta.10

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.
Files changed (94) hide show
  1. package/README.md +6 -0
  2. package/outfile.cjs +5712 -0
  3. package/package.json +21 -12
  4. package/template/base/package.json +4 -6
  5. package/template/base/vite.config.js +3 -1
  6. package/template/code/default/cypress/integration/example.spec.js +1 -1
  7. package/template/code/default/src/App.vue +73 -14
  8. package/template/code/default/src/assets/base.css +74 -0
  9. package/template/code/default/src/assets/logo.svg +1 -0
  10. package/template/code/default/src/components/HelloWorld.vue +28 -41
  11. package/template/code/default/src/components/TheWelcome.vue +84 -0
  12. package/template/code/default/src/components/WelcomeItem.vue +86 -0
  13. package/template/code/default/src/components/__tests__/HelloWorld.spec.js +0 -9
  14. package/template/code/default/src/components/icons/IconCommunity.vue +7 -0
  15. package/template/code/default/src/components/icons/IconDocumentation.vue +7 -0
  16. package/template/code/default/src/components/icons/IconEcosystem.vue +7 -0
  17. package/template/code/default/src/components/icons/IconSupport.vue +7 -0
  18. package/template/code/default/src/components/icons/IconTooling.vue +19 -0
  19. package/template/code/router/cypress/integration/example.spec.js +1 -1
  20. package/template/code/router/src/App.vue +103 -15
  21. package/template/code/router/src/assets/base.css +74 -0
  22. package/template/code/router/src/assets/logo.svg +1 -0
  23. package/template/code/router/src/components/HelloWorld.vue +28 -41
  24. package/template/code/router/src/components/TheWelcome.vue +84 -0
  25. package/template/code/router/src/components/WelcomeItem.vue +86 -0
  26. package/template/code/router/src/components/__tests__/HelloWorld.spec.js +0 -9
  27. package/template/code/router/src/components/icons/IconCommunity.vue +7 -0
  28. package/template/code/router/src/components/icons/IconDocumentation.vue +7 -0
  29. package/template/code/router/src/components/icons/IconEcosystem.vue +7 -0
  30. package/template/code/router/src/components/icons/IconSupport.vue +7 -0
  31. package/template/code/router/src/components/icons/IconTooling.vue +19 -0
  32. package/template/code/router/src/router/index.js +16 -18
  33. package/template/code/router/src/views/AboutView.vue +15 -0
  34. package/template/code/router/src/views/HomeView.vue +9 -0
  35. package/template/code/typescript-default/cypress/integration/example.spec.ts +1 -1
  36. package/template/code/typescript-default/src/App.vue +73 -11
  37. package/template/code/typescript-default/src/assets/base.css +74 -0
  38. package/template/code/typescript-default/src/assets/logo.svg +1 -0
  39. package/template/code/typescript-default/src/components/HelloWorld.vue +29 -42
  40. package/template/code/typescript-default/src/components/TheWelcome.vue +84 -0
  41. package/template/code/typescript-default/src/components/WelcomeItem.vue +86 -0
  42. package/template/code/typescript-default/src/components/__tests__/HelloWorld.spec.ts +0 -9
  43. package/template/code/typescript-default/src/components/icons/IconCommunity.vue +7 -0
  44. package/template/code/typescript-default/src/components/icons/IconDocumentation.vue +7 -0
  45. package/template/code/typescript-default/src/components/icons/IconEcosystem.vue +7 -0
  46. package/template/code/typescript-default/src/components/icons/IconSupport.vue +7 -0
  47. package/template/code/typescript-default/src/components/icons/IconTooling.vue +19 -0
  48. package/template/code/typescript-router/cypress/integration/example.spec.ts +1 -1
  49. package/template/code/typescript-router/src/App.vue +103 -15
  50. package/template/code/typescript-router/src/assets/base.css +74 -0
  51. package/template/code/typescript-router/src/assets/logo.svg +1 -0
  52. package/template/code/typescript-router/src/components/HelloWorld.vue +29 -42
  53. package/template/code/typescript-router/src/components/TheWelcome.vue +84 -0
  54. package/template/code/typescript-router/src/components/WelcomeItem.vue +86 -0
  55. package/template/code/typescript-router/src/components/__tests__/HelloWorld.spec.ts +0 -9
  56. package/template/code/typescript-router/src/components/icons/IconCommunity.vue +7 -0
  57. package/template/code/typescript-router/src/components/icons/IconDocumentation.vue +7 -0
  58. package/template/code/typescript-router/src/components/icons/IconEcosystem.vue +7 -0
  59. package/template/code/typescript-router/src/components/icons/IconSupport.vue +7 -0
  60. package/template/code/typescript-router/src/components/icons/IconTooling.vue +19 -0
  61. package/template/code/typescript-router/src/router/index.ts +16 -20
  62. package/template/code/typescript-router/src/views/AboutView.vue +15 -0
  63. package/template/code/typescript-router/src/views/HomeView.vue +9 -0
  64. package/template/config/cypress/package.json +6 -6
  65. package/template/config/jsx/package.json +1 -1
  66. package/template/config/jsx/vite.config.js +3 -1
  67. package/template/config/pinia/package.json +5 -0
  68. package/template/config/pinia/src/stores/counter.js +16 -0
  69. package/template/config/router/package.json +1 -1
  70. package/template/{base/vite-env.d.ts → config/typescript/env.d.ts} +0 -0
  71. package/template/config/typescript/package.json +3 -2
  72. package/template/{base/jsconfig.json → config/typescript/tsconfig.json} +2 -2
  73. package/template/{code/router → entry/pinia}/src/main.js +2 -2
  74. package/template/entry/{vuex-and-router → router-and-pinia}/src/main.js +3 -3
  75. package/index.js +0 -332
  76. package/template/code/default/src/assets/logo.png +0 -0
  77. package/template/code/default/src/main.js +0 -4
  78. package/template/code/router/src/assets/logo.png +0 -0
  79. package/template/code/router/src/views/About.vue +0 -5
  80. package/template/code/router/src/views/Home.vue +0 -19
  81. package/template/code/typescript-default/src/assets/logo.png +0 -0
  82. package/template/code/typescript-default/src/main.ts +0 -4
  83. package/template/code/typescript-router/src/assets/logo.png +0 -0
  84. package/template/code/typescript-router/src/views/About.vue +0 -5
  85. package/template/code/typescript-router/src/views/Home.vue +0 -19
  86. package/template/config/cypress/cypress/.DS_Store +0 -0
  87. package/template/entry/vuex/src/main.js +0 -9
  88. package/utils/deepMerge.js +0 -26
  89. package/utils/directoryTraverse.js +0 -29
  90. package/utils/docs/README-TEMPLATE.md +0 -17
  91. package/utils/docs/SFC-TYPE-SUPPORT.md +0 -5
  92. package/utils/generateReadme.js +0 -69
  93. package/utils/getCommand.js +0 -7
  94. package/utils/renderTemplate.js +0 -47
package/index.js DELETED
@@ -1,332 +0,0 @@
1
- #!/usr/bin/env node
2
- // @ts-check
3
-
4
- import fs from 'fs'
5
- import path from 'path'
6
-
7
- import minimist from 'minimist'
8
- import prompts from 'prompts'
9
- import { red, green, bold } from 'kolorist'
10
-
11
- import renderTemplate from './utils/renderTemplate.js'
12
- import {
13
- postOrderDirectoryTraverse,
14
- preOrderDirectoryTraverse
15
- } from './utils/directoryTraverse.js'
16
- import generateReadme from './utils/generateReadme.js'
17
- import getCommand from './utils/getCommand.js'
18
-
19
- function isValidPackageName(projectName) {
20
- return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(
21
- projectName
22
- )
23
- }
24
-
25
- function toValidPackageName(projectName) {
26
- return projectName
27
- .trim()
28
- .toLowerCase()
29
- .replace(/\s+/g, '-')
30
- .replace(/^[._]/, '')
31
- .replace(/[^a-z0-9-~]+/g, '-')
32
- }
33
-
34
- function canSafelyOverwrite(dir) {
35
- return !fs.existsSync(dir) || fs.readdirSync(dir).length === 0
36
- }
37
-
38
- function emptyDir(dir) {
39
- postOrderDirectoryTraverse(
40
- dir,
41
- (dir) => fs.rmdirSync(dir),
42
- (file) => fs.unlinkSync(file)
43
- )
44
- }
45
-
46
- async function init() {
47
- const cwd = process.cwd()
48
- // possible options:
49
- // --default
50
- // --typescript / --ts
51
- // --jsx
52
- // --router / --vue-router
53
- // --vuex
54
- // --with-tests / --tests / --cypress
55
- // --force (for force overwriting)
56
- const argv = minimist(process.argv.slice(2), {
57
- alias: {
58
- typescript: ['ts'],
59
- 'with-tests': ['tests', 'cypress'],
60
- router: ['vue-router']
61
- },
62
- // all arguments are treated as booleans
63
- boolean: true
64
- })
65
-
66
- // if any of the feature flags is set, we would skip the feature prompts
67
- // use `??` instead of `||` once we drop Node.js 12 support
68
- const isFeatureFlagsUsed =
69
- typeof (
70
- argv.default ||
71
- argv.ts ||
72
- argv.jsx ||
73
- argv.router ||
74
- argv.vuex ||
75
- argv.tests
76
- ) === 'boolean'
77
-
78
- let targetDir = argv._[0]
79
- const defaultProjectName = !targetDir ? 'vue-project' : targetDir
80
-
81
- const forceOverwrite = argv.force
82
-
83
- let result = {}
84
-
85
- try {
86
- // Prompts:
87
- // - Project name:
88
- // - whether to overwrite the existing directory or not?
89
- // - enter a valid package name for package.json
90
- // - Project language: JavaScript / TypeScript
91
- // - Add JSX Support?
92
- // - Install Vue Router for SPA development?
93
- // - Install Vuex for state management? (TODO)
94
- // - Add Cypress for testing?
95
- result = await prompts(
96
- [
97
- {
98
- name: 'projectName',
99
- type: targetDir ? null : 'text',
100
- message: 'Project name:',
101
- initial: defaultProjectName,
102
- onState: (state) =>
103
- (targetDir = String(state.value).trim() || defaultProjectName)
104
- },
105
- {
106
- name: 'shouldOverwrite',
107
- type: () =>
108
- canSafelyOverwrite(targetDir) || forceOverwrite ? null : 'confirm',
109
- message: () => {
110
- const dirForPrompt =
111
- targetDir === '.'
112
- ? 'Current directory'
113
- : `Target directory "${targetDir}"`
114
-
115
- return `${dirForPrompt} is not empty. Remove existing files and continue?`
116
- }
117
- },
118
- {
119
- name: 'overwriteChecker',
120
- type: (prev, values = {}) => {
121
- if (values.shouldOverwrite === false) {
122
- throw new Error(red('✖') + ' Operation cancelled')
123
- }
124
- return null
125
- }
126
- },
127
- {
128
- name: 'packageName',
129
- type: () => (isValidPackageName(targetDir) ? null : 'text'),
130
- message: 'Package name:',
131
- initial: () => toValidPackageName(targetDir),
132
- validate: (dir) =>
133
- isValidPackageName(dir) || 'Invalid package.json name'
134
- },
135
- {
136
- name: 'needsTypeScript',
137
- type: () => (isFeatureFlagsUsed ? null : 'toggle'),
138
- message: 'Add TypeScript?',
139
- initial: false,
140
- active: 'Yes',
141
- inactive: 'No'
142
- },
143
- {
144
- name: 'needsJsx',
145
- type: () => (isFeatureFlagsUsed ? null : 'toggle'),
146
- message: 'Add JSX Support?',
147
- initial: false,
148
- active: 'Yes',
149
- inactive: 'No'
150
- },
151
- {
152
- name: 'needsRouter',
153
- type: () => (isFeatureFlagsUsed ? null : 'toggle'),
154
- message: 'Add Vue Router for Single Page Application development?',
155
- initial: false,
156
- active: 'Yes',
157
- inactive: 'No'
158
- },
159
- {
160
- name: 'needsVuex',
161
- type: () => (isFeatureFlagsUsed ? null : 'toggle'),
162
- message: 'Add Vuex for state management?',
163
- initial: false,
164
- active: 'Yes',
165
- inactive: 'No'
166
- },
167
- {
168
- name: 'needsTests',
169
- type: () => (isFeatureFlagsUsed ? null : 'toggle'),
170
- message: 'Add Cypress for testing?',
171
- initial: false,
172
- active: 'Yes',
173
- inactive: 'No'
174
- }
175
- ],
176
- {
177
- onCancel: () => {
178
- throw new Error(red('✖') + ' Operation cancelled')
179
- }
180
- }
181
- )
182
- } catch (cancelled) {
183
- console.log(cancelled.message)
184
- process.exit(1)
185
- }
186
-
187
- // `initial` won't take effect if the prompt type is null
188
- // so we still have to assign the default values here
189
- const {
190
- packageName = toValidPackageName(defaultProjectName),
191
- shouldOverwrite,
192
- needsJsx = argv.jsx,
193
- needsTypeScript = argv.typescript,
194
- needsRouter = argv.router,
195
- needsVuex = argv.vuex,
196
- needsTests = argv.tests
197
- } = result
198
- const root = path.join(cwd, targetDir)
199
-
200
- if (shouldOverwrite) {
201
- emptyDir(root)
202
- } else if (!fs.existsSync(root)) {
203
- fs.mkdirSync(root)
204
- }
205
-
206
- console.log(`\nScaffolding project in ${root}...`)
207
-
208
- const pkg = { name: packageName, version: '0.0.0' }
209
- fs.writeFileSync(
210
- path.resolve(root, 'package.json'),
211
- JSON.stringify(pkg, null, 2)
212
- )
213
-
214
- const templateRoot = new URL('./template', import.meta.url).pathname
215
- const render = function render(templateName) {
216
- const templateDir = path.resolve(templateRoot, templateName)
217
- renderTemplate(templateDir, root)
218
- }
219
-
220
- // Render base template
221
- render('base')
222
-
223
- // Add configs.
224
- if (needsJsx) {
225
- render('config/jsx')
226
- }
227
- if (needsRouter) {
228
- render('config/router')
229
- }
230
- if (needsVuex) {
231
- render('config/vuex')
232
- }
233
- if (needsTests) {
234
- render('config/cypress')
235
- }
236
- if (needsTypeScript) {
237
- render('config/typescript')
238
- }
239
-
240
- // Render code template.
241
- // prettier-ignore
242
- const codeTemplate =
243
- (needsTypeScript ? 'typescript-' : '') +
244
- (needsRouter ? 'router' : 'default')
245
- render(`code/${codeTemplate}`)
246
-
247
- // Render entry file (main.js/ts).
248
- if (needsVuex && needsRouter) {
249
- render('entry/vuex-and-router')
250
- } else if (needsVuex) {
251
- render('entry/vuex')
252
- } else if (needsRouter) {
253
- render('entry/router')
254
- } else {
255
- render('entry/default')
256
- }
257
-
258
- // Cleanup.
259
-
260
- if (needsTypeScript) {
261
- // rename all `.js` files to `.ts`
262
- // rename jsconfig.json to tsconfig.json
263
- preOrderDirectoryTraverse(
264
- root,
265
- () => {},
266
- (filepath) => {
267
- if (filepath.endsWith('.js')) {
268
- fs.renameSync(filepath, filepath.replace(/\.js$/, '.ts'))
269
- } else if (path.basename(filepath) === 'jsconfig.json') {
270
- fs.renameSync(
271
- filepath,
272
- filepath.replace(/jsconfig\.json$/, 'tsconfig.json')
273
- )
274
- }
275
- }
276
- )
277
-
278
- // Rename entry in `index.html`
279
- const indexHtmlPath = path.resolve(root, 'index.html')
280
- const indexHtmlContent = fs.readFileSync(indexHtmlPath, 'utf8')
281
- fs.writeFileSync(
282
- indexHtmlPath,
283
- indexHtmlContent.replace('src/main.js', 'src/main.ts')
284
- )
285
- }
286
-
287
- if (!needsTests) {
288
- // All templates assumes the need of tests.
289
- // If the user doesn't need it:
290
- // rm -rf cypress **/__tests__/
291
- preOrderDirectoryTraverse(
292
- root,
293
- (dirpath) => {
294
- const dirname = path.basename(dirpath)
295
-
296
- if (dirname === 'cypress' || dirname === '__tests__') {
297
- emptyDir(dirpath)
298
- fs.rmdirSync(dirpath)
299
- }
300
- },
301
- () => {}
302
- )
303
- }
304
-
305
- // Instructions:
306
- // Supported package managers: pnpm > yarn > npm
307
- const packageManager = /pnpm/.test(process.env.npm_execpath)
308
- ? 'pnpm'
309
- : /yarn/.test(process.env.npm_execpath)
310
- ? 'yarn'
311
- : 'npm'
312
-
313
- // README generation
314
- fs.writeFileSync(path.resolve(root, 'README.md'), generateReadme({
315
- projectName: result.projectName || defaultProjectName,
316
- packageManager,
317
- needsTypeScript,
318
- needsTests
319
- }))
320
-
321
- console.log(`\nDone. Now run:\n`)
322
- if (root !== cwd) {
323
- console.log(` ${bold(green(`cd ${path.relative(cwd, root)}`))}`)
324
- }
325
- console.log(` ${bold(green(getCommand(packageManager, 'install')))}`)
326
- console.log(` ${bold(green(getCommand(packageManager, 'dev')))}`)
327
- console.log()
328
- }
329
-
330
- init().catch((e) => {
331
- console.error(e)
332
- })
@@ -1,4 +0,0 @@
1
- import { createApp } from 'vue'
2
- import App from './App.vue'
3
-
4
- createApp(App).mount('#app')
@@ -1,5 +0,0 @@
1
- <template>
2
- <div class="about">
3
- <h1>This is an about page</h1>
4
- </div>
5
- </template>
@@ -1,19 +0,0 @@
1
- <template>
2
- <img alt="Vue logo" src="@/assets/logo.png" />
3
- <HelloWorld msg="Hello Vue 3 + Vite" />
4
- </template>
5
-
6
- <script setup>
7
- import HelloWorld from '@/components/HelloWorld.vue'
8
- </script>
9
-
10
- <style>
11
- #app {
12
- font-family: Avenir, Helvetica, Arial, sans-serif;
13
- -webkit-font-smoothing: antialiased;
14
- -moz-osx-font-smoothing: grayscale;
15
- text-align: center;
16
- color: #2c3e50;
17
- margin-top: 60px;
18
- }
19
- </style>
@@ -1,4 +0,0 @@
1
- import { createApp } from 'vue'
2
- import App from './App.vue'
3
-
4
- createApp(App).mount('#app')
@@ -1,5 +0,0 @@
1
- <template>
2
- <div class="about">
3
- <h1>This is an about page</h1>
4
- </div>
5
- </template>
@@ -1,19 +0,0 @@
1
- <template>
2
- <img alt="Vue logo" src="@/assets/logo.png" />
3
- <HelloWorld msg="Hello Vue 3 + TypeScript + Vite" />
4
- </template>
5
-
6
- <script setup lang="ts">
7
- import HelloWorld from '@/components/HelloWorld.vue'
8
- </script>
9
-
10
- <style>
11
- #app {
12
- font-family: Avenir, Helvetica, Arial, sans-serif;
13
- -webkit-font-smoothing: antialiased;
14
- -moz-osx-font-smoothing: grayscale;
15
- text-align: center;
16
- color: #2c3e50;
17
- margin-top: 60px;
18
- }
19
- </style>
@@ -1,9 +0,0 @@
1
- import { createApp } from 'vue'
2
- import App from './App.vue'
3
- import store from './store'
4
-
5
- const app = createApp(App)
6
-
7
- app.use(store)
8
-
9
- app.mount('#app')
@@ -1,26 +0,0 @@
1
- const isObject = (val) => val && typeof val === 'object'
2
- const mergeArrayWithDedupe = (a, b) => Array.from(new Set([...a, ...b]))
3
-
4
- /**
5
- * Recursively merge the content of the new object to the existing one
6
- * @param {Object} target the existing object
7
- * @param {Object} obj the new object
8
- */
9
- function deepMerge(target, obj) {
10
- for (const key of Object.keys(obj)) {
11
- const oldVal = target[key]
12
- const newVal = obj[key]
13
-
14
- if (Array.isArray(oldVal) && Array.isArray(newVal)) {
15
- target[key] = mergeArrayWithDedupe(oldVal, newVal)
16
- } else if (isObject(oldVal) && isObject(newVal)) {
17
- target[key] = deepMerge(oldVal, newVal)
18
- } else {
19
- target[key] = newVal
20
- }
21
- }
22
-
23
- return target
24
- }
25
-
26
- export default deepMerge
@@ -1,29 +0,0 @@
1
- import fs from 'fs'
2
- import path from 'path'
3
-
4
- export function preOrderDirectoryTraverse(dir, dirCallback, fileCallback) {
5
- for (const filename of fs.readdirSync(dir)) {
6
- const fullpath = path.resolve(dir, filename)
7
- if (fs.lstatSync(fullpath).isDirectory()) {
8
- dirCallback(fullpath)
9
- // in case the dirCallback removes the directory entirely
10
- if (fs.existsSync(fullpath)) {
11
- preOrderDirectoryTraverse(fullpath, dirCallback, fileCallback)
12
- }
13
- continue
14
- }
15
- fileCallback(fullpath)
16
- }
17
- }
18
-
19
- export function postOrderDirectoryTraverse(dir, dirCallback, fileCallback) {
20
- for (const filename of fs.readdirSync(dir)) {
21
- const fullpath = path.resolve(dir, filename)
22
- if (fs.lstatSync(fullpath).isDirectory()) {
23
- postOrderDirectoryTraverse(fullpath, dirCallback, fileCallback)
24
- dirCallback(fullpath)
25
- continue
26
- }
27
- fileCallback(fullpath)
28
- }
29
- }
@@ -1,17 +0,0 @@
1
- # {{projectName}}
2
-
3
- This template should help get you started developing with Vue 3 in Vite.
4
-
5
- ## Recommended IDE Setup
6
-
7
- [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=johnsoncodehk.volar) (and disable Vetur).
8
-
9
- <!-- SFC-TYPE-SUPPORT -->
10
-
11
- ## Customize configuration
12
-
13
- See [Vite Configuration Reference](https://vitejs.dev/config/).
14
-
15
- ## Project Setup
16
-
17
- <!-- NPM-SCRIPTS -->
@@ -1,5 +0,0 @@
1
- ## Type Support for `.vue` Imports in TS
2
-
3
- Since TypeScript cannot handle type information for `.vue` imports, they are shimmed to be a generic Vue component type by default. In most cases this is fine if you don't really care about component prop types outside of templates.
4
-
5
- However, if you wish to get actual prop types in `.vue` imports (for example to get props validation when using manual `h(...)` calls), you can run `Volar: Switch TS Plugin on/off` from VSCode command palette.
@@ -1,69 +0,0 @@
1
- import fs from 'fs'
2
-
3
- import getCommand from './getCommand.js'
4
-
5
- const sfcTypeSupportDoc = fs.readFileSync(
6
- new URL('./docs/SFC-TYPE-SUPPORT.md', import.meta.url).pathname,
7
- 'utf8'
8
- )
9
-
10
- export default function generateReadme({
11
- projectName,
12
- packageManager,
13
- needsTypeScript,
14
- needsTests
15
- }) {
16
- let template = fs.readFileSync(
17
- new URL('./docs/README-TEMPLATE.md', import.meta.url).pathname,
18
- 'utf8'
19
- )
20
-
21
- template = template.replace('{{projectName}}', projectName)
22
-
23
- if (needsTypeScript) {
24
- template = template.replace('<!-- SFC-TYPE-SUPPORT -->\n', sfcTypeSupportDoc)
25
- } else {
26
- template = template.replace('<!-- SFC-TYPE-SUPPORT -->\n\n', '')
27
- }
28
-
29
- let npmScriptsDescriptions =
30
- `\`\`\`sh
31
- ${getCommand(packageManager, 'install')}
32
- \`\`\`
33
-
34
- ### Compile and Hot-Reload for Development
35
-
36
- \`\`\`sh
37
- ${getCommand(packageManager, 'dev')}
38
- \`\`\`
39
-
40
- ### ${needsTypeScript ? 'Type-Check, ' : ''}Compile and Minify for Production
41
-
42
- \`\`\`sh
43
- ${getCommand(packageManager, 'build')}
44
- \`\`\`
45
- `
46
-
47
- if (needsTests) {
48
- npmScriptsDescriptions +=`
49
- ### Run Unit Tests with [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/introduction)
50
-
51
- \`\`\`sh
52
- ${getCommand(packageManager, 'test:unit')} # or \`${getCommand(packageManager, 'test:unit:ci')}\` for headless testing
53
- \`\`\`
54
-
55
- ### Run End-to-End Tests with [Cypress](https://www.cypress.io/)
56
-
57
- \`\`\`sh
58
- ${getCommand(packageManager, 'test:e2e')} # or \`${getCommand(packageManager, 'test:e2e:ci')}\` for headless testing
59
- \`\`\`
60
- `
61
- }
62
-
63
- template = template.replace(
64
- '<!-- NPM-SCRIPTS -->\n',
65
- npmScriptsDescriptions
66
- )
67
-
68
- return template
69
- }
@@ -1,7 +0,0 @@
1
- export default function getCommand(packageManager, scriptName) {
2
- if (scriptName === 'install') {
3
- return packageManager === 'yarn' ? 'yarn': `${packageManager} install`
4
- }
5
-
6
- return packageManager === 'npm' ? `npm run ${scriptName}` : `${packageManager} ${scriptName}`
7
- }
@@ -1,47 +0,0 @@
1
- import fs from 'fs'
2
- import path from 'path'
3
-
4
- import deepMerge from './deepMerge.js'
5
-
6
- /**
7
- * Renders a template folder/file to the file system,
8
- * by recursively copying all files under the `src` directory,
9
- * with the following exception:
10
- * - `_filename` should be renamed to `.filename`
11
- * - Fields in `package.json` should be recursively merged
12
- * @param {string} src source filename to copy
13
- * @param {string} dest destination filename of the copy operation
14
- */
15
- function renderTemplate(src, dest) {
16
- const stats = fs.statSync(src)
17
-
18
- if (stats.isDirectory()) {
19
- // if it's a directory, render its subdirectories and files recusively
20
- fs.mkdirSync(dest, { recursive: true })
21
- for (const file of fs.readdirSync(src)) {
22
- renderTemplate(path.resolve(src, file), path.resolve(dest, file))
23
- }
24
- return
25
- }
26
-
27
- const filename = path.basename(src)
28
-
29
- if (filename === 'package.json' && fs.existsSync(dest)) {
30
- // merge instead of overwriting
31
- const pkg = deepMerge(
32
- JSON.parse(fs.readFileSync(dest)),
33
- JSON.parse(fs.readFileSync(src))
34
- )
35
- fs.writeFileSync(dest, JSON.stringify(pkg, null, 2) + '\n')
36
- return
37
- }
38
-
39
- if (filename.startsWith('_')) {
40
- // rename `_file` to `.file`
41
- dest = path.resolve(path.dirname(dest), filename.replace(/^_/, '.'))
42
- }
43
-
44
- fs.copyFileSync(src, dest)
45
- }
46
-
47
- export default renderTemplate