From 5d002ccb07ce73e304818c9176625a32894186dd Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Mon, 24 Aug 2020 15:44:25 +0800 Subject: [PATCH 01/14] fix: do not throw when api.render is called from an anonymous function (#5801) Fixes #4774 --- packages/@vue/cli/__tests__/Generator.spec.js | 20 +++++++++++++++++++ packages/@vue/cli/lib/GeneratorAPI.js | 13 +++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/@vue/cli/__tests__/Generator.spec.js b/packages/@vue/cli/__tests__/Generator.spec.js index 5a97a794d1..8e169b3e43 100644 --- a/packages/@vue/cli/__tests__/Generator.spec.js +++ b/packages/@vue/cli/__tests__/Generator.spec.js @@ -531,6 +531,26 @@ test('api: render fs directory', async () => { expect(fs.readFileSync('/.vscode/config.json', 'utf-8')).toMatch('{}') }) +// #4774 +test('api: call render inside an anonymous function', async () => { + const generator = new Generator('/', { plugins: [ + { + id: 'test1', + apply: api => { + (() => { + api.render('./template', { m: 2 }) + })() + }, + options: { + n: 1 + } + } + ] }) + + await generator.generate() + expect(fs.readFileSync('/foo.js', 'utf-8')).toMatch('foo(1)') +}) + test('api: render object', async () => { const generator = new Generator('/', { plugins: [ { diff --git a/packages/@vue/cli/lib/GeneratorAPI.js b/packages/@vue/cli/lib/GeneratorAPI.js index f7ea81b638..30aefa11fd 100644 --- a/packages/@vue/cli/lib/GeneratorAPI.js +++ b/packages/@vue/cli/lib/GeneratorAPI.js @@ -457,7 +457,18 @@ function extractCallDir () { const obj = {} Error.captureStackTrace(obj) const callSite = obj.stack.split('\n')[3] - const fileName = callSite.match(/\s\((.*):\d+:\d+\)$/)[1] + + // the regexp for the stack when called inside a named function + const namedStackRegExp = /\s\((.*):\d+:\d+\)$/ + // the regexp for the stack when called inside an anonymous + const anonymousStackRegExp = /at (.*):\d+:\d+$/ + + let matchResult = callSite.match(namedStackRegExp) + if (!matchResult) { + matchResult = callSite.match(anonymousStackRegExp) + } + + const fileName = matchResult[1] return path.dirname(fileName) } From 27db6bfaa8e771eacefe3b59629f46bd74136e10 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Mon, 24 Aug 2020 15:52:37 +0800 Subject: [PATCH 02/14] fix: strip non-ansi characters from registry config (#5808) To deal with malformed stdout result retrieved from child processes. Fixes #5802 --- packages/@vue/cli/lib/util/ProjectPackageManager.js | 3 +++ packages/@vue/cli/package.json | 1 + 2 files changed, 4 insertions(+) diff --git a/packages/@vue/cli/lib/util/ProjectPackageManager.js b/packages/@vue/cli/lib/util/ProjectPackageManager.js index a39228eb96..15256a7c4b 100644 --- a/packages/@vue/cli/lib/util/ProjectPackageManager.js +++ b/packages/@vue/cli/lib/util/ProjectPackageManager.js @@ -5,6 +5,8 @@ const ini = require('ini') const minimist = require('minimist') const LRU = require('lru-cache') +const stripAnsi = require('strip-ansi') + const { chalk, execa, @@ -152,6 +154,7 @@ class PackageManager { } } + this._registry = stripAnsi(this._registry).trim() return this._registry } diff --git a/packages/@vue/cli/package.json b/packages/@vue/cli/package.json index 1f10c5b564..7aff26a065 100644 --- a/packages/@vue/cli/package.json +++ b/packages/@vue/cli/package.json @@ -55,6 +55,7 @@ "resolve": "^1.17.0", "shortid": "^2.2.15", "slash": "^3.0.0", + "strip-ansi": "^6.0.0", "validate-npm-package-name": "^3.0.0", "vue": "^2.6.11", "vue-codemod": "^0.0.4", From 9706cd1d2866475744b94af997c1426e42c38b8b Mon Sep 17 00:00:00 2001 From: Spenser Black Date: Thu, 27 Aug 2020 03:04:05 -0400 Subject: [PATCH 03/14] fix: handle GPG sign git config for initial commit (#5823) Fixes #5818 --- packages/@vue/cli/lib/Creator.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/@vue/cli/lib/Creator.js b/packages/@vue/cli/lib/Creator.js index a443b338b3..4dd321b778 100644 --- a/packages/@vue/cli/lib/Creator.js +++ b/packages/@vue/cli/lib/Creator.js @@ -248,12 +248,22 @@ module.exports = class Creator extends EventEmitter { // commit initial state let gitCommitFailed = false + let gpgSign = false if (shouldInitGit) { await run('git add -A') if (isTestOrDebug) { await run('git', ['config', 'user.name', 'test']) await run('git', ['config', 'user.email', 'test@test.com']) + await run('git', ['config', 'commit.gpgSign', 'false']) } + gpgSign = await (async () => { + const { stdout: gpgSignConfig } = await run('git', [ + 'config', + '--get', + 'commit.gpgSign' + ]) + return gpgSignConfig === 'true' + })() const msg = typeof cliOptions.git === 'string' ? cliOptions.git : 'init' try { await run('git', ['commit', '-m', msg, '--no-verify']) @@ -277,7 +287,7 @@ module.exports = class Creator extends EventEmitter { if (gitCommitFailed) { warn( - `Skipped git commit due to missing username and email in git config.\n` + + `Skipped git commit due to missing username and email in git config${gpgSign ? ' or failed to sign commit' : ''}.\n` + `You will need to perform the initial commit yourself.\n` ) } From 9641d6d254bd708c66a670b51639d316567c6a4c Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Thu, 27 Aug 2020 16:29:01 +0800 Subject: [PATCH 04/14] fix: fix support for Node.js v8 and deprecate it (#5827) Fixes #5800 --- packages/@vue/cli/bin/vue.js | 15 +++++--- packages/@vue/cli/lib/Creator.js | 35 +++++++++++------ .../cli/lib/util/ProjectPackageManager.js | 38 +++++++++++++++++++ 3 files changed, 70 insertions(+), 18 deletions(-) diff --git a/packages/@vue/cli/bin/vue.js b/packages/@vue/cli/bin/vue.js index c30d66a1e5..c65a809c49 100755 --- a/packages/@vue/cli/bin/vue.js +++ b/packages/@vue/cli/bin/vue.js @@ -19,12 +19,15 @@ function checkNodeVersion (wanted, id) { checkNodeVersion(requiredVersion, '@vue/cli') -if (semver.satisfies(process.version, '9.x')) { - console.log(chalk.red( - `You are using Node ${process.version}.\n` + - `Node.js 9.x has already reached end-of-life and will not be supported in future major releases.\n` + - `It's strongly recommended to use an active LTS version instead.` - )) +const EOL_NODE_MAJORS = ['8.x', '9.x', '11.x', '13.x'] +for (const major of EOL_NODE_MAJORS) { + if (semver.satisfies(process.version, major)) { + console.log(chalk.red( + `You are using Node ${process.version}.\n` + + `Node.js ${major} has already reached end-of-life and will not be supported in future major releases.\n` + + `It's strongly recommended to use an active LTS version instead.` + )) + } } const fs = require('fs') diff --git a/packages/@vue/cli/lib/Creator.js b/packages/@vue/cli/lib/Creator.js index 4dd321b778..ff947b912b 100644 --- a/packages/@vue/cli/lib/Creator.js +++ b/packages/@vue/cli/lib/Creator.js @@ -28,6 +28,7 @@ const { const { chalk, execa, + semver, log, warn, @@ -132,9 +133,10 @@ module.exports = class Creator extends EventEmitter { (hasYarn() ? 'yarn' : null) || (hasPnpm3OrLater() ? 'pnpm' : 'npm') ) - const pm = new PackageManager({ context, forcePackageManager: packageManager }) await clearConsole() + const pm = new PackageManager({ context, forcePackageManager: packageManager }) + log(`✨ Creating project in ${chalk.yellow(context)}.`) this.emit('creation', { event: 'creating' }) @@ -173,6 +175,26 @@ module.exports = class Creator extends EventEmitter { 'package.json': JSON.stringify(pkg, null, 2) }) + // generate a .npmrc file for pnpm, to persist the `shamefully-flatten` flag + if (packageManager === 'pnpm') { + const pnpmConfig = hasPnpmVersionOrLater('4.0.0') + ? 'shamefully-hoist=true\n' + : 'shamefully-flatten=true\n' + + await writeFileTree(context, { + '.npmrc': pnpmConfig + }) + } + + if (packageManager === 'yarn' && semver.satisfies(process.version, '8.x')) { + // Vue CLI 4.x should support Node 8.x, + // but some dependenices already bumped `engines` field to Node 10 + // and Yarn treats `engines` field too strictly + await writeFileTree(context, { + '.yarnrc': '# Hotfix for Node 8.x\n--install.ignore-engines true\n' + }) + } + // intilaize git repository before installing deps // so that vue-cli-service can setup git hooks. const shouldInitGit = this.shouldInitGit(cliOptions) @@ -235,17 +257,6 @@ module.exports = class Creator extends EventEmitter { }) } - // generate a .npmrc file for pnpm, to persist the `shamefully-flatten` flag - if (packageManager === 'pnpm') { - const pnpmConfig = hasPnpmVersionOrLater('4.0.0') - ? 'shamefully-hoist=true\n' - : 'shamefully-flatten=true\n' - - await writeFileTree(context, { - '.npmrc': pnpmConfig - }) - } - // commit initial state let gitCommitFailed = false let gpgSign = false diff --git a/packages/@vue/cli/lib/util/ProjectPackageManager.js b/packages/@vue/cli/lib/util/ProjectPackageManager.js index 15256a7c4b..2ab3877bf5 100644 --- a/packages/@vue/cli/lib/util/ProjectPackageManager.js +++ b/packages/@vue/cli/lib/util/ProjectPackageManager.js @@ -106,6 +106,22 @@ class PackageManager { this.bin = loadOptions().packageManager || (hasYarn() ? 'yarn' : hasPnpm3OrLater() ? 'pnpm' : 'npm') } + if (this.bin === 'npm') { + // npm doesn't support package aliases until v6.9 + const MIN_SUPPORTED_NPM_VERSION = '6.9.0' + const npmVersion = stripAnsi(execa.sync('npm', ['--version']).stdout) + + if (semver.lt(npmVersion, MIN_SUPPORTED_NPM_VERSION)) { + warn( + 'You are using an outdated version of NPM.\n' + + 'there may be unexpected errors during installation.\n' + + 'Please upgrade your NPM version.' + ) + + this.needsNpmInstallFix = true + } + } + if (!SUPPORTED_PACKAGE_MANAGERS.includes(this.bin)) { log() warn( @@ -313,6 +329,28 @@ class PackageManager { } } + if (this.needsNpmInstallFix) { + // if npm 5, split into several `npm add` calls + // see https://github.com/vuejs/vue-cli/issues/5800#issuecomment-675199729 + const pkg = resolvePkg(this.context) + if (pkg.dependencies) { + const deps = Object.entries(pkg.dependencies).map(([dep, range]) => `${dep}@${range}`) + await this.runCommand('install', deps) + } + + if (pkg.devDependencies) { + const devDeps = Object.entries(pkg.devDependencies).map(([dep, range]) => `${dep}@${range}`) + await this.runCommand('install', [...devDeps, '--save-dev']) + } + + if (pkg.optionalDependencies) { + const devDeps = Object.entries(pkg.devDependencies).map(([dep, range]) => `${dep}@${range}`) + await this.runCommand('install', [...devDeps, '--save-optional']) + } + + return + } + return await this.runCommand('install') } From ebee88259e4ef21b9fdb9bc0f380930c96721e05 Mon Sep 17 00:00:00 2001 From: Renan Cidale Assumpcao Date: Thu, 27 Aug 2020 16:01:55 +0200 Subject: [PATCH 05/14] refactor: remove ListFilter logic (#5391) Co-authored-by: Renan Cidale Assumpcao Co-authored-by: Haoqun Jiang --- .../components/dashboard/WidgetAddPane.vue | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/packages/@vue/cli-ui/src/components/dashboard/WidgetAddPane.vue b/packages/@vue/cli-ui/src/components/dashboard/WidgetAddPane.vue index 78be305b15..f6f95a82b6 100644 --- a/packages/@vue/cli-ui/src/components/dashboard/WidgetAddPane.vue +++ b/packages/@vue/cli-ui/src/components/dashboard/WidgetAddPane.vue @@ -34,19 +34,12 @@ /> From bbe4bb5a234382c902936ff358660bd7b6ce96c4 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Fri, 28 Aug 2020 00:44:45 +0800 Subject: [PATCH 06/14] test: fix test errors --- .../__tests__/wdioPlugin.spec.js | 8 ++++++-- .../cli-plugin-unit-mocha/__tests__/mochaPlugin.spec.js | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/@vue/cli-plugin-e2e-webdriverio/__tests__/wdioPlugin.spec.js b/packages/@vue/cli-plugin-e2e-webdriverio/__tests__/wdioPlugin.spec.js index 6e5678adea..8019cc9f43 100644 --- a/packages/@vue/cli-plugin-e2e-webdriverio/__tests__/wdioPlugin.spec.js +++ b/packages/@vue/cli-plugin-e2e-webdriverio/__tests__/wdioPlugin.spec.js @@ -6,7 +6,9 @@ test('should work', async () => { const project = await create('e2e-webdriverio', { plugins: { '@vue/cli-plugin-babel': {}, - '@vue/cli-plugin-e2e-webdriverio': {}, + '@vue/cli-plugin-e2e-webdriverio': { + webdrivers: ['chrome'] + }, '@vue/cli-plugin-eslint': { config: 'airbnb', lintOn: 'save' @@ -29,7 +31,9 @@ test('should work with TS', async () => { 'tsLint': true, 'lintOn': ['save'] }, - '@vue/cli-plugin-e2e-webdriverio': {} + '@vue/cli-plugin-e2e-webdriverio': { + webdrivers: ['chrome'] + } } }) diff --git a/packages/@vue/cli-plugin-unit-mocha/__tests__/mochaPlugin.spec.js b/packages/@vue/cli-plugin-unit-mocha/__tests__/mochaPlugin.spec.js index 2fb088a8bd..fe90cb26ec 100644 --- a/packages/@vue/cli-plugin-unit-mocha/__tests__/mochaPlugin.spec.js +++ b/packages/@vue/cli-plugin-unit-mocha/__tests__/mochaPlugin.spec.js @@ -27,7 +27,7 @@ test('should work with Vue 3', async () => { }) test('should work with Vue 3 + TS', async () => { - const project = await createOutside('unit-mocha-vue-3', { + const project = await createOutside('unit-mocha-vue-3-ts', { vueVersion: '3', plugins: { '@vue/cli-plugin-babel': {}, From d88d927000502ba9e55bfde384aa5f66628bcdf4 Mon Sep 17 00:00:00 2001 From: Amour1688 <31695475+Amour1688@users.noreply.github.com> Date: Fri, 28 Aug 2020 15:32:39 +0800 Subject: [PATCH 07/14] chore: rename jsx package scope from ant-design-vue to vue (#5831) --- packages/@vue/babel-preset-app/README.md | 2 +- packages/@vue/babel-preset-app/index.js | 2 +- packages/@vue/babel-preset-app/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/@vue/babel-preset-app/README.md b/packages/@vue/babel-preset-app/README.md index efdb574a6a..36cf4ea277 100644 --- a/packages/@vue/babel-preset-app/README.md +++ b/packages/@vue/babel-preset-app/README.md @@ -88,7 +88,7 @@ Use this option when you have 3rd party dependencies that are not processed by B - Default: `true`. -Set to `false` to disable JSX support. Or you can toggle [@vue/babel-preset-jsx](https://github.com/vuejs/jsx/tree/dev/packages/babel-preset-jsx) (or [@ant-design-vue/babel-plugin-jsx](https://github.com/vueComponent/jsx) for Vue 3 projects) features here. +Set to `false` to disable JSX support. Or you can toggle [@vue/babel-preset-jsx](https://github.com/vuejs/jsx/tree/dev/packages/babel-preset-jsx) (or [@vue/babel-plugin-jsx](https://github.com/vuejs/jsx-next) for Vue 3 projects) features here. ### loose diff --git a/packages/@vue/babel-preset-app/index.js b/packages/@vue/babel-preset-app/index.js index c7f34bbf87..a87ebfbbef 100644 --- a/packages/@vue/babel-preset-app/index.js +++ b/packages/@vue/babel-preset-app/index.js @@ -126,7 +126,7 @@ module.exports = (context, options = {}) => { if (vueVersion === 2) { presets.push([require('@vue/babel-preset-jsx'), jsxOptions]) } else if (vueVersion === 3) { - plugins.push([require('@ant-design-vue/babel-plugin-jsx'), jsxOptions]) + plugins.push([require('@vue/babel-plugin-jsx'), jsxOptions]) } } diff --git a/packages/@vue/babel-preset-app/package.json b/packages/@vue/babel-preset-app/package.json index 323df6e6c4..47f7bb7c62 100644 --- a/packages/@vue/babel-preset-app/package.json +++ b/packages/@vue/babel-preset-app/package.json @@ -22,7 +22,6 @@ }, "homepage": "https://github.com/vuejs/vue-cli/tree/dev/packages/@vue/babel-preset-app#readme", "dependencies": { - "@ant-design-vue/babel-plugin-jsx": "^1.0.0-0", "@babel/core": "^7.11.0", "@babel/helper-compilation-targets": "^7.9.6", "@babel/helper-module-imports": "^7.8.3", @@ -33,6 +32,7 @@ "@babel/plugin-transform-runtime": "^7.11.0", "@babel/preset-env": "^7.11.0", "@babel/runtime": "^7.11.0", + "@vue/babel-plugin-jsx": "^1.0.0-0", "@vue/babel-preset-jsx": "^1.1.2", "babel-plugin-dynamic-import-node": "^2.3.3", "core-js": "^3.6.5", From 34b58c0f6246ddbd34784ac49fb0c2807cbf986e Mon Sep 17 00:00:00 2001 From: GabrielGMartinsBr Date: Sun, 30 Aug 2020 22:52:39 -0300 Subject: [PATCH 08/14] fix: allow turning off theme color tags (#5820) Co-authored-by: Haoqun Jiang --- .../@vue/cli-plugin-pwa/lib/HtmlPwaPlugin.js | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/packages/@vue/cli-plugin-pwa/lib/HtmlPwaPlugin.js b/packages/@vue/cli-plugin-pwa/lib/HtmlPwaPlugin.js index 25b4bfbe2a..f6683ef47e 100644 --- a/packages/@vue/cli-plugin-pwa/lib/HtmlPwaPlugin.js +++ b/packages/@vue/cli-plugin-pwa/lib/HtmlPwaPlugin.js @@ -111,13 +111,18 @@ module.exports = class HtmlPwaPlugin { rel: 'manifest', href: getTagHref(publicPath, manifestPath, assetsVersionStr) } - ), - makeTag('meta', { - name: 'theme-color', - content: themeColor - }) + ) ) + if (themeColor != null) { + data.head.push( + makeTag('meta', { + name: 'theme-color', + content: themeColor + }) + ) + } + // Add to home screen for Safari on iOS data.head.push( makeTag('meta', { @@ -154,12 +159,14 @@ module.exports = class HtmlPwaPlugin { content: getTagHref(publicPath, iconPaths.msTileImage, assetsVersionStr) })) } - data.head.push( - makeTag('meta', { - name: 'msapplication-TileColor', - content: msTileColor - }) - ) + if (msTileColor != null) { + data.head.push( + makeTag('meta', { + name: 'msapplication-TileColor', + content: msTileColor + }) + ) + } cb(null, data) }) From 10d5ae4a13b0534f6244cf31057f35b587725aff Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Tue, 1 Sep 2020 09:30:03 +0100 Subject: [PATCH 09/14] perf(ui): improve get folder list to use Promises instead of sync (#3687) --- .../apollo-server/connectors/folders.js | 51 ++++++++++++++----- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/packages/@vue/cli-ui/apollo-server/connectors/folders.js b/packages/@vue/cli-ui/apollo-server/connectors/folders.js index f6ad016d8e..3349c015c8 100644 --- a/packages/@vue/cli-ui/apollo-server/connectors/folders.js +++ b/packages/@vue/cli-ui/apollo-server/connectors/folders.js @@ -16,7 +16,7 @@ const cwd = require('./cwd') function isDirectory (file) { file = file.replace(/\\/g, path.sep) try { - return fs.statSync(file).isDirectory() + return fs.stat(file).then((x) => x.isDirectory()) } catch (e) { if (process.env.VUE_APP_CLI_UI_DEBUG) console.warn(e.message) } @@ -31,21 +31,41 @@ async function list (base, context) { } } const files = await fs.readdir(dir, 'utf8') - return files.map( - file => { + + const f = await Promise.all( + files.map(async (file) => { const folderPath = path.join(base, file) + + const [directory, hidden] = await Promise.all([ + isDirectory(folderPath), + isHidden(folderPath) + ]) + if (!directory) { + return null + } return { path: folderPath, name: file, - hidden: isHidden(folderPath) + hidden } - } - ).filter( - file => isDirectory(file.path) + }) ) + return f.filter((x) => !!x) } -function isHidden (file) { +async function isHiddenWindows (file) { + const windowsFile = file.replace(/\\/g, '\\\\') + return new Promise((resolve, reject) => { + winattr.get(windowsFile, (file, error) => { + if (error) { + return reject(error) + } + resolve(file) + }) + }).then((x) => x.hidden) +} + +async function isHidden (file) { try { const prefixed = path.basename(file).charAt(0) === hiddenPrefix const result = { @@ -54,11 +74,13 @@ function isHidden (file) { } if (isPlatformWindows) { - const windowsFile = file.replace(/\\/g, '\\\\') - result.windows = winattr.getSync(windowsFile).hidden + result.windows = await isHiddenWindows(file) } - return (!isPlatformWindows && result.unix) || (isPlatformWindows && result.windows) + return ( + (!isPlatformWindows && result.unix) || + (isPlatformWindows && result.windows) + ) } catch (e) { if (process.env.VUE_APP_CLI_UI_DEBUG) { console.log('file:', file) @@ -142,9 +164,10 @@ function isVueProject (file, context) { } function listFavorite (context) { - return context.db.get('foldersFavorite').value().map( - file => generateFolder(file.id, context) - ) + return context.db + .get('foldersFavorite') + .value() + .map((file) => generateFolder(file.id, context)) } function isFavorite (file, context) { From f42888d9e1a9002f35f92bd9ed5081e6bd73ba3e Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Thu, 3 Sep 2020 09:55:33 +0800 Subject: [PATCH 10/14] chore: fix indentation --- .../cli-plugin-router/generator/template/src/router/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@vue/cli-plugin-router/generator/template/src/router/index.js b/packages/@vue/cli-plugin-router/generator/template/src/router/index.js index 3f1acf1fd9..bd387557f2 100644 --- a/packages/@vue/cli-plugin-router/generator/template/src/router/index.js +++ b/packages/@vue/cli-plugin-router/generator/template/src/router/index.js @@ -9,9 +9,9 @@ import Home from '../views/Home.vue' Vue.use(VueRouter) <%_ if (hasTypeScript) { _%> - const routes: Array = [ +const routes: Array = [ <%_ } else { _%> - const routes = [ +const routes = [ <%_ } _%> { path: '/', From d6e493db7471976050cb7f9ab16e4a072a3a3ba8 Mon Sep 17 00:00:00 2001 From: Sergey Skrynnikov Date: Mon, 7 Sep 2020 10:45:09 +0300 Subject: [PATCH 11/14] fix(unit-jest, unit-mocha): generate passing tests when `bare` option is used with router enabled (#5591) Fixes #3544 --- .../__tests__/jestGenerator.spec.js | 53 +++++++++++++++++++ .../cli-plugin-unit-jest/generator/index.js | 3 +- .../template/tests/unit/example.spec.js | 22 ++++++++ .../template/tests/unit/example.spec.ts | 22 ++++++++ .../__tests__/mochaGenerator.spec.js | 53 +++++++++++++++++++ .../cli-plugin-unit-mocha/generator/index.js | 3 +- .../template/tests/unit/example.spec.js | 24 +++++++++ .../template/tests/unit/example.spec.ts | 24 +++++++++ 8 files changed, 202 insertions(+), 2 deletions(-) diff --git a/packages/@vue/cli-plugin-unit-jest/__tests__/jestGenerator.spec.js b/packages/@vue/cli-plugin-unit-jest/__tests__/jestGenerator.spec.js index dcc581a68f..0166aae893 100644 --- a/packages/@vue/cli-plugin-unit-jest/__tests__/jestGenerator.spec.js +++ b/packages/@vue/cli-plugin-unit-jest/__tests__/jestGenerator.spec.js @@ -88,3 +88,56 @@ test('TS + bare', async () => { expect(spec).toMatch(`const wrapper = shallowMount(App)`) expect(spec).toMatch(`expect(wrapper.text()).toMatch(\`Welcome to Your Vue.js + TypeScript App\`)`) }) + +test('bare + router', async () => { + const { files } = await generateWithPlugin([ + { + id: 'unit-jest', + apply: require('../generator'), + options: {} + }, + { + id: '@vue/cli-service', + apply: () => {}, + options: { bare: true } + }, + { + id: 'router', + apply: () => {}, + options: {} + } + ]) + + const spec = files['tests/unit/example.spec.js'] + expect(spec).toMatch(`const wrapper = mount(App,`) + expect(spec).toMatch(`expect(wrapper.text()).toMatch(\`Welcome to Your Vue.js App\`)`) +}) + +test('TS + bare + router', async () => { + const { files } = await generateWithPlugin([ + { + id: 'unit-jest', + apply: require('../generator'), + options: {} + }, + { + id: 'typescript', + apply: () => {}, + options: {} + }, + { + id: '@vue/cli-service', + apply: () => {}, + options: { bare: true } + }, + { + id: 'router', + apply: () => {}, + options: {} + } + ]) + + const spec = files['tests/unit/example.spec.ts'] + expect(spec).toMatch(`const wrapper = mount(App,`) + expect(spec).toMatch(`expect(wrapper.text()).toMatch(\`Welcome to Your Vue.js App\`)`) +}) diff --git a/packages/@vue/cli-plugin-unit-jest/generator/index.js b/packages/@vue/cli-plugin-unit-jest/generator/index.js index 220189b9a9..843d560850 100644 --- a/packages/@vue/cli-plugin-unit-jest/generator/index.js +++ b/packages/@vue/cli-plugin-unit-jest/generator/index.js @@ -3,7 +3,8 @@ module.exports = (api, options, rootOptions, invoking) => { api.render('./template', { isVue3, - hasTS: api.hasPlugin('typescript') + hasTS: api.hasPlugin('typescript'), + hasRouter: api.hasPlugin('router') }) api.extendPackage({ diff --git a/packages/@vue/cli-plugin-unit-jest/generator/template/tests/unit/example.spec.js b/packages/@vue/cli-plugin-unit-jest/generator/template/tests/unit/example.spec.js index 3851de59a3..a67350bf09 100644 --- a/packages/@vue/cli-plugin-unit-jest/generator/template/tests/unit/example.spec.js +++ b/packages/@vue/cli-plugin-unit-jest/generator/template/tests/unit/example.spec.js @@ -1,5 +1,9 @@ <%_ if (!hasTS) { _%> +<%_ if (!rootOptions.bare || !hasRouter) { _%> import { shallowMount } from '@vue/test-utils' +<%_ } else { _%> +import { mount, createLocalVue } from '@vue/test-utils' +<%_ } _%> <%_ if (!rootOptions.bare) { _%> import HelloWorld from '@/components/HelloWorld.vue' @@ -18,10 +22,28 @@ describe('HelloWorld.vue', () => { }) <%_ } else { _%> import App from '@/App.vue' +<%_ if (!hasRouter) { _%> test('App should work', () => { const wrapper = shallowMount(App) expect(wrapper.text()).toMatch(`Welcome to Your Vue.js App`) }) + +<%_ } else {_%> +import VueRouter from 'vue-router' +import router from '@/router' + +const localVue = createLocalVue() +localVue.use(VueRouter) + +test('App should render default route', () => { + const wrapper = mount(App, { + localVue, + router + }) + expect(wrapper.text()).toMatch(`Welcome to Your Vue.js App`) +}) + +<%_ } _%> <%_ } _%> <%_ } _%> diff --git a/packages/@vue/cli-plugin-unit-jest/generator/template/tests/unit/example.spec.ts b/packages/@vue/cli-plugin-unit-jest/generator/template/tests/unit/example.spec.ts index 962d8ed7b8..68bccac4cc 100644 --- a/packages/@vue/cli-plugin-unit-jest/generator/template/tests/unit/example.spec.ts +++ b/packages/@vue/cli-plugin-unit-jest/generator/template/tests/unit/example.spec.ts @@ -1,5 +1,9 @@ <%_ if (hasTS) { _%> +<%_ if (!rootOptions.bare || !hasRouter) { _%> import { shallowMount } from '@vue/test-utils' +<%_ } else { _%> +import { mount, createLocalVue } from '@vue/test-utils' +<%_ } _%> <%_ if (!rootOptions.bare) { _%> import HelloWorld from '@/components/HelloWorld.vue' @@ -18,10 +22,28 @@ describe('HelloWorld.vue', () => { }) <%_ } else { _%> import App from '@/App.vue' +<%_ if (!hasRouter) { _%> test('App should work', () => { const wrapper = shallowMount(App) expect(wrapper.text()).toMatch(`Welcome to Your Vue.js + TypeScript App`) }) + +<%_ } else {_%> +import VueRouter from 'vue-router' +import router from '@/router' + +const localVue = createLocalVue() +localVue.use(VueRouter) + +test('App should render default route', () => { + const wrapper = mount(App, { + localVue, + router + }) + expect(wrapper.text()).toMatch(`Welcome to Your Vue.js App`) +}) + +<%_ } _%> <%_ } _%> <%_ } _%> diff --git a/packages/@vue/cli-plugin-unit-mocha/__tests__/mochaGenerator.spec.js b/packages/@vue/cli-plugin-unit-mocha/__tests__/mochaGenerator.spec.js index 572de94703..6c6368c4d1 100644 --- a/packages/@vue/cli-plugin-unit-mocha/__tests__/mochaGenerator.spec.js +++ b/packages/@vue/cli-plugin-unit-mocha/__tests__/mochaGenerator.spec.js @@ -85,3 +85,56 @@ test('TS + bare', async () => { expect(spec).toMatch(`const wrapper = shallowMount(App)`) expect(spec).toMatch(`expect(wrapper.text()).to.include(\`Welcome to Your Vue.js + TypeScript App\`)`) }) + +test('bare + router', async () => { + const { files } = await generateWithPlugin([ + { + id: 'unit-mocha', + apply: require('../generator'), + options: {} + }, + { + id: '@vue/cli-service', + apply: () => {}, + options: { bare: true } + }, + { + id: 'router', + apply: () => {}, + options: {} + } + ]) + + const spec = files['tests/unit/example.spec.js'] + expect(spec).toMatch(`const wrapper = mount(App,`) + expect(spec).toMatch(`expect(wrapper.text()).to.include(\`Welcome to Your Vue.js App\`)`) +}) + +test('TS + bare + router', async () => { + const { files } = await generateWithPlugin([ + { + id: 'unit-mocha', + apply: require('../generator'), + options: {} + }, + { + id: 'typescript', + apply: () => {}, + options: {} + }, + { + id: '@vue/cli-service', + apply: () => {}, + options: { bare: true } + }, + { + id: 'router', + apply: () => {}, + options: {} + } + ]) + + const spec = files['tests/unit/example.spec.ts'] + expect(spec).toMatch(`const wrapper = mount(App,`) + expect(spec).toMatch(`expect(wrapper.text()).to.include(\`Welcome to Your Vue.js App\`)`) +}) diff --git a/packages/@vue/cli-plugin-unit-mocha/generator/index.js b/packages/@vue/cli-plugin-unit-mocha/generator/index.js index cadf62d8f8..88cea45bb9 100644 --- a/packages/@vue/cli-plugin-unit-mocha/generator/index.js +++ b/packages/@vue/cli-plugin-unit-mocha/generator/index.js @@ -3,7 +3,8 @@ module.exports = (api, options, rootOptions, invoking) => { api.render('./template', { isVue3, - hasTS: api.hasPlugin('typescript') + hasTS: api.hasPlugin('typescript'), + hasRouter: api.hasPlugin('router') }) api.extendPackage({ diff --git a/packages/@vue/cli-plugin-unit-mocha/generator/template/tests/unit/example.spec.js b/packages/@vue/cli-plugin-unit-mocha/generator/template/tests/unit/example.spec.js index 12bbb8c152..50d8c04882 100644 --- a/packages/@vue/cli-plugin-unit-mocha/generator/template/tests/unit/example.spec.js +++ b/packages/@vue/cli-plugin-unit-mocha/generator/template/tests/unit/example.spec.js @@ -1,6 +1,10 @@ <%_ if (!hasTS) { _%> import { expect } from 'chai' +<%_ if (!rootOptions.bare || !hasRouter) { _%> import { shallowMount } from '@vue/test-utils' +<%_ } else { _%> +import { mount, createLocalVue } from '@vue/test-utils' +<%_ } _%> <%_ if (!rootOptions.bare) { _%> import HelloWorld from '@/components/HelloWorld.vue' @@ -19,6 +23,7 @@ describe('HelloWorld.vue', () => { }) <%_ } else { _%> import App from '@/App.vue' +<%_ if (!hasRouter) { _%> describe('App', () => { it('should work', () => { @@ -26,5 +31,24 @@ describe('App', () => { expect(wrapper.text()).to.include(`Welcome to Your Vue.js App`) }) }) + +<%_ } else {_%> +import VueRouter from 'vue-router' +import router from '@/router' + +const localVue = createLocalVue() +localVue.use(VueRouter) + +describe('App', () => { + it('should render default route', () => { + const wrapper = mount(App, { + localVue, + router + }) + expect(wrapper.text()).to.include(`Welcome to Your Vue.js App`) + }) +}) + +<%_ } _%> <%_ } _%> <%_ } _%> diff --git a/packages/@vue/cli-plugin-unit-mocha/generator/template/tests/unit/example.spec.ts b/packages/@vue/cli-plugin-unit-mocha/generator/template/tests/unit/example.spec.ts index b218903b4b..9b2de2d60c 100644 --- a/packages/@vue/cli-plugin-unit-mocha/generator/template/tests/unit/example.spec.ts +++ b/packages/@vue/cli-plugin-unit-mocha/generator/template/tests/unit/example.spec.ts @@ -1,6 +1,10 @@ <%_ if (hasTS) { _%> import { expect } from 'chai' +<%_ if (!rootOptions.bare || !hasRouter) { _%> import { shallowMount } from '@vue/test-utils' +<%_ } else { _%> +import { mount, createLocalVue } from '@vue/test-utils' +<%_ } _%> <%_ if (!rootOptions.bare) { _%> import HelloWorld from '@/components/HelloWorld.vue' @@ -19,6 +23,7 @@ describe('HelloWorld.vue', () => { }) <%_ } else { _%> import App from '@/App.vue' +<%_ if (!hasRouter) { _%> describe('App', () => { it('should work', () => { @@ -26,5 +31,24 @@ describe('App', () => { expect(wrapper.text()).to.include(`Welcome to Your Vue.js + TypeScript App`) }) }) + +<%_ } else {_%> +import VueRouter from 'vue-router' +import router from '@/router' + +const localVue = createLocalVue() +localVue.use(VueRouter) + +describe('App', () => { + it('should render default route', () => { + const wrapper = mount(App, { + localVue, + router + }) + expect(wrapper.text()).to.include(`Welcome to Your Vue.js App`) + }) +}) + +<%_ } _%> <%_ } _%> <%_ } _%> From 34c09dc80344c7fa6f5614c110060f2823de3462 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Tue, 8 Sep 2020 19:44:08 +0800 Subject: [PATCH 12/14] fix: fix duplicate id="app" in Vue 3 project template (#5852) closes #5813 --- .../__tests__/routerGenerator.spec.js | 2 + .../generator/template-vue3/src/App.vue | 63 +++++++++++++++++++ .../cli-service/__tests__/generator.spec.js | 2 + packages/@vue/cli-service/generator/index.js | 4 +- .../generator/template/src/App.vue | 9 +++ .../generator/template/src/main.js | 2 +- 6 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 packages/@vue/cli-plugin-router/generator/template-vue3/src/App.vue diff --git a/packages/@vue/cli-plugin-router/__tests__/routerGenerator.spec.js b/packages/@vue/cli-plugin-router/__tests__/routerGenerator.spec.js index 2cf76c8207..b9121c2a3b 100644 --- a/packages/@vue/cli-plugin-router/__tests__/routerGenerator.spec.js +++ b/packages/@vue/cli-plugin-router/__tests__/routerGenerator.spec.js @@ -85,6 +85,8 @@ test('use with Vue 3', async () => { expect(files['src/main.js']).toMatch('.use(router)') + expect(files['src/App.vue']).not.toMatch('
') + expect(pkg.dependencies).toHaveProperty('vue-router') expect(pkg.dependencies['vue-router']).toMatch('^4') }) diff --git a/packages/@vue/cli-plugin-router/generator/template-vue3/src/App.vue b/packages/@vue/cli-plugin-router/generator/template-vue3/src/App.vue new file mode 100644 index 0000000000..1ca554712f --- /dev/null +++ b/packages/@vue/cli-plugin-router/generator/template-vue3/src/App.vue @@ -0,0 +1,63 @@ +--- +extend: '@vue/cli-service/generator/template/src/App.vue' +replace: + - !!js/regexp /