create-vue 3.0.0-beta.3 → 3.0.0-beta.7
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/outfile.cjs +163 -144
- package/package.json +6 -7
- package/template/base/package.json +4 -6
- package/template/base/vite.config.js +3 -1
- package/template/code/default/src/App.vue +2 -2
- package/template/code/default/src/components/{Welcome.vue → TheWelcome.vue} +0 -0
- package/template/code/router/src/App.vue +8 -8
- package/template/code/router/src/components/{Welcome.vue → TheWelcome.vue} +0 -0
- package/template/code/router/src/router/index.js +16 -18
- package/template/code/router/src/views/{About.vue → AboutView.vue} +0 -0
- package/template/code/router/src/views/{Home.vue → HomeView.vue} +2 -2
- package/template/code/typescript-default/src/App.vue +2 -2
- package/template/code/typescript-default/src/components/{Welcome.vue → TheWelcome.vue} +0 -0
- package/template/code/typescript-router/src/App.vue +8 -8
- package/template/code/typescript-router/src/components/{Welcome.vue → TheWelcome.vue} +0 -0
- package/template/code/typescript-router/src/router/index.ts +16 -20
- package/template/code/typescript-router/src/views/{About.vue → AboutView.vue} +0 -0
- package/template/code/typescript-router/src/views/{Home.vue → HomeView.vue} +2 -2
- package/template/config/cypress/package.json +5 -5
- package/template/config/jsx/package.json +1 -1
- package/template/config/jsx/vite.config.js +3 -1
- package/template/config/router/package.json +1 -1
- package/template/config/typescript/package.json +2 -2
- package/template/config/typescript/tsconfig.json +1 -0
- package/index.js +0 -316
package/index.js
DELETED
|
@@ -1,316 +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 { postOrderDirectoryTraverse, preOrderDirectoryTraverse } from './utils/directoryTraverse.js'
|
|
13
|
-
import generateReadme from './utils/generateReadme.js'
|
|
14
|
-
import getCommand from './utils/getCommand.js'
|
|
15
|
-
|
|
16
|
-
function isValidPackageName(projectName) {
|
|
17
|
-
return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(projectName)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function toValidPackageName(projectName) {
|
|
21
|
-
return projectName
|
|
22
|
-
.trim()
|
|
23
|
-
.toLowerCase()
|
|
24
|
-
.replace(/\s+/g, '-')
|
|
25
|
-
.replace(/^[._]/, '')
|
|
26
|
-
.replace(/[^a-z0-9-~]+/g, '-')
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function canSafelyOverwrite(dir) {
|
|
30
|
-
return !fs.existsSync(dir) || fs.readdirSync(dir).length === 0
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function emptyDir(dir) {
|
|
34
|
-
postOrderDirectoryTraverse(
|
|
35
|
-
dir,
|
|
36
|
-
(dir) => fs.rmdirSync(dir),
|
|
37
|
-
(file) => fs.unlinkSync(file)
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async function init() {
|
|
42
|
-
const cwd = process.cwd()
|
|
43
|
-
// possible options:
|
|
44
|
-
// --default
|
|
45
|
-
// --typescript / --ts
|
|
46
|
-
// --jsx
|
|
47
|
-
// --router / --vue-router
|
|
48
|
-
// --vuex
|
|
49
|
-
// --with-tests / --tests / --cypress
|
|
50
|
-
// --force (for force overwriting)
|
|
51
|
-
const argv = minimist(process.argv.slice(2), {
|
|
52
|
-
alias: {
|
|
53
|
-
typescript: ['ts'],
|
|
54
|
-
'with-tests': ['tests', 'cypress'],
|
|
55
|
-
router: ['vue-router']
|
|
56
|
-
},
|
|
57
|
-
// all arguments are treated as booleans
|
|
58
|
-
boolean: true
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
// if any of the feature flags is set, we would skip the feature prompts
|
|
62
|
-
// use `??` instead of `||` once we drop Node.js 12 support
|
|
63
|
-
const isFeatureFlagsUsed =
|
|
64
|
-
typeof (argv.default || argv.ts || argv.jsx || argv.router || argv.vuex || argv.tests) ===
|
|
65
|
-
'boolean'
|
|
66
|
-
|
|
67
|
-
let targetDir = argv._[0]
|
|
68
|
-
const defaultProjectName = !targetDir ? 'vue-project' : targetDir
|
|
69
|
-
|
|
70
|
-
const forceOverwrite = argv.force
|
|
71
|
-
|
|
72
|
-
let result = {}
|
|
73
|
-
|
|
74
|
-
try {
|
|
75
|
-
// Prompts:
|
|
76
|
-
// - Project name:
|
|
77
|
-
// - whether to overwrite the existing directory or not?
|
|
78
|
-
// - enter a valid package name for package.json
|
|
79
|
-
// - Project language: JavaScript / TypeScript
|
|
80
|
-
// - Add JSX Support?
|
|
81
|
-
// - Install Vue Router for SPA development?
|
|
82
|
-
// - Install Vuex for state management? (TODO)
|
|
83
|
-
// - Add Cypress for testing?
|
|
84
|
-
result = await prompts(
|
|
85
|
-
[
|
|
86
|
-
{
|
|
87
|
-
name: 'projectName',
|
|
88
|
-
type: targetDir ? null : 'text',
|
|
89
|
-
message: 'Project name:',
|
|
90
|
-
initial: defaultProjectName,
|
|
91
|
-
onState: (state) => (targetDir = String(state.value).trim() || defaultProjectName)
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
name: 'shouldOverwrite',
|
|
95
|
-
type: () => (canSafelyOverwrite(targetDir) || forceOverwrite ? null : 'confirm'),
|
|
96
|
-
message: () => {
|
|
97
|
-
const dirForPrompt =
|
|
98
|
-
targetDir === '.' ? 'Current directory' : `Target directory "${targetDir}"`
|
|
99
|
-
|
|
100
|
-
return `${dirForPrompt} is not empty. Remove existing files and continue?`
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
name: 'overwriteChecker',
|
|
105
|
-
type: (prev, values = {}) => {
|
|
106
|
-
if (values.shouldOverwrite === false) {
|
|
107
|
-
throw new Error(red('✖') + ' Operation cancelled')
|
|
108
|
-
}
|
|
109
|
-
return null
|
|
110
|
-
}
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
name: 'packageName',
|
|
114
|
-
type: () => (isValidPackageName(targetDir) ? null : 'text'),
|
|
115
|
-
message: 'Package name:',
|
|
116
|
-
initial: () => toValidPackageName(targetDir),
|
|
117
|
-
validate: (dir) => isValidPackageName(dir) || 'Invalid package.json name'
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
name: 'needsTypeScript',
|
|
121
|
-
type: () => (isFeatureFlagsUsed ? null : 'toggle'),
|
|
122
|
-
message: 'Add TypeScript?',
|
|
123
|
-
initial: false,
|
|
124
|
-
active: 'Yes',
|
|
125
|
-
inactive: 'No'
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
name: 'needsJsx',
|
|
129
|
-
type: () => (isFeatureFlagsUsed ? null : 'toggle'),
|
|
130
|
-
message: 'Add JSX Support?',
|
|
131
|
-
initial: false,
|
|
132
|
-
active: 'Yes',
|
|
133
|
-
inactive: 'No'
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
name: 'needsRouter',
|
|
137
|
-
type: () => (isFeatureFlagsUsed ? null : 'toggle'),
|
|
138
|
-
message: 'Add Vue Router for Single Page Application development?',
|
|
139
|
-
initial: false,
|
|
140
|
-
active: 'Yes',
|
|
141
|
-
inactive: 'No'
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
name: 'needsVuex',
|
|
145
|
-
type: () => (isFeatureFlagsUsed ? null : 'toggle'),
|
|
146
|
-
message: 'Add Vuex for state management?',
|
|
147
|
-
initial: false,
|
|
148
|
-
active: 'Yes',
|
|
149
|
-
inactive: 'No'
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
name: 'needsTests',
|
|
153
|
-
type: () => (isFeatureFlagsUsed ? null : 'toggle'),
|
|
154
|
-
message: 'Add Cypress for testing?',
|
|
155
|
-
initial: false,
|
|
156
|
-
active: 'Yes',
|
|
157
|
-
inactive: 'No'
|
|
158
|
-
}
|
|
159
|
-
],
|
|
160
|
-
{
|
|
161
|
-
onCancel: () => {
|
|
162
|
-
throw new Error(red('✖') + ' Operation cancelled')
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
)
|
|
166
|
-
} catch (cancelled) {
|
|
167
|
-
console.log(cancelled.message)
|
|
168
|
-
process.exit(1)
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// `initial` won't take effect if the prompt type is null
|
|
172
|
-
// so we still have to assign the default values here
|
|
173
|
-
const {
|
|
174
|
-
packageName = toValidPackageName(defaultProjectName),
|
|
175
|
-
shouldOverwrite,
|
|
176
|
-
needsJsx = argv.jsx,
|
|
177
|
-
needsTypeScript = argv.typescript,
|
|
178
|
-
needsRouter = argv.router,
|
|
179
|
-
needsVuex = argv.vuex,
|
|
180
|
-
needsTests = argv.tests
|
|
181
|
-
} = result
|
|
182
|
-
const root = path.join(cwd, targetDir)
|
|
183
|
-
|
|
184
|
-
if (shouldOverwrite) {
|
|
185
|
-
emptyDir(root)
|
|
186
|
-
} else if (!fs.existsSync(root)) {
|
|
187
|
-
fs.mkdirSync(root)
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
console.log(`\nScaffolding project in ${root}...`)
|
|
191
|
-
|
|
192
|
-
const pkg = { name: packageName, version: '0.0.0' }
|
|
193
|
-
fs.writeFileSync(path.resolve(root, 'package.json'), JSON.stringify(pkg, null, 2))
|
|
194
|
-
|
|
195
|
-
// todo:
|
|
196
|
-
// work around the esbuild issue that `import.meta.url` cannot be correctly transpiled
|
|
197
|
-
// when bundling for node and the format is cjs
|
|
198
|
-
// const templateRoot = new URL('./template', import.meta.url).pathname
|
|
199
|
-
const templateRoot = path.resolve(__dirname, 'template')
|
|
200
|
-
const render = function render(templateName) {
|
|
201
|
-
const templateDir = path.resolve(templateRoot, templateName)
|
|
202
|
-
renderTemplate(templateDir, root)
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Render base template
|
|
206
|
-
render('base')
|
|
207
|
-
|
|
208
|
-
// Add configs.
|
|
209
|
-
if (needsJsx) {
|
|
210
|
-
render('config/jsx')
|
|
211
|
-
}
|
|
212
|
-
if (needsRouter) {
|
|
213
|
-
render('config/router')
|
|
214
|
-
}
|
|
215
|
-
if (needsVuex) {
|
|
216
|
-
render('config/vuex')
|
|
217
|
-
}
|
|
218
|
-
if (needsTests) {
|
|
219
|
-
render('config/cypress')
|
|
220
|
-
}
|
|
221
|
-
if (needsTypeScript) {
|
|
222
|
-
render('config/typescript')
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Render code template.
|
|
226
|
-
// prettier-ignore
|
|
227
|
-
const codeTemplate =
|
|
228
|
-
(needsTypeScript ? 'typescript-' : '') +
|
|
229
|
-
(needsRouter ? 'router' : 'default')
|
|
230
|
-
render(`code/${codeTemplate}`)
|
|
231
|
-
|
|
232
|
-
// Render entry file (main.js/ts).
|
|
233
|
-
if (needsVuex && needsRouter) {
|
|
234
|
-
render('entry/vuex-and-router')
|
|
235
|
-
} else if (needsVuex) {
|
|
236
|
-
render('entry/vuex')
|
|
237
|
-
} else if (needsRouter) {
|
|
238
|
-
render('entry/router')
|
|
239
|
-
} else {
|
|
240
|
-
render('entry/default')
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// Cleanup.
|
|
244
|
-
|
|
245
|
-
if (needsTypeScript) {
|
|
246
|
-
// rename all `.js` files to `.ts`
|
|
247
|
-
// rename jsconfig.json to tsconfig.json
|
|
248
|
-
preOrderDirectoryTraverse(
|
|
249
|
-
root,
|
|
250
|
-
() => {},
|
|
251
|
-
(filepath) => {
|
|
252
|
-
if (filepath.endsWith('.js')) {
|
|
253
|
-
fs.renameSync(filepath, filepath.replace(/\.js$/, '.ts'))
|
|
254
|
-
} else if (path.basename(filepath) === 'jsconfig.json') {
|
|
255
|
-
fs.renameSync(filepath, filepath.replace(/jsconfig\.json$/, 'tsconfig.json'))
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
)
|
|
259
|
-
|
|
260
|
-
// Rename entry in `index.html`
|
|
261
|
-
const indexHtmlPath = path.resolve(root, 'index.html')
|
|
262
|
-
const indexHtmlContent = fs.readFileSync(indexHtmlPath, 'utf8')
|
|
263
|
-
fs.writeFileSync(indexHtmlPath, indexHtmlContent.replace('src/main.js', 'src/main.ts'))
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (!needsTests) {
|
|
267
|
-
// All templates assumes the need of tests.
|
|
268
|
-
// If the user doesn't need it:
|
|
269
|
-
// rm -rf cypress **/__tests__/
|
|
270
|
-
preOrderDirectoryTraverse(
|
|
271
|
-
root,
|
|
272
|
-
(dirpath) => {
|
|
273
|
-
const dirname = path.basename(dirpath)
|
|
274
|
-
|
|
275
|
-
if (dirname === 'cypress' || dirname === '__tests__') {
|
|
276
|
-
emptyDir(dirpath)
|
|
277
|
-
fs.rmdirSync(dirpath)
|
|
278
|
-
}
|
|
279
|
-
},
|
|
280
|
-
() => {}
|
|
281
|
-
)
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// Instructions:
|
|
285
|
-
// Supported package managers: pnpm > yarn > npm
|
|
286
|
-
// Note: until <https://github.com/pnpm/pnpm/issues/3505> is resolved,
|
|
287
|
-
// it is not possible to tell if the command is called by `pnpm init`.
|
|
288
|
-
const packageManager = /pnpm/.test(process.env.npm_execpath)
|
|
289
|
-
? 'pnpm'
|
|
290
|
-
: /yarn/.test(process.env.npm_execpath)
|
|
291
|
-
? 'yarn'
|
|
292
|
-
: 'npm'
|
|
293
|
-
|
|
294
|
-
// README generation
|
|
295
|
-
fs.writeFileSync(
|
|
296
|
-
path.resolve(root, 'README.md'),
|
|
297
|
-
generateReadme({
|
|
298
|
-
projectName: result.projectName || defaultProjectName,
|
|
299
|
-
packageManager,
|
|
300
|
-
needsTypeScript,
|
|
301
|
-
needsTests
|
|
302
|
-
})
|
|
303
|
-
)
|
|
304
|
-
|
|
305
|
-
console.log(`\nDone. Now run:\n`)
|
|
306
|
-
if (root !== cwd) {
|
|
307
|
-
console.log(` ${bold(green(`cd ${path.relative(cwd, root)}`))}`)
|
|
308
|
-
}
|
|
309
|
-
console.log(` ${bold(green(getCommand(packageManager, 'install')))}`)
|
|
310
|
-
console.log(` ${bold(green(getCommand(packageManager, 'dev')))}`)
|
|
311
|
-
console.log()
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
init().catch((e) => {
|
|
315
|
-
console.error(e)
|
|
316
|
-
})
|