From 42bd29b13ae7931fa90deaf7f71f7b3796b8a861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E4=BB=81=E6=B4=AA?= Date: Fri, 26 Apr 2019 17:46:04 +0800 Subject: [PATCH] feat(cli): Generator support async --- packages/@vue/cli/__tests__/Generator.spec.js | 19 ++++++++---- .../generator/index.js | 17 +++++++++++ .../generator/template/test.js | 1 + .../preset.json | 5 ++++ .../prompts.js | 5 ++++ packages/@vue/cli/__tests__/preset.spec.js | 29 +++++++++++++++++++ packages/@vue/cli/lib/Generator.js | 22 +++++++++++--- 7 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 packages/@vue/cli/__tests__/mock-preset-with-async-generator/generator/index.js create mode 100644 packages/@vue/cli/__tests__/mock-preset-with-async-generator/generator/template/test.js create mode 100644 packages/@vue/cli/__tests__/mock-preset-with-async-generator/preset.json create mode 100644 packages/@vue/cli/__tests__/mock-preset-with-async-generator/prompts.js diff --git a/packages/@vue/cli/__tests__/Generator.spec.js b/packages/@vue/cli/__tests__/Generator.spec.js index 3ae81ed220..939a129caf 100644 --- a/packages/@vue/cli/__tests__/Generator.spec.js +++ b/packages/@vue/cli/__tests__/Generator.spec.js @@ -242,7 +242,7 @@ test('api: extendPackage merge dependencies', async () => { }) test('api: warn invalid dep range', async () => { - new Generator('/', { plugins: [ + const generator = new Generator('/', { plugins: [ { id: 'test1', apply: api => { @@ -255,6 +255,8 @@ test('api: warn invalid dep range', async () => { } ] }) + await generator.generate() + expect(logs.warn.some(([msg]) => { return ( msg.match(/invalid version range for dependency "foo"/) && @@ -264,7 +266,7 @@ test('api: warn invalid dep range', async () => { }) test('api: extendPackage dependencies conflict', async () => { - new Generator('/', { plugins: [ + const generator = new Generator('/', { plugins: [ { id: 'test1', apply: api => { @@ -287,6 +289,8 @@ test('api: extendPackage dependencies conflict', async () => { } ] }) + await generator.generate() + expect(logs.warn.some(([msg]) => { return ( msg.match(/conflicting versions for project dependency "foo"/) && @@ -298,7 +302,7 @@ test('api: extendPackage dependencies conflict', async () => { }) test('api: extendPackage merge warn nonstrictly semver deps', async () => { - new Generator('/', { plugins: [ + const generator = new Generator('/', { plugins: [ { id: 'test3', apply: api => { @@ -321,6 +325,8 @@ test('api: extendPackage merge warn nonstrictly semver deps', async () => { } ] }) + await generator.generate() + expect(logs.warn.some(([msg]) => { return ( msg.match(/conflicting versions for project dependency "bar"/) && @@ -422,10 +428,10 @@ test('api: hasPlugin', () => { ] }) }) -test('api: onCreateComplete', () => { +test('api: onCreateComplete', async () => { const fn = () => {} const cbs = [] - new Generator('/', { + const generator = new Generator('/', { plugins: [ { id: 'test', @@ -436,6 +442,9 @@ test('api: onCreateComplete', () => { ], completeCbs: cbs }) + + await generator.generate() + expect(cbs).toContain(fn) }) diff --git a/packages/@vue/cli/__tests__/mock-preset-with-async-generator/generator/index.js b/packages/@vue/cli/__tests__/mock-preset-with-async-generator/generator/index.js new file mode 100644 index 0000000000..22ba464be7 --- /dev/null +++ b/packages/@vue/cli/__tests__/mock-preset-with-async-generator/generator/index.js @@ -0,0 +1,17 @@ +const sleep = n => new Promise(resolve => setTimeout(resolve, n)) + +module.exports = async (api, options) => { + api.render('./template', options) + + // add asynchronous code test + await sleep(1000) + + api.extendPackage({ + scripts: { + testasync: 'this is the test' + }, + devDependencies: { + 'vue-cli-plugin-async-generator': 'v0.0.1' + } + }) +} diff --git a/packages/@vue/cli/__tests__/mock-preset-with-async-generator/generator/template/test.js b/packages/@vue/cli/__tests__/mock-preset-with-async-generator/generator/template/test.js new file mode 100644 index 0000000000..12db7fb421 --- /dev/null +++ b/packages/@vue/cli/__tests__/mock-preset-with-async-generator/generator/template/test.js @@ -0,0 +1 @@ +<%= ok %> diff --git a/packages/@vue/cli/__tests__/mock-preset-with-async-generator/preset.json b/packages/@vue/cli/__tests__/mock-preset-with-async-generator/preset.json new file mode 100644 index 0000000000..63ec289edc --- /dev/null +++ b/packages/@vue/cli/__tests__/mock-preset-with-async-generator/preset.json @@ -0,0 +1,5 @@ +{ + "plugins": { + "@vue/cli-plugin-babel": {} + } +} diff --git a/packages/@vue/cli/__tests__/mock-preset-with-async-generator/prompts.js b/packages/@vue/cli/__tests__/mock-preset-with-async-generator/prompts.js new file mode 100644 index 0000000000..26971b45f2 --- /dev/null +++ b/packages/@vue/cli/__tests__/mock-preset-with-async-generator/prompts.js @@ -0,0 +1,5 @@ +module.exports = [{ + type: 'confirm', + name: 'ok', + message: 'Are you ok?' +}] diff --git a/packages/@vue/cli/__tests__/preset.spec.js b/packages/@vue/cli/__tests__/preset.spec.js index 7afab7b1f9..5329976922 100644 --- a/packages/@vue/cli/__tests__/preset.spec.js +++ b/packages/@vue/cli/__tests__/preset.spec.js @@ -56,3 +56,32 @@ test('should recognize generator/index.js in a local preset directory', async () const pkg = require(path.resolve(cwd, name, 'package.json')) expect(pkg.devDependencies).toHaveProperty('@vue/cli-plugin-babel') }) + +test('should recognize generator/index.js in a local preset directory by async generatory', async () => { + const cwd = path.resolve(__dirname, '../../../test') + const name = 'test-preset-template-async-generator' + + expectPrompts([{ + message: 'Are you ok', + confirm: true + }]) + + await create( + name, + { + force: true, + git: false, + cwd, + preset: path.resolve(__dirname, './mock-preset-with-async-generator') + } + ) + + const testFile = await fs.readFile(path.resolve(cwd, name, 'test.js'), 'utf-8') + expect(testFile).toBe('true\n') + + const pkg = require(path.resolve(cwd, name, 'package.json')) + expect(pkg.devDependencies).toHaveProperty('@vue/cli-plugin-babel') + expect(pkg.devDependencies).toHaveProperty('vue-cli-plugin-async-generator') + expect(pkg.scripts).toHaveProperty('testasync') +}) + diff --git a/packages/@vue/cli/lib/Generator.js b/packages/@vue/cli/lib/Generator.js index 30f6ff8873..87006dce5f 100644 --- a/packages/@vue/cli/lib/Generator.js +++ b/packages/@vue/cli/lib/Generator.js @@ -97,10 +97,22 @@ module.exports = class Generator { const rootOptions = cliService ? cliService.options : inferRootOptions(pkg) - // apply generators from plugins - plugins.forEach(({ id, apply, options }) => { - const api = new GeneratorAPI(id, this, options, rootOptions) - apply(api, options, rootOptions, invoking) + + this.rootOptions = rootOptions + } + + initPlugins () { + const { rootOptions, invoking } = this + return new Promise((resolve, reject) => { + const arrP = [] + // apply generators from plugins + this.plugins.forEach(({ id, apply, options }) => { + const api = new GeneratorAPI(id, this, options, rootOptions) + const fn = apply(api, options, rootOptions, invoking) + arrP.push(fn) + }) + + Promise.all(arrP).then(resolve).catch(reject) }) } @@ -108,6 +120,8 @@ module.exports = class Generator { extractConfigFiles = false, checkExisting = false } = {}) { + await this.initPlugins() + // save the file system before applying plugin for comparison const initialFiles = Object.assign({}, this.files) // extract configs from package.json into dedicated files.