mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-04-24 05:50:21 -05:00
feat: support generator.js and prompts.js in preset
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
module.exports = (api, options) => {
|
||||
api.render(files => {
|
||||
files['test.js'] = options.ok ? 'true' : 'false'
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"plugins": {
|
||||
"@vue/cli-plugin-babel": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
module.exports = [{
|
||||
type: 'confirm',
|
||||
name: 'ok',
|
||||
message: 'Are you ok?'
|
||||
}]
|
||||
@@ -0,0 +1,32 @@
|
||||
jest.mock('inquirer')
|
||||
const { expectPrompts } = require('inquirer')
|
||||
|
||||
const path = require('path')
|
||||
const fs = require('fs-extra')
|
||||
const create = require('@vue/cli/lib/create')
|
||||
|
||||
test('fetching local preset with prompts and generator', async () => {
|
||||
const cwd = path.resolve(__dirname, '../../../test')
|
||||
const name = 'test-preset'
|
||||
|
||||
expectPrompts([{
|
||||
message: 'Are you ok',
|
||||
confirm: true
|
||||
}])
|
||||
|
||||
await create(
|
||||
name,
|
||||
{
|
||||
force: true,
|
||||
git: false,
|
||||
cwd,
|
||||
preset: path.resolve(__dirname, './mock-preset')
|
||||
}
|
||||
)
|
||||
|
||||
const testFile = await fs.readFile(path.resolve(cwd, name, 'test.js'), 'utf-8')
|
||||
expect(testFile).toBe('true')
|
||||
|
||||
const pkg = require(path.resolve(cwd, name, 'package.json'))
|
||||
expect(pkg.devDependencies).toHaveProperty('@vue/cli-plugin-babel')
|
||||
})
|
||||
@@ -1,9 +1,9 @@
|
||||
const EventEmitter = require('events')
|
||||
const fs = require('fs-extra')
|
||||
const path = require('path')
|
||||
const chalk = require('chalk')
|
||||
const debug = require('debug')
|
||||
const execa = require('execa')
|
||||
const inquirer = require('inquirer')
|
||||
const EventEmitter = require('events')
|
||||
const Generator = require('./Generator')
|
||||
const cloneDeep = require('lodash.clonedeep')
|
||||
const sortObject = require('./util/sortObject')
|
||||
@@ -13,7 +13,8 @@ const { clearConsole } = require('./util/clearConsole')
|
||||
const PromptModuleAPI = require('./PromptModuleAPI')
|
||||
const writeFileTree = require('./util/writeFileTree')
|
||||
const { formatFeatures } = require('./util/features')
|
||||
const fetchRemotePreset = require('./util/fetchRemotePreset')
|
||||
const loadLocalPreset = require('./util/loadLocalPreset')
|
||||
const loadRemotePreset = require('./util/loadRemotePreset')
|
||||
const generateReadme = require('./util/generateReadme')
|
||||
|
||||
const {
|
||||
@@ -113,8 +114,13 @@ module.exports = class Creator extends EventEmitter {
|
||||
}
|
||||
const deps = Object.keys(preset.plugins)
|
||||
deps.forEach(dep => {
|
||||
pkg.devDependencies[dep] = preset.plugins[dep].version ||
|
||||
if (preset.plugins[dep]._isPreset) {
|
||||
return
|
||||
}
|
||||
pkg.devDependencies[dep] = (
|
||||
preset.plugins[dep].version ||
|
||||
(/^@vue/.test(dep) ? `^${latest}` : `latest`)
|
||||
)
|
||||
})
|
||||
// write package.json
|
||||
await writeFileTree(context, {
|
||||
@@ -267,13 +273,13 @@ module.exports = class Creator extends EventEmitter {
|
||||
|
||||
if (name in savedPresets) {
|
||||
preset = savedPresets[name]
|
||||
} else if (name.endsWith('.json')) {
|
||||
preset = await fs.readJson(name)
|
||||
} else if (name.endsWith('.json') || /^[./\\]/.test(name)) {
|
||||
preset = await loadLocalPreset(path.resolve(name))
|
||||
} else if (name.includes('/')) {
|
||||
logWithSpinner(`Fetching remote preset ${chalk.cyan(name)}...`)
|
||||
this.emit('creation', { event: 'fetch-remote-preset' })
|
||||
try {
|
||||
preset = await fetchRemotePreset(name, clone)
|
||||
preset = await loadRemotePreset(name, clone)
|
||||
stopSpinner()
|
||||
} catch (e) {
|
||||
stopSpinner()
|
||||
@@ -312,7 +318,8 @@ module.exports = class Creator extends EventEmitter {
|
||||
if (options.prompts) {
|
||||
const prompts = loadModule(`${id}/prompts`, this.context)
|
||||
if (prompts) {
|
||||
console.log(`\n${chalk.cyan(id)}`)
|
||||
log()
|
||||
log(`${chalk.cyan(options._isPreset ? `Preset options:` : id)}`)
|
||||
options = await inquirer.prompt(prompts)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,9 +13,10 @@ async function create (projectName, options) {
|
||||
process.env.HTTP_PROXY = options.proxy
|
||||
}
|
||||
|
||||
const cwd = options.cwd || process.cwd()
|
||||
const inCurrent = projectName === '.'
|
||||
const name = inCurrent ? path.relative('../', process.cwd()) : projectName
|
||||
const targetDir = path.resolve(projectName || '.')
|
||||
const name = inCurrent ? path.relative('../', cwd) : projectName
|
||||
const targetDir = path.resolve(cwd, projectName || '.')
|
||||
|
||||
const result = validateProjectName(name)
|
||||
if (!result.validForNewPackages) {
|
||||
@@ -70,7 +71,7 @@ async function create (projectName, options) {
|
||||
}
|
||||
|
||||
module.exports = (...args) => {
|
||||
create(...args).catch(err => {
|
||||
return create(...args).catch(err => {
|
||||
stopSpinner(false) // do not persist
|
||||
error(err)
|
||||
process.exit(1)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
const fs = require('fs-extra')
|
||||
const loadPresetFromDir = require('./loadPresetFromDir')
|
||||
|
||||
module.exports = async function loadLocalPreset (path) {
|
||||
const stats = fs.statSync(path)
|
||||
if (stats.isFile()) {
|
||||
return await fs.readJson(path)
|
||||
} else if (stats.isDirectory()) {
|
||||
return await loadPresetFromDir(path)
|
||||
} else {
|
||||
throw new Error(`Invalid local preset path: ${path}`)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
const path = require('path')
|
||||
const fs = require('fs-extra')
|
||||
|
||||
module.exports = async function loadPresetFromDir (dir) {
|
||||
const presetPath = path.join(dir, 'preset.json')
|
||||
if (!fs.existsSync(presetPath)) {
|
||||
throw new Error('remote / local preset does not contain preset.json!')
|
||||
}
|
||||
const preset = await fs.readJson(presetPath)
|
||||
|
||||
// if the preset dir contains generator.js, we will inject it as a hidden
|
||||
// plugin so it will be invoked by the generator.
|
||||
const generatorPath = path.join(dir, 'generator.js')
|
||||
if (fs.existsSync(generatorPath)) {
|
||||
(preset.plugins || (preset.plugins = {}))[dir.replace(/[\/]$/, '')] = {
|
||||
_isPreset: true,
|
||||
prompts: true
|
||||
}
|
||||
}
|
||||
|
||||
return preset
|
||||
}
|
||||
+5
-16
@@ -1,14 +1,7 @@
|
||||
const fs = require('fs-extra')
|
||||
const loadPresetFromDir = require('./loadPresetFromDir')
|
||||
|
||||
module.exports = async function fetchRemotePreset (name, clone) {
|
||||
// github shorthand fastpath
|
||||
if (!clone && /^[\w_-]+\/[\w_-]+$/.test(name)) {
|
||||
const { request } = require('@vue/cli-shared-utils')
|
||||
return request.get(`https://raw.githubusercontent.com/${name}/master/preset.json`)
|
||||
.then(res => res.body)
|
||||
}
|
||||
|
||||
// fallback to full download
|
||||
const os = require('os')
|
||||
const path = require('path')
|
||||
const download = require('download-git-repo')
|
||||
@@ -20,16 +13,12 @@ module.exports = async function fetchRemotePreset (name, clone) {
|
||||
await fs.remove(tmpdir)
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
await new Promise((resolve, reject) => {
|
||||
download(name, tmpdir, { clone }, err => {
|
||||
if (err) return reject(err)
|
||||
let preset
|
||||
try {
|
||||
preset = require(path.join(tmpdir, 'preset.json'))
|
||||
} catch (e) {
|
||||
return reject(e)
|
||||
}
|
||||
resolve(preset)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
|
||||
return await loadPresetFromDir(tmpdir)
|
||||
}
|
||||
Reference in New Issue
Block a user