From 148b42459af825dc20b3e0f626c66717f0a823f9 Mon Sep 17 00:00:00 2001 From: fangbinwei Date: Mon, 6 Apr 2020 00:27:34 +0800 Subject: [PATCH 01/13] feat(cli-service): add declaration for PluginAPI fix #5324 --- packages/@vue/cli-service/package.json | 2 + .../cli-service/types/cli-service-test.ts | 63 +++++++++ packages/@vue/cli-service/types/index.d.ts | 123 ++++++++++++++++++ packages/@vue/cli-service/types/tsconfig.json | 23 ++++ yarn.lock | 87 ++++++++++++- 5 files changed, 296 insertions(+), 2 deletions(-) create mode 100644 packages/@vue/cli-service/types/cli-service-test.ts create mode 100644 packages/@vue/cli-service/types/tsconfig.json diff --git a/packages/@vue/cli-service/package.json b/packages/@vue/cli-service/package.json index 8c5b304bc8..eae81610cc 100644 --- a/packages/@vue/cli-service/package.json +++ b/packages/@vue/cli-service/package.json @@ -26,6 +26,8 @@ "@intervolga/optimize-cssnano-plugin": "^1.0.5", "@soda/friendly-errors-webpack-plugin": "^1.7.1", "@soda/get-current-script": "^1.0.0", + "@types/minimist": "^1.2.0", + "@types/webpack-dev-server": "^3.10.1", "@vue/cli-overlay": "^4.3.0", "@vue/cli-plugin-router": "^4.3.0", "@vue/cli-plugin-vuex": "^4.3.0", diff --git a/packages/@vue/cli-service/types/cli-service-test.ts b/packages/@vue/cli-service/types/cli-service-test.ts new file mode 100644 index 0000000000..626f7725fe --- /dev/null +++ b/packages/@vue/cli-service/types/cli-service-test.ts @@ -0,0 +1,63 @@ +import { PluginAPI } from '@vue/cli-service' + +export = (api: PluginAPI) => { + const version = api.version + api.assertVersion(4) + api.assertVersion('^100') + api.getCwd() + api.resolve('src/main.js') + api.hasPlugin('eslint') + api.registerCommand( + 'lint', + { + description: 'lint and fix source files', + usage: 'vue-cli-service lint [options] [...files]', + options: { + '--format [formatter]': 'specify formatter (default: codeframe)' + }, + details: 'For more options, see https://eslint.org/docs/user-guide/command-line-interface#options' + }, + args => { + require('./lint')(args, api) + } + ) + api.registerCommand('lint', args => {}) + + api.chainWebpack(webpackConfig => { + if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test') { + webpackConfig.devtool('cheap-module-eval-source-map') + + webpackConfig.plugin('hmr').use(require('webpack/lib/HotModuleReplacementPlugin')) + + webpackConfig.output.globalObject(`(typeof self !== 'undefined' ? self : this)`) + } + }) + + api.configureWebpack(config => { + config.output = { + path: 'test-dist-2' + } + }) + + api.configureWebpack(config => { + return { + devtool: config.devtool ? config.devtool : 'source-map' + } + }) + + api.resolveWebpackConfig() + + api.resolveWebpackConfig(api.resolveChainableWebpackConfig()) + + const { cacheIdentifier, cacheDirectory } = api.genCacheConfig( + 'babel-loader', + { + '@babel/core': require('@babel/core/package.json').version, + '@vue/babel-preset-app': require('@vue/babel-preset-app/package.json').version, + 'babel-loader': require('babel-loader/package.json').version, + modern: !!process.env.VUE_CLI_MODERN_BUILD, + browserslist: api.service.pkg.browserslist + }, + ['babel.config.js', '.browserslistrc'] + ) +} diff --git a/packages/@vue/cli-service/types/index.d.ts b/packages/@vue/cli-service/types/index.d.ts index d91403bdf8..3874a2e89d 100644 --- a/packages/@vue/cli-service/types/index.d.ts +++ b/packages/@vue/cli-service/types/index.d.ts @@ -1 +1,124 @@ +// Users who do not have --allowSyntheticDefaultExports or --esModuleInterop will get different behavior +// https://github.com/Microsoft/dtslint/blob/master/docs/no-import-default-of-export-equals.md +import minimist = require('minimist') +import ChainableConfig = require('webpack-chain') +import webpack = require('webpack') +import WebpackDevServer = require('webpack-dev-server') +import express = require('express') // @types/webpack-dev-server depends on @types/express + +type RegisterCommandFn = (args: minimist.ParsedArgs, rawArgv: string[]) => any + +type RegisterCommandOpts = Partial<{ + description: string + usage: string + options: { + [flags: string]: string + } + details: string +}> + +type WebpackChainFn = (chainableConfig: ChainableConfig) => void + +type webpackRawConfigFn = ((config: webpack.Configuration) => webpack.Configuration | void) | webpack.Configuration + +type DevServerConfigFn = (app: express.Application, server: WebpackDevServer) => void + +interface CacheConfig { + cacheDirectory: string + cacheIdentifier: string +} +export class PluginAPI { + id: string + + service: any + + get version(): string + + assertVersion(range: number | string): void + + /** + * Current working directory. + */ + getCwd(): string + + /** + * Resolve path for a project. + * + * @param _path - Relative path from project root + * @return The resolved absolute path. + */ + resolve(_path: string): string + + /** + * Check if the project has a given plugin. + * + * @param id - Plugin id, can omit the (@vue/|vue-|@scope/vue)-cli-plugin- prefix + * @return `boolean` + */ + hasPlugin(id: string): boolean + + /** + * Register a command that will become available as `vue-cli-service [name]`. + * + * @param name + * @param [opts] + * @param fn + */ + registerCommand(name: string, fn: RegisterCommandFn): void + registerCommand(name: string, opts: RegisterCommandOpts, fn: RegisterCommandFn): void + + /** + * Register a function that will receive a chainable webpack config + * the function is lazy and won't be called until `resolveWebpackConfig` is + * called + * + * @param fn + */ + chainWebpack(fn: WebpackChainFn): void + + /** + * Register + * - a webpack configuration object that will be merged into the config + * OR + * - a function that will receive the raw webpack config. + * the function can either mutate the config directly or return an object + * that will be merged into the config. + * + * @param fn + */ + configureWebpack(fn: webpackRawConfigFn): void + + /** + * Register a dev serve config function. It will receive the express `app` + * instance of the dev server. + * + * @param fn + */ + configureDevServer(fn: DevServerConfigFn): void + + /** + * Resolve the final raw webpack config, that will be passed to webpack. + * + * @param [chainableConfig] + * @return Raw webpack config. + */ + resolveWebpackConfig(chainableConfig?: ChainableConfig): webpack.Configuration + + /** + * Resolve an intermediate chainable webpack config instance, which can be + * further tweaked before generating the final raw webpack config. + * You can call this multiple times to generate different branches of the + * base webpack config. + * See https://github.com/mozilla-neutrino/webpack-chain + * + * @return ChainableWebpackConfig + */ + resolveChainableWebpackConfig(): ChainableConfig + + /** + * Generate a cache identifier from a number of variables + */ + genCacheConfig(id: string, partialIdentifier: any, configFiles?: object | object[]): CacheConfig +} + export { ProjectOptions, ConfigFunction } from './ProjectOptions' diff --git a/packages/@vue/cli-service/types/tsconfig.json b/packages/@vue/cli-service/types/tsconfig.json new file mode 100644 index 0000000000..210259de31 --- /dev/null +++ b/packages/@vue/cli-service/types/tsconfig.json @@ -0,0 +1,23 @@ + +{ + "files": [ + "cli-service-test.ts", + "index.d.ts" + ], + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "esModuleInterop": true, + "strictFunctionTypes": true, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": ".", + "skipLibCheck": true + } +} diff --git a/yarn.lock b/yarn.lock index f32e167aa6..1ddb2caaac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2677,6 +2677,11 @@ dependencies: "@types/node" "*" +"@types/anymatch@*": + version "1.3.1" + resolved "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== + "@types/babel__core@^7.1.0": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30" @@ -2736,6 +2741,14 @@ resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@types/connect-history-api-fallback@*": + version "1.3.3" + resolved "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.3.tgz#4772b79b8b53185f0f4c9deab09236baf76ee3b4" + integrity sha512-7SxFCd+FLlxCfwVwbyPxbR4khL9aNikJhrorw8nUIOqeuooc9gifBuDQOJw5kzN7i6i3vLn9G8Wde/4QDihpYw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + "@types/connect@*": version "3.4.33" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" @@ -2818,6 +2831,22 @@ resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.1.tgz#d775e93630c2469c2f980fc27e3143240335db3b" integrity sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ== +"@types/http-proxy-middleware@*": + version "0.19.3" + resolved "https://registry.npmjs.org/@types/http-proxy-middleware/-/http-proxy-middleware-0.19.3.tgz#b2eb96fbc0f9ac7250b5d9c4c53aade049497d03" + integrity sha512-lnBTx6HCOUeIJMLbI/LaL5EmdKLhczJY5oeXZpX/cXE4rRqb3RmV7VcMpiEfYkmTjipv3h7IAyIINe4plEv7cA== + dependencies: + "@types/connect" "*" + "@types/http-proxy" "*" + "@types/node" "*" + +"@types/http-proxy@*": + version "1.17.4" + resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.4.tgz#e7c92e3dbe3e13aa799440ff42e6d3a17a9d045b" + integrity sha512-IrSHl2u6AWXduUaDLqYpt45tLVCtYv7o4Z0s1KghBCDgIIS9oW5K1H8mZG/A2CfeLdEa7rTd1ACOiHBc1EMT2Q== + dependencies: + "@types/node" "*" + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" @@ -2889,6 +2918,11 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== +"@types/minimist@^1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6" + integrity sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY= + "@types/mocha@^5.2.6": version "5.2.7" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea" @@ -2939,6 +2973,11 @@ resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47" integrity sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg== +"@types/source-list-map@*": + version "0.1.2" + resolved "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== + "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" @@ -2954,11 +2993,55 @@ resolved "https://registry.yarnpkg.com/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz#9aa30c04db212a9a0649d6ae6fd50accc40748a1" integrity sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ== +"@types/tapable@*": + version "1.0.5" + resolved "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz#9adbc12950582aa65ead76bffdf39fe0c27a3c02" + integrity sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ== + +"@types/uglify-js@*": + version "3.0.5" + resolved "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.0.5.tgz#2c70d5c68f6e002e3b2e4f849adc5f162546f633" + integrity sha512-L7EbSkhSaWBpkl+PZAEAqZTqtTeIsq7s/oX/q0LNnxxJoRVKQE0T81XDVyaxjiiKQwiV2vhVeYRqxdRNqGOGJw== + dependencies: + source-map "^0.6.1" + +"@types/webpack-dev-server@^3.10.1": + version "3.10.1" + resolved "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-3.10.1.tgz#93b7133cc9dab1ca1b76659f5ef8b763ad54c28a" + integrity sha512-2nwwQ/qHRghUirvG/gEDkOQDa+d881UTJM7EG9ok5KNaYCjYVvy7fdaO528Lcym9OQDn75SvruPYVVvMJxqO0g== + dependencies: + "@types/connect-history-api-fallback" "*" + "@types/express" "*" + "@types/http-proxy-middleware" "*" + "@types/serve-static" "*" + "@types/webpack" "*" + "@types/webpack-env@^1.15.1": version "1.15.1" resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.1.tgz#c8e84705e08eed430b5e15b39c65b0944e4d1422" integrity sha512-eWN5ElDTeBc5lRDh95SqA8x18D0ll2pWudU3uWiyfsRmIZcmUXpEsxPU+7+BsdCrO2vfLRC629u/MmjbmF+2tA== +"@types/webpack-sources@*": + version "0.1.7" + resolved "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz#0a330a9456113410c74a5d64180af0cbca007141" + integrity sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw== + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.6.1" + +"@types/webpack@*": + version "4.41.10" + resolved "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.10.tgz#2e1f6b3508a249854efe3dcc7690905ac5ee10be" + integrity sha512-vIy0qaq8AjOjZLuFPqpo7nAJzcoVXMdw3mvpNN07Uvdy0p1IpJeLNBe3obdRP7FX2jIusDE7z1pZa0A6qYUgnA== + dependencies: + "@types/anymatch" "*" + "@types/node" "*" + "@types/tapable" "*" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + source-map "^0.6.0" + "@types/ws@^6.0.0": version "6.0.4" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.4.tgz#7797707c8acce8f76d8c34b370d4645b70421ff1" @@ -15448,7 +15531,7 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -puppeteer@1.11.0, puppeteer@^1.11.0: +puppeteer@^1.11.0: version "1.11.0" resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-1.11.0.tgz#63cdbe12b07275cd6e0b94bce41f3fcb20305770" integrity sha512-iG4iMOHixc2EpzqRV+pv7o3GgmU2dNYEMkvKwSaQO/vMZURakwSOn/EYJ6OIRFYOque1qorzIBvrytPIQB3YzQ== @@ -18823,7 +18906,7 @@ vue-router@^3.1.6: resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.1.6.tgz#45f5a3a3843e31702c061dd829393554e4328f89" integrity sha512-GYhn2ynaZlysZMkFE5oCHRUTqE8BWs/a9YbKpNLi0i7xD6KG1EzDqpHQmv1F5gXjr8kL5iIVS8EOtRaVUEXTqA== -vue-server-renderer@^2.6.10, vue-server-renderer@^2.6.11: +vue-server-renderer@^2.6.10: version "2.6.11" resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.6.11.tgz#be8c9abc6aacc309828a755c021a05fc474b4bc3" integrity sha512-V3faFJHr2KYfdSIalL+JjinZSHYUhlrvJ9pzCIjjwSh77+pkrsXpK4PucdPcng57+N77pd1LrKqwbqjQdktU1A== From fc5fc9f12e405d2b4c3af314b21beabdc98fefb2 Mon Sep 17 00:00:00 2001 From: fangbinwei Date: Mon, 6 Apr 2020 00:30:00 +0800 Subject: [PATCH 02/13] feat(cli): add declaration for GeneratorAPI,PromptModuleAPI fix #5324 --- packages/@vue/cli/package.json | 4 + packages/@vue/cli/types/cli-test.ts | 183 +++++++++++++++++++++ packages/@vue/cli/types/index.d.ts | 224 ++++++++++++++++++++++++++ packages/@vue/cli/types/tsconfig.json | 23 +++ yarn.lock | 45 +++++- 5 files changed, 478 insertions(+), 1 deletion(-) create mode 100644 packages/@vue/cli/types/cli-test.ts create mode 100644 packages/@vue/cli/types/index.d.ts create mode 100644 packages/@vue/cli/types/tsconfig.json diff --git a/packages/@vue/cli/package.json b/packages/@vue/cli/package.json index e62a12112f..0f018ba7f3 100644 --- a/packages/@vue/cli/package.json +++ b/packages/@vue/cli/package.json @@ -5,6 +5,7 @@ "bin": { "vue": "bin/vue.js" }, + "types": "types/index.d.ts", "repository": { "type": "git", "url": "git+https://github.com/vuejs/vue-cli.git", @@ -24,6 +25,9 @@ "access": "public" }, "dependencies": { + "@types/ejs": "^2.7.0", + "@types/inquirer": "^6.5.0", + "@types/jscodeshift": "^0.7.0", "@vue/cli-shared-utils": "^4.3.0", "@vue/cli-ui": "^4.3.0", "@vue/cli-ui-addon-webpack": "^4.3.0", diff --git a/packages/@vue/cli/types/cli-test.ts b/packages/@vue/cli/types/cli-test.ts new file mode 100644 index 0000000000..ecb78b8481 --- /dev/null +++ b/packages/@vue/cli/types/cli-test.ts @@ -0,0 +1,183 @@ +import { GeneratorAPI, PromptModuleAPI } from '@vue/cli' + +const testPromptAPI = (cli: PromptModuleAPI) => { + cli.injectFeature({ + name: 'Babel', + value: 'babel', + short: 'Babel', + // descriptions: 'Transpile modern JavaScript to older versions (for compatibility)', + // link: 'https://babeljs.io/', + checked: true + }) + + cli.injectOptionForPrompt('customBar', { + name: 'barChoice', + value: 'barChoice' + }) + cli.onPromptComplete<{ features: string[]; useTsWithBabel: boolean }>((answers, options) => { + if (answers.features.includes('ts')) { + if (!answers.useTsWithBabel) { + return + } + } else if (!answers.features.includes('babel')) { + return + } + options.plugins['@vue/cli-plugin-babel'] = {} + }) + + cli.injectFeature({ + name: 'CSS Pre-processors', + value: 'css-preprocessor' + // description: 'Add support for CSS pre-processors like Sass, Less or Stylus', + // link: 'https://cli.vuejs.org/guide/css.html' + }) + + const notice = 'PostCSS, Autoprefixer and CSS Modules are supported by default' + cli.injectPrompt<{ features: string[] }>({ + name: 'cssPreprocessor', + when: answers => answers.features.includes('css-preprocessor'), + type: 'list', + message: `Pick a CSS pre-processor${process.env.VUE_CLI_API_MODE ? '' : ` (${notice})`}:`, + // description: `${notice}.`, + choices: [ + { + name: 'Sass/SCSS (with dart-sass)', + value: 'dart-sass' + }, + { + name: 'Sass/SCSS (with node-sass)', + value: 'node-sass' + }, + { + name: 'Less', + value: 'less' + }, + { + name: 'Stylus', + value: 'stylus' + } + ] + }) +} + +export = (api: GeneratorAPI) => { + const version = api.cliVersion + const cliServiceVersion = api.cliServiceVersion + api.assertCliServiceVersion(4) + api.assertCliServiceVersion('^100') + api.hasPlugin('eslint') + api.hasPlugin('eslint', '^6.0.0') + + api.addConfigTransform('fooConfig', { + file: { + json: ['foo.config.json'] + } + }) + + api.extendPackage({ + fooConfig: { + bar: 42 + }, + dependencies: { + 'vue-router-layout': '^0.1.2' + } + }) + api.extendPackage(() => ({ + fooConfig: { + bar: 42 + }, + dependencies: { + 'vue-router-layout': '^0.1.2' + } + })) + api.extendPackage( + { + fooConfig: { + bar: 42 + }, + dependencies: { + 'vue-router-layout': '^0.1.2' + } + }, + true + ) + api.extendPackage( + { + fooConfig: { + bar: 42 + }, + dependencies: { + 'vue-router-layout': '^0.1.2' + } + }, + { + merge: true, + prune: true, + warnIncompatibleVersions: true + } + ) + + api.render('./template') + + api.render( + './template', + { + hasTS: api.hasPlugin('typescript'), + hasESLint: api.hasPlugin('eslint') + }, + { + strict: true, + rmWhitespace: false + } + ) + + api.render((files, render) => { + files['foo2.js'] = render('foo(<%- n %>)', { n: 3 }) + files['bar/bar2.js'] = render('bar(<%- n %>)', { n: 3 }, { rmWhitespace: false }) + }) + + api.postProcessFiles(files => { + delete files['src/test.js'] + }) + + api.onCreateComplete(() => { + console.log('complete') + }) + + api.afterInvoke(() => { + console.log('after invoke') + }) + + api.afterAnyInvoke(() => { + console.log('after any invoke') + }) + + api.exitLog('msg') + api.exitLog('msg', 'error') + api.genJSConfig({ foo: 1 }) + + api.extendPackage({ + vue: { + publicPath: api.makeJSOnlyValue(`process.env.VUE_CONTEXT`) + } + }) + api.transformScript( + 'src/test.js', + (fileInfo, api, { additionalData }) => { + const j = api.jscodeshift + const root = j(fileInfo.source) + return root.toSource() + }, + { + additionalData: [] + } + ) + + api.injectImports('main.js', `import bar from 'bar'`) + + api.injectRootOptions('main.js', ['foo', 'bar']) + + api.resolve(api.entryFile) + + const isInvoking = api.invoking +} diff --git a/packages/@vue/cli/types/index.d.ts b/packages/@vue/cli/types/index.d.ts new file mode 100644 index 0000000000..ea7b3262dc --- /dev/null +++ b/packages/@vue/cli/types/index.d.ts @@ -0,0 +1,224 @@ +import { DistinctQuestion, CheckboxChoiceOptions, Answers, ChoiceOptions } from 'inquirer' +import { Parser, Transform } from 'jscodeshift' +import ejs from 'ejs' + +interface RenderFile { + [path: string]: string | Buffer +} + +type FileMiddleware = (files: RenderFile, render: typeof ejs.render) => void +type PostProcessFilesCallback = (files: RenderFile) => void + +type RenderSource = string | RenderFile + +type TransformModule = Transform & { + default?: Transform + parser?: string | Parser +} +interface TransformOptions { + [prop: string]: any + parser?: string | Parser +} +interface __expressionFn { + (): void + __expression: string +} + +interface OnPromptCompleteCb { + ( + answers: T, + options: { + useConfigFiles: boolean + plugins: Record + }, + ): void +} +interface Feature extends CheckboxChoiceOptions { + [prop: string]: any +} + +type GeneratorRootOptions = Partial<{ + [props: string]: any + projectName: string + useConfigFiles: boolean + plugins: object + configs: object + cssPreprocessor: 'sass' | 'dart-sass' | 'node-sass' | 'less' | 'stylus' +}> +class PromptModuleAPI { + /** inject checkbox choice for feature prompt. */ + injectFeature(feature: CheckboxChoiceOptions): void + + injectPrompt(prompt: DistinctQuestion): void + + injectOptionForPrompt(name: string, option: ChoiceOptions): void + + /** run cb registered by prompt modules to finalize the preset. */ + onPromptComplete(cb: OnPromptCompleteCb): void +} + +class GeneratorAPI { + /** + * Resolve path for a project. + * + * @param _paths - A sequence of relative paths or path segments + * @return The resolved absolute path, calculated based on the current project root. + */ + resolve(..._paths: string[]): string + + get cliVersion(): string + + assertCliVersion(range: number | string): void + + get cliServiceVersion(): string + + assertCliServiceVersion(range: number | string): void + + /** + * Check if the project has a given plugin. + * + * @param id - Plugin id, can omit the (@vue/|vue-|@scope/vue)-cli-plugin- prefix + * @param version - Plugin version. Defaults to '' + * @return `boolean` + */ + hasPlugin(id: string, version?: string): boolean + + /** + * Configure how config files are extracted. + * + * @param key - Config key in package.json + * @param options - Options + * @param options.file - File descriptor + * Used to search for existing file. + * Each key is a file type (possible values: ['js', 'json', 'yaml', 'lines']). + * The value is a list of filenames. + * Example: + * { + * js: ['.eslintrc.js'], + * json: ['.eslintrc.json', '.eslintrc'] + * } + * By default, the first filename will be used to create the config file. + */ + addConfigTransform(key: string, options: { file: { [type: string]: string[] } }): void + + /** + * Extend the package.json of the project. + * Also resolves dependency conflicts between plugins. + * Tool configuration fields may be extracted into standalone files before + * files are written to disk. + * + * @param fields - Fields to merge. + * @param [options] - Options for extending / merging fields. + * @param [options.prune=false] - Remove null or undefined fields + * from the object after merging. + * @param [options.merge=true] deep-merge nested fields, note + * that dependency fields are always deep merged regardless of this option. + * @param [options.warnIncompatibleVersions=true] Output warning + * if two dependency version ranges don't intersect. + */ + extendPackage( + fields: object | ((pkg: object) => object), + options?: + | { + prune?: boolean + merge?: boolean + warnIncompatibleVersions?: boolean + } + | boolean, + ): void + + /** + * Render template files into the virtual files tree object. + * + * @param source - + * Can be one of: + * - relative path to a directory; + * - Object hash of { sourceTemplate: targetFile } mappings; + * - a custom file middleware function. + * @param [additionalData] - additional data available to templates. + * @param [ejsOptions] - options for ejs. + */ + render(source: RenderSource, additionalData?: object, ejsOptions?: ejs.Options): void + render(source: FileMiddleware): void + + /** + * Push a file middleware that will be applied after all normal file + * middlewares have been applied. + * + * @param cb + */ + postProcessFiles(cb: PostProcessFilesCallback): void + + /** + * Push a callback to be called when the files have been written to disk. + * + * @param cb + */ + onCreateComplete(cb: (...args: any[]) => any): void + + /** + * same to `onCreateComplete`. + * + * @param cb + */ + afterInvoke(cb: (...args: any[]) => any): void + + /** + * Push a callback to be called when the files have been written to disk + * from non invoked plugins + * + * @param cb + */ + afterAnyInvoke(cb: (...args: any[]) => any): void + + /** + * Add a message to be printed when the generator exits (after any other standard messages). + * + * @param msg String or value to print after the generation is completed + * @param [type='log'] Type of message + */ + exitLog(msg: any, type?: 'log' | 'info' | 'done' | 'warn' | 'error'): void + + /** + * convenience method for generating a js config file from json + */ + genJSConfig(value: any): string + + /** + * Turns a string expression into executable JS for JS configs. + * @param str JS expression as a string + */ + makeJSOnlyValue(str: string): __expressionFn + + /** + * Run codemod on a script file or the script part of a .vue file + * @param file the path to the file to transform + * @param codemod the codemod module to run + * @param options additional options for the codemod + */ + transformScript(file: string, codemod: TransformModule, options?: TransformOptions): void + + /** + * Add import statements to a file. + */ + injectImports(file: string, imports: string | string[]): void + + /** + * Add options to the root Vue instance (detected by `new Vue`). + */ + injectRootOptions(file: string, options: string | string[]): void + + /** + * Get the entry file taking into account typescript. + * + */ + get entryFile(): 'src/main.ts' | 'src/main.js' + + /** + * Is the plugin being invoked? + * + */ + get invoking(): boolean +} + +export { PromptModuleAPI, GeneratorAPI, GeneratorRootOptions } diff --git a/packages/@vue/cli/types/tsconfig.json b/packages/@vue/cli/types/tsconfig.json new file mode 100644 index 0000000000..0940c7c7dd --- /dev/null +++ b/packages/@vue/cli/types/tsconfig.json @@ -0,0 +1,23 @@ + +{ + "files": [ + "cli-test.ts", + "index.d.ts" + ], + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "esModuleInterop": true, + "strictFunctionTypes": true, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": ".", + "skipLibCheck": true + } +} diff --git a/yarn.lock b/yarn.lock index 1ddb2caaac..4a4cae2904 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2773,6 +2773,11 @@ dependencies: "@types/express" "*" +"@types/ejs@^2.7.0": + version "2.7.0" + resolved "https://registry.npmjs.org/@types/ejs/-/ejs-2.7.0.tgz#bc84e083eae38f64a287a6dab9012bbe1d96e295" + integrity sha512-kM2g9Fdk/du24fKuuQhA/LBleFR4Z4JP2MVKpLxQQSzofF1uJ06D+c05zfLDAkkDO55aEeNwJih0gHrE/Ci20A== + "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" @@ -2847,6 +2852,14 @@ dependencies: "@types/node" "*" +"@types/inquirer@^6.5.0": + version "6.5.0" + resolved "https://registry.npmjs.org/@types/inquirer/-/inquirer-6.5.0.tgz#b83b0bf30b88b8be7246d40e51d32fe9d10e09be" + integrity sha512-rjaYQ9b9y/VFGOpqBEXRavc3jh0a+e6evAbI31tMda8VlPaSy0AZJfXsvmIe3wklc7W6C3zCSfleuMXR7NOyXw== + dependencies: + "@types/through" "*" + rxjs "^6.4.0" + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" @@ -2874,6 +2887,14 @@ dependencies: jest-diff "^24.3.0" +"@types/jscodeshift@^0.7.0": + version "0.7.0" + resolved "https://registry.npmjs.org/@types/jscodeshift/-/jscodeshift-0.7.0.tgz#796bf05a420c5d3e95b196b1fa01cc75f10c41b2" + integrity sha512-W59Y/fnztfJ/5gP4m2ZSWHvb4JPl9SXXn5ne3/6kYP5twRek9DTyKB6xbPIeg0RXbcNTHPBXHNLcKw3AlCrjTw== + dependencies: + ast-types "0.12.1" + recast "0.17.2" + "@types/json-schema@^7.0.3": version "7.0.4" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" @@ -2998,6 +3019,13 @@ resolved "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz#9adbc12950582aa65ead76bffdf39fe0c27a3c02" integrity sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ== +"@types/through@*": + version "0.0.30" + resolved "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz#e0e42ce77e897bd6aead6f6ea62aeb135b8a3895" + integrity sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg== + dependencies: + "@types/node" "*" + "@types/uglify-js@*": version "3.0.5" resolved "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.0.5.tgz#2c70d5c68f6e002e3b2e4f849adc5f162546f633" @@ -4662,6 +4690,11 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +ast-types@0.12.1: + version "0.12.1" + resolved "https://registry.npmjs.org/ast-types/-/ast-types-0.12.1.tgz#55d3737a8a68e1ccde131067005ce7ee3dd42b99" + integrity sha512-H2izJAyT2xwew4TxShpmxe6f9R5hHgJQy1QloLiUC2yrJMtyraBWNJL7903rpeCY9keNUipORR/zIUC2XcYKng== + ast-types@0.13.2, ast-types@0.x.x, ast-types@^0.13.0: version "0.13.2" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48" @@ -15345,7 +15378,7 @@ prismjs@^1.13.0, prismjs@^1.19.0: optionalDependencies: clipboard "^2.0.0" -private@^0.1.6, private@^0.1.8: +private@^0.1.6, private@^0.1.8, private@~0.1.5: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== @@ -15851,6 +15884,16 @@ realpath-native@^1.1.0: dependencies: util.promisify "^1.0.0" +recast@0.17.2: + version "0.17.2" + resolved "https://registry.npmjs.org/recast/-/recast-0.17.2.tgz#f18f18cf20bf3fad4522621a7f9c2ada37276814" + integrity sha512-YHFvn4rBXl8eIjALjUiOV/AP3xFpyGNGNHDw9mAncAWuIdgnBKjbZQ9+P3VlsKcNaNapRVFlTEX1dvDRlYwyxg== + dependencies: + ast-types "0.12.1" + esprima "~4.0.0" + private "~0.1.5" + source-map "~0.6.1" + recast@^0.18.0, recast@^0.18.1: version "0.18.5" resolved "https://registry.yarnpkg.com/recast/-/recast-0.18.5.tgz#9d5adbc07983a3c8145f3034812374a493e0fe4d" From 49e8ab14b1e84597abe82297f3442e8ea7037260 Mon Sep 17 00:00:00 2001 From: fangbinwei Date: Mon, 6 Apr 2020 00:34:04 +0800 Subject: [PATCH 03/13] feat(cli-test-utils): add declaration for test utilities fix #5324 --- .../cli-test-utils/assertPromptModule.d.ts | 16 ++++ .../@vue/cli-test-utils/createJSONServer.d.ts | 10 ++ .../@vue/cli-test-utils/createServer.d.ts | 13 +++ .../cli-test-utils/createTestProject.d.ts | 45 +++++++++ .../cli-test-utils/generateWithPlugin.d.ts | 32 +++++++ .../@vue/cli-test-utils/launchPuppeteer.d.ts | 12 +++ packages/@vue/cli-test-utils/package.json | 4 + .../cli-test-utils/serveWithPuppeteer.d.ts | 31 +++++++ .../types/cli-test-utils-test.ts | 92 +++++++++++++++++++ .../@vue/cli-test-utils/types/tsconfig.json | 22 +++++ yarn.lock | 29 ++++++ 11 files changed, 306 insertions(+) create mode 100644 packages/@vue/cli-test-utils/assertPromptModule.d.ts create mode 100644 packages/@vue/cli-test-utils/createJSONServer.d.ts create mode 100644 packages/@vue/cli-test-utils/createServer.d.ts create mode 100644 packages/@vue/cli-test-utils/createTestProject.d.ts create mode 100644 packages/@vue/cli-test-utils/generateWithPlugin.d.ts create mode 100644 packages/@vue/cli-test-utils/launchPuppeteer.d.ts create mode 100644 packages/@vue/cli-test-utils/serveWithPuppeteer.d.ts create mode 100644 packages/@vue/cli-test-utils/types/cli-test-utils-test.ts create mode 100644 packages/@vue/cli-test-utils/types/tsconfig.json diff --git a/packages/@vue/cli-test-utils/assertPromptModule.d.ts b/packages/@vue/cli-test-utils/assertPromptModule.d.ts new file mode 100644 index 0000000000..2671ded9e5 --- /dev/null +++ b/packages/@vue/cli-test-utils/assertPromptModule.d.ts @@ -0,0 +1,16 @@ +import { PromptModuleAPI } from '@vue/cli' + +interface CliPromptModule { + (api: PromptModuleAPI): void +} + +declare function assertPromptModule( + module: CliPromptModule | CliPromptModule[], + expectedPrompts: object[], + expectedOptions: object, + opts?: { + pluginsOnly?: boolean + }, +): Promise + +export = assertPromptModule diff --git a/packages/@vue/cli-test-utils/createJSONServer.d.ts b/packages/@vue/cli-test-utils/createJSONServer.d.ts new file mode 100644 index 0000000000..ce1e1df341 --- /dev/null +++ b/packages/@vue/cli-test-utils/createJSONServer.d.ts @@ -0,0 +1,10 @@ +import { Application } from 'express' + +declare function createJSONServer( + /** + * Either a path to a json file (e.g. 'db.json') or an object in memory + */ + data?: string | object, +): Application + +export = createJSONServer diff --git a/packages/@vue/cli-test-utils/createServer.d.ts b/packages/@vue/cli-test-utils/createServer.d.ts new file mode 100644 index 0000000000..87f0b5befa --- /dev/null +++ b/packages/@vue/cli-test-utils/createServer.d.ts @@ -0,0 +1,13 @@ +import http from 'http' + +type Options = { + [props: string]: any + /** + * Set a sub directory to be served + */ + root: string +} + +declare function createServer(options: Options): http.Server + +export = createServer diff --git a/packages/@vue/cli-test-utils/createTestProject.d.ts b/packages/@vue/cli-test-utils/createTestProject.d.ts new file mode 100644 index 0000000000..201b3b7583 --- /dev/null +++ b/packages/@vue/cli-test-utils/createTestProject.d.ts @@ -0,0 +1,45 @@ +import execa = require('execa') // execa@1.0.0 needs @types/execa +import { GeneratorRootOptions } from '@vue/cli' + +/** + * create project at path `cwd` + */ +declare function createTestProject( + /** + * project name + */ + name: string, + /** + * manual preset used to generate project. + * + * Example: + * { + * plugins: { + * '@vue/cli-plugin-babel': {} + * } + * } + */ + preset: GeneratorRootOptions, + cwd?: string | null, + /** + * if init git repo + * + * Default:`true` + */ + initGit?: boolean, +): Promise<{ + /** test project's root path */ + dir: string + /** test if project contains the file */ + has: (file: string) => boolean + /** read the content for the file */ + read: (file: string) => Promise + /** write file to project */ + write: (file: string, content: string) => Promise + /** execa command at root path of project */ + run: (command: string, args?: ReadonlyArray) => execa.ExecaChildProcess + /** delete the file of project */ + rm: (file: string) => Promise +}> + +export = createTestProject diff --git a/packages/@vue/cli-test-utils/generateWithPlugin.d.ts b/packages/@vue/cli-test-utils/generateWithPlugin.d.ts new file mode 100644 index 0000000000..c07df09473 --- /dev/null +++ b/packages/@vue/cli-test-utils/generateWithPlugin.d.ts @@ -0,0 +1,32 @@ +import { GeneratorAPI, GeneratorRootOptions } from '@vue/cli' + +type ApplyFn = ( + api: GeneratorAPI, + options: Record, + rootOptions: GeneratorRootOptions, + invoking: boolean, +) => any +interface Plugin { + /** package name from plugin */ + id: string + /** generator function from plugin */ + apply: ApplyFn + /** parameter passed to generator function */ + options: Record +} + +/** + * invoke generator function, and generate file tree in memory + */ +declare function generateWithPlugin( + plugin: Plugin | Plugin[], +): Promise<{ + /** package.json Object */ + pkg: object + /** virtual file tree, file path is the key of Object */ + files: { + [filePath: string]: string | Buffer + } +}> + +export = generateWithPlugin diff --git a/packages/@vue/cli-test-utils/launchPuppeteer.d.ts b/packages/@vue/cli-test-utils/launchPuppeteer.d.ts new file mode 100644 index 0000000000..1cb8383b56 --- /dev/null +++ b/packages/@vue/cli-test-utils/launchPuppeteer.d.ts @@ -0,0 +1,12 @@ +import { Browser, Page } from 'puppeteer' + +declare function launchPuppeteer( + url: string, +): Promise<{ + browser: Browser + page: Page + logs: string[] + requestUrls: string[] +}> + +export = launchPuppeteer diff --git a/packages/@vue/cli-test-utils/package.json b/packages/@vue/cli-test-utils/package.json index 9cde0915e4..1e3db3a7e3 100644 --- a/packages/@vue/cli-test-utils/package.json +++ b/packages/@vue/cli-test-utils/package.json @@ -22,6 +22,10 @@ "access": "public" }, "dependencies": { + "@types/execa": "^0.9.0", + "@types/express": "^4.17.4", + "@types/puppeteer": "^1.11.0", + "@vue/cli": "^4.3.0", "execa": "^1.0.0", "fs-extra": "^7.0.1", "json-server": "^0.15.0", diff --git a/packages/@vue/cli-test-utils/serveWithPuppeteer.d.ts b/packages/@vue/cli-test-utils/serveWithPuppeteer.d.ts new file mode 100644 index 0000000000..a18af5e6ee --- /dev/null +++ b/packages/@vue/cli-test-utils/serveWithPuppeteer.d.ts @@ -0,0 +1,31 @@ +import execa = require('execa') +import { Browser, Page } from 'puppeteer' + +interface Helpers { + getText: (selector: string) => Promise + hasElement: (selector: string) => Promise + hasClass: (selector: string, cls: string) => Promise +} + +interface Utils { + url: string + browser: Browser + page: Page + /** wait for hot replacement */ + nextUpdate: () => Promise + helpers: Helpers + requestUrls: string[] +} + +declare function serveWithPuppeteer( + serve: () => execa.ExecaChildProcess, + /** Function which executes test codes*/ + test: (arg: Utils) => any, + /** + * don't launch puppeteer. + * Defaults to `false`. + */ + noPuppeteer?: boolean, +): Promise + +export = serveWithPuppeteer diff --git a/packages/@vue/cli-test-utils/types/cli-test-utils-test.ts b/packages/@vue/cli-test-utils/types/cli-test-utils-test.ts new file mode 100644 index 0000000000..0b923314ba --- /dev/null +++ b/packages/@vue/cli-test-utils/types/cli-test-utils-test.ts @@ -0,0 +1,92 @@ +import assertPromptModule from '@vue/cli-test-utils/assertPromptModule' +import createJSONServer from '@vue/cli-test-utils/createJSONServer' +import createServer from '@vue/cli-test-utils/createServer' +import createTestProject from '@vue/cli-test-utils/createTestProject' +import generateWithPlugin from '@vue/cli-test-utils/generateWithPlugin' +import launchPuppeteer from '@vue/cli-test-utils/launchPuppeteer' +import serveWithPuppeteer from '@vue/cli-test-utils/serveWithPuppeteer' +import path from 'path' + +const expectedPrompts = [{ choose: 0 }] + +const expectedOptions = { + useConfigFiles: false, + plugins: { + foo: {} + } +} + +assertPromptModule( + api => { + api.injectFeature({ + name: 'Foo', + value: 'foo' + }) + api.injectFeature({ + name: 'Bar', + value: 'bar' + }) + api.onPromptComplete((answers, options) => { + if (answers.features.includes('foo')) { + options.plugins.foo = {} + } + }) + }, + expectedPrompts, + expectedOptions +) + +const mockServer1 = createJSONServer({ + posts: [{ id: 1, title: 'server-one', author: 'typicode' }] +}).listen(3000, () => {}) + +const server = createServer({ root: path.resolve(__dirname, 'temp') }) + +async function createTest() { + const project = await createTestProject( + 'eslint', + { + plugins: { + '@vue/cli-plugin-babel': {}, + '@vue/cli-plugin-eslint': { + config: 'airbnb', + lintOn: 'commit' + } + } + }, + null, + true + ) + const { dir, has, read, write, run, rm } = project + + if (!has('src/main.js')) return + + const main = await read('src/main.js') + + const updatedMain = main.replace(/;/g, '') + + await write('src/main.js', updatedMain) + + await project.rm(`src/test.js`) + + const { stdout } = await run('vue-cli-service lint') + + await serveWithPuppeteer( + () => project.run('vue-cli-service serve'), + async ({ url, browser, page, nextUpdate, helpers, requestUrls }) => { + await helpers.getText('h1') + } + ) +} + +async function testGenerate() { + const { pkg, files } = await generateWithPlugin({ + id: 'test-plugin', + apply: (api, options, rootOptions, invoking) => {}, + options: {} + }) +} + +async function testLaunchPuppeteer() { + const { browser, page, logs, requestUrls } = await launchPuppeteer(`http://localhost:8080/`) +} diff --git a/packages/@vue/cli-test-utils/types/tsconfig.json b/packages/@vue/cli-test-utils/types/tsconfig.json new file mode 100644 index 0000000000..8d12c6ad14 --- /dev/null +++ b/packages/@vue/cli-test-utils/types/tsconfig.json @@ -0,0 +1,22 @@ + +{ + "files": [ + "cli-test-utils-test.ts" + ], + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" + ], + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "esModuleInterop": true, + "strictFunctionTypes": true, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": ".", + "skipLibCheck": true + } +} diff --git a/yarn.lock b/yarn.lock index 4a4cae2904..93cc5278e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2788,6 +2788,13 @@ resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== +"@types/execa@^0.9.0": + version "0.9.0" + resolved "https://registry.npmjs.org/@types/execa/-/execa-0.9.0.tgz#9b025d2755f17e80beaf9368c3f4f319d8b0fb93" + integrity sha512-mgfd93RhzjYBUHHV532turHC2j4l/qxsF/PbfDmprHDEUHmNZGlDn1CEsulGK3AfsPdhkWzZQT/S/k0UGhLGsA== + dependencies: + "@types/node" "*" + "@types/express-serve-static-core@*": version "4.17.2" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.2.tgz#f6f41fa35d42e79dbf6610eccbb2637e6008a0cf" @@ -2805,6 +2812,16 @@ "@types/express-serve-static-core" "*" "@types/serve-static" "*" +"@types/express@^4.17.4": + version "4.17.4" + resolved "https://registry.npmjs.org/@types/express/-/express-4.17.4.tgz#e78bf09f3f530889575f4da8a94cd45384520aac" + integrity sha512-DO1L53rGqIDUEvOjJKmbMEQ5Z+BM2cIEPy/eV3En+s166Gz+FeuzRerxcab757u/U4v4XF4RYrZPmqKa+aY/2w== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/fs-capacitor@*": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/fs-capacitor/-/fs-capacitor-2.0.0.tgz#17113e25817f584f58100fb7a08eed288b81956e" @@ -2971,11 +2988,23 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== +"@types/puppeteer@^1.11.0": + version "1.20.4" + resolved "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-1.20.4.tgz#30cb0a4ee5394c420119cbdf9f079d6595a07f67" + integrity sha512-T/kFgyLnYWk0H94hxI0HbOLnqHvzBRpfS0F0oo9ESGI24oiC2fEjDcMbBjuK3wH7VLsaIsp740vVXVzR1dsMNg== + dependencies: + "@types/node" "*" + "@types/q@^1.5.1": version "1.5.2" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw== +"@types/qs@*": + version "6.9.1" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.1.tgz#937fab3194766256ee09fcd40b781740758617e7" + integrity sha512-lhbQXx9HKZAPgBkISrBcmAcMpZsmpe/Cd/hY7LGZS5OfkySUBItnPZHgQPssWYUET8elF+yCFBbP1Q0RZPTdaw== + "@types/range-parser@*": version "1.2.3" resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" From 2d916e4de76a3bc3663aa229a3fb1fb6f08d5b6b Mon Sep 17 00:00:00 2001 From: fangbinwei Date: Tue, 7 Apr 2020 01:00:44 +0800 Subject: [PATCH 04/13] fix(cli-test-utils): fix ts declaration the data written by fs.writeFile should be any --- packages/@vue/cli-test-utils/createJSONServer.d.ts | 11 +++++++++++ packages/@vue/cli-test-utils/createTestProject.d.ts | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/@vue/cli-test-utils/createJSONServer.d.ts b/packages/@vue/cli-test-utils/createJSONServer.d.ts index ce1e1df341..723b3a506b 100644 --- a/packages/@vue/cli-test-utils/createJSONServer.d.ts +++ b/packages/@vue/cli-test-utils/createJSONServer.d.ts @@ -3,6 +3,17 @@ import { Application } from 'express' declare function createJSONServer( /** * Either a path to a json file (e.g. 'db.json') or an object in memory + * + * Default: + *{ + * 'posts': [ + * { 'id': 1, 'title': 'json-server', 'author': 'typicode' } + * ], + * 'comments': [ + * { 'id': 1, 'body': 'some comment', 'postId': 1 } + * ], + * 'profile': { 'name': 'typicode' } + *} */ data?: string | object, ): Application diff --git a/packages/@vue/cli-test-utils/createTestProject.d.ts b/packages/@vue/cli-test-utils/createTestProject.d.ts index 201b3b7583..0edf09dbdc 100644 --- a/packages/@vue/cli-test-utils/createTestProject.d.ts +++ b/packages/@vue/cli-test-utils/createTestProject.d.ts @@ -20,6 +20,7 @@ declare function createTestProject( * } */ preset: GeneratorRootOptions, + /** `path.resolve(cwd, name)` will be the project's root directory */ cwd?: string | null, /** * if init git repo @@ -35,7 +36,7 @@ declare function createTestProject( /** read the content for the file */ read: (file: string) => Promise /** write file to project */ - write: (file: string, content: string) => Promise + write: (file: string, content: any) => Promise /** execa command at root path of project */ run: (command: string, args?: ReadonlyArray) => execa.ExecaChildProcess /** delete the file of project */ From f1ade5332997eb3e632b41082242abf6e02eb620 Mon Sep 17 00:00:00 2001 From: fangbinwei Date: Tue, 7 Apr 2020 18:02:56 +0800 Subject: [PATCH 05/13] fix(cli,cli-service,cli-test-utils): fix ts declaration compatible with esModuleInterop:false --- packages/@vue/cli-service/types/ProjectOptions.d.ts | 2 +- packages/@vue/cli-service/types/tsconfig.json | 3 ++- packages/@vue/cli-test-utils/createServer.d.ts | 2 +- packages/@vue/cli-test-utils/types/tsconfig.json | 6 +++--- packages/@vue/cli/types/index.d.ts | 6 +++--- packages/@vue/cli/types/tsconfig.json | 3 +-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/@vue/cli-service/types/ProjectOptions.d.ts b/packages/@vue/cli-service/types/ProjectOptions.d.ts index df7daa2ddf..0b77b42a18 100644 --- a/packages/@vue/cli-service/types/ProjectOptions.d.ts +++ b/packages/@vue/cli-service/types/ProjectOptions.d.ts @@ -1,4 +1,4 @@ -import ChainableWebpackConfig from 'webpack-chain' +import ChainableWebpackConfig = require('webpack-chain') import { WebpackOptions } from 'webpack/declarations/WebpackOptions' type PageEntry = string | string[]; diff --git a/packages/@vue/cli-service/types/tsconfig.json b/packages/@vue/cli-service/types/tsconfig.json index 210259de31..9ac4ce4303 100644 --- a/packages/@vue/cli-service/types/tsconfig.json +++ b/packages/@vue/cli-service/types/tsconfig.json @@ -2,7 +2,8 @@ { "files": [ "cli-service-test.ts", - "index.d.ts" + "index.d.ts", + "ProjectOptions.d.ts" ], "compilerOptions": { "module": "commonjs", diff --git a/packages/@vue/cli-test-utils/createServer.d.ts b/packages/@vue/cli-test-utils/createServer.d.ts index 87f0b5befa..ac0091055f 100644 --- a/packages/@vue/cli-test-utils/createServer.d.ts +++ b/packages/@vue/cli-test-utils/createServer.d.ts @@ -1,4 +1,4 @@ -import http from 'http' +import * as http from 'http' type Options = { [props: string]: any diff --git a/packages/@vue/cli-test-utils/types/tsconfig.json b/packages/@vue/cli-test-utils/types/tsconfig.json index 8d12c6ad14..25e61bc4b6 100644 --- a/packages/@vue/cli-test-utils/types/tsconfig.json +++ b/packages/@vue/cli-test-utils/types/tsconfig.json @@ -6,7 +6,8 @@ "compilerOptions": { "module": "commonjs", "lib": [ - "es6" + "es6", + "dom" ], "noImplicitAny": true, "noImplicitThis": true, @@ -16,7 +17,6 @@ "types": [], "noEmit": true, "forceConsistentCasingInFileNames": true, - "baseUrl": ".", - "skipLibCheck": true + "baseUrl": "." } } diff --git a/packages/@vue/cli/types/index.d.ts b/packages/@vue/cli/types/index.d.ts index ea7b3262dc..54e84aa3f1 100644 --- a/packages/@vue/cli/types/index.d.ts +++ b/packages/@vue/cli/types/index.d.ts @@ -1,6 +1,6 @@ import { DistinctQuestion, CheckboxChoiceOptions, Answers, ChoiceOptions } from 'inquirer' import { Parser, Transform } from 'jscodeshift' -import ejs from 'ejs' +import * as ejs from 'ejs' interface RenderFile { [path: string]: string | Buffer @@ -45,7 +45,7 @@ type GeneratorRootOptions = Partial<{ configs: object cssPreprocessor: 'sass' | 'dart-sass' | 'node-sass' | 'less' | 'stylus' }> -class PromptModuleAPI { +declare class PromptModuleAPI { /** inject checkbox choice for feature prompt. */ injectFeature(feature: CheckboxChoiceOptions): void @@ -57,7 +57,7 @@ class PromptModuleAPI { onPromptComplete(cb: OnPromptCompleteCb): void } -class GeneratorAPI { +declare class GeneratorAPI { /** * Resolve path for a project. * diff --git a/packages/@vue/cli/types/tsconfig.json b/packages/@vue/cli/types/tsconfig.json index 0940c7c7dd..f1d98433ff 100644 --- a/packages/@vue/cli/types/tsconfig.json +++ b/packages/@vue/cli/types/tsconfig.json @@ -17,7 +17,6 @@ "types": [], "noEmit": true, "forceConsistentCasingInFileNames": true, - "baseUrl": ".", - "skipLibCheck": true + "baseUrl": "." } } From 1c7a4a623c8bfe75d9f514892249120405e225e8 Mon Sep 17 00:00:00 2001 From: fangbinwei Date: Wed, 8 Apr 2020 01:12:32 +0800 Subject: [PATCH 06/13] chore: update yarn.lock revert yarn.lock, use registry.yarnpkg.com instead of registry.npmjs.org --- yarn.lock | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/yarn.lock b/yarn.lock index 93cc5278e7..7f33c7f547 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2679,7 +2679,7 @@ "@types/anymatch@*": version "1.3.1" - resolved "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" + resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== "@types/babel__core@^7.1.0": @@ -2743,7 +2743,7 @@ "@types/connect-history-api-fallback@*": version "1.3.3" - resolved "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.3.tgz#4772b79b8b53185f0f4c9deab09236baf76ee3b4" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.3.tgz#4772b79b8b53185f0f4c9deab09236baf76ee3b4" integrity sha512-7SxFCd+FLlxCfwVwbyPxbR4khL9aNikJhrorw8nUIOqeuooc9gifBuDQOJw5kzN7i6i3vLn9G8Wde/4QDihpYw== dependencies: "@types/express-serve-static-core" "*" @@ -2775,7 +2775,7 @@ "@types/ejs@^2.7.0": version "2.7.0" - resolved "https://registry.npmjs.org/@types/ejs/-/ejs-2.7.0.tgz#bc84e083eae38f64a287a6dab9012bbe1d96e295" + resolved "https://registry.yarnpkg.com/@types/ejs/-/ejs-2.7.0.tgz#bc84e083eae38f64a287a6dab9012bbe1d96e295" integrity sha512-kM2g9Fdk/du24fKuuQhA/LBleFR4Z4JP2MVKpLxQQSzofF1uJ06D+c05zfLDAkkDO55aEeNwJih0gHrE/Ci20A== "@types/eslint-visitor-keys@^1.0.0": @@ -2790,7 +2790,7 @@ "@types/execa@^0.9.0": version "0.9.0" - resolved "https://registry.npmjs.org/@types/execa/-/execa-0.9.0.tgz#9b025d2755f17e80beaf9368c3f4f319d8b0fb93" + resolved "https://registry.yarnpkg.com/@types/execa/-/execa-0.9.0.tgz#9b025d2755f17e80beaf9368c3f4f319d8b0fb93" integrity sha512-mgfd93RhzjYBUHHV532turHC2j4l/qxsF/PbfDmprHDEUHmNZGlDn1CEsulGK3AfsPdhkWzZQT/S/k0UGhLGsA== dependencies: "@types/node" "*" @@ -2814,7 +2814,7 @@ "@types/express@^4.17.4": version "4.17.4" - resolved "https://registry.npmjs.org/@types/express/-/express-4.17.4.tgz#e78bf09f3f530889575f4da8a94cd45384520aac" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.4.tgz#e78bf09f3f530889575f4da8a94cd45384520aac" integrity sha512-DO1L53rGqIDUEvOjJKmbMEQ5Z+BM2cIEPy/eV3En+s166Gz+FeuzRerxcab757u/U4v4XF4RYrZPmqKa+aY/2w== dependencies: "@types/body-parser" "*" @@ -2855,7 +2855,7 @@ "@types/http-proxy-middleware@*": version "0.19.3" - resolved "https://registry.npmjs.org/@types/http-proxy-middleware/-/http-proxy-middleware-0.19.3.tgz#b2eb96fbc0f9ac7250b5d9c4c53aade049497d03" + resolved "https://registry.yarnpkg.com/@types/http-proxy-middleware/-/http-proxy-middleware-0.19.3.tgz#b2eb96fbc0f9ac7250b5d9c4c53aade049497d03" integrity sha512-lnBTx6HCOUeIJMLbI/LaL5EmdKLhczJY5oeXZpX/cXE4rRqb3RmV7VcMpiEfYkmTjipv3h7IAyIINe4plEv7cA== dependencies: "@types/connect" "*" @@ -2864,14 +2864,14 @@ "@types/http-proxy@*": version "1.17.4" - resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.4.tgz#e7c92e3dbe3e13aa799440ff42e6d3a17a9d045b" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.4.tgz#e7c92e3dbe3e13aa799440ff42e6d3a17a9d045b" integrity sha512-IrSHl2u6AWXduUaDLqYpt45tLVCtYv7o4Z0s1KghBCDgIIS9oW5K1H8mZG/A2CfeLdEa7rTd1ACOiHBc1EMT2Q== dependencies: "@types/node" "*" "@types/inquirer@^6.5.0": version "6.5.0" - resolved "https://registry.npmjs.org/@types/inquirer/-/inquirer-6.5.0.tgz#b83b0bf30b88b8be7246d40e51d32fe9d10e09be" + resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-6.5.0.tgz#b83b0bf30b88b8be7246d40e51d32fe9d10e09be" integrity sha512-rjaYQ9b9y/VFGOpqBEXRavc3jh0a+e6evAbI31tMda8VlPaSy0AZJfXsvmIe3wklc7W6C3zCSfleuMXR7NOyXw== dependencies: "@types/through" "*" @@ -2906,7 +2906,7 @@ "@types/jscodeshift@^0.7.0": version "0.7.0" - resolved "https://registry.npmjs.org/@types/jscodeshift/-/jscodeshift-0.7.0.tgz#796bf05a420c5d3e95b196b1fa01cc75f10c41b2" + resolved "https://registry.yarnpkg.com/@types/jscodeshift/-/jscodeshift-0.7.0.tgz#796bf05a420c5d3e95b196b1fa01cc75f10c41b2" integrity sha512-W59Y/fnztfJ/5gP4m2ZSWHvb4JPl9SXXn5ne3/6kYP5twRek9DTyKB6xbPIeg0RXbcNTHPBXHNLcKw3AlCrjTw== dependencies: ast-types "0.12.1" @@ -2958,7 +2958,7 @@ "@types/minimist@^1.2.0": version "1.2.0" - resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6" integrity sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY= "@types/mocha@^5.2.6": @@ -2990,7 +2990,7 @@ "@types/puppeteer@^1.11.0": version "1.20.4" - resolved "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-1.20.4.tgz#30cb0a4ee5394c420119cbdf9f079d6595a07f67" + resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-1.20.4.tgz#30cb0a4ee5394c420119cbdf9f079d6595a07f67" integrity sha512-T/kFgyLnYWk0H94hxI0HbOLnqHvzBRpfS0F0oo9ESGI24oiC2fEjDcMbBjuK3wH7VLsaIsp740vVXVzR1dsMNg== dependencies: "@types/node" "*" @@ -3002,7 +3002,7 @@ "@types/qs@*": version "6.9.1" - resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.1.tgz#937fab3194766256ee09fcd40b781740758617e7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.1.tgz#937fab3194766256ee09fcd40b781740758617e7" integrity sha512-lhbQXx9HKZAPgBkISrBcmAcMpZsmpe/Cd/hY7LGZS5OfkySUBItnPZHgQPssWYUET8elF+yCFBbP1Q0RZPTdaw== "@types/range-parser@*": @@ -3025,7 +3025,7 @@ "@types/source-list-map@*": version "0.1.2" - resolved "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== "@types/stack-utils@^1.0.1": @@ -3045,26 +3045,26 @@ "@types/tapable@*": version "1.0.5" - resolved "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz#9adbc12950582aa65ead76bffdf39fe0c27a3c02" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.5.tgz#9adbc12950582aa65ead76bffdf39fe0c27a3c02" integrity sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ== "@types/through@*": version "0.0.30" - resolved "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz#e0e42ce77e897bd6aead6f6ea62aeb135b8a3895" + resolved "https://registry.yarnpkg.com/@types/through/-/through-0.0.30.tgz#e0e42ce77e897bd6aead6f6ea62aeb135b8a3895" integrity sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg== dependencies: "@types/node" "*" "@types/uglify-js@*": version "3.0.5" - resolved "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.0.5.tgz#2c70d5c68f6e002e3b2e4f849adc5f162546f633" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.0.5.tgz#2c70d5c68f6e002e3b2e4f849adc5f162546f633" integrity sha512-L7EbSkhSaWBpkl+PZAEAqZTqtTeIsq7s/oX/q0LNnxxJoRVKQE0T81XDVyaxjiiKQwiV2vhVeYRqxdRNqGOGJw== dependencies: source-map "^0.6.1" "@types/webpack-dev-server@^3.10.1": version "3.10.1" - resolved "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-3.10.1.tgz#93b7133cc9dab1ca1b76659f5ef8b763ad54c28a" + resolved "https://registry.yarnpkg.com/@types/webpack-dev-server/-/webpack-dev-server-3.10.1.tgz#93b7133cc9dab1ca1b76659f5ef8b763ad54c28a" integrity sha512-2nwwQ/qHRghUirvG/gEDkOQDa+d881UTJM7EG9ok5KNaYCjYVvy7fdaO528Lcym9OQDn75SvruPYVVvMJxqO0g== dependencies: "@types/connect-history-api-fallback" "*" @@ -3080,7 +3080,7 @@ "@types/webpack-sources@*": version "0.1.7" - resolved "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.7.tgz#0a330a9456113410c74a5d64180af0cbca007141" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.7.tgz#0a330a9456113410c74a5d64180af0cbca007141" integrity sha512-XyaHrJILjK1VHVC4aVlKsdNN5KBTwufMb43cQs+flGxtPAf/1Qwl8+Q0tp5BwEGaI8D6XT1L+9bSWXckgkjTLw== dependencies: "@types/node" "*" @@ -3089,7 +3089,7 @@ "@types/webpack@*": version "4.41.10" - resolved "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.10.tgz#2e1f6b3508a249854efe3dcc7690905ac5ee10be" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.10.tgz#2e1f6b3508a249854efe3dcc7690905ac5ee10be" integrity sha512-vIy0qaq8AjOjZLuFPqpo7nAJzcoVXMdw3mvpNN07Uvdy0p1IpJeLNBe3obdRP7FX2jIusDE7z1pZa0A6qYUgnA== dependencies: "@types/anymatch" "*" @@ -4721,7 +4721,7 @@ assign-symbols@^1.0.0: ast-types@0.12.1: version "0.12.1" - resolved "https://registry.npmjs.org/ast-types/-/ast-types-0.12.1.tgz#55d3737a8a68e1ccde131067005ce7ee3dd42b99" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.12.1.tgz#55d3737a8a68e1ccde131067005ce7ee3dd42b99" integrity sha512-H2izJAyT2xwew4TxShpmxe6f9R5hHgJQy1QloLiUC2yrJMtyraBWNJL7903rpeCY9keNUipORR/zIUC2XcYKng== ast-types@0.13.2, ast-types@0.x.x, ast-types@^0.13.0: @@ -15593,7 +15593,7 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -puppeteer@^1.11.0: +puppeteer@1.11.0, puppeteer@^1.11.0: version "1.11.0" resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-1.11.0.tgz#63cdbe12b07275cd6e0b94bce41f3fcb20305770" integrity sha512-iG4iMOHixc2EpzqRV+pv7o3GgmU2dNYEMkvKwSaQO/vMZURakwSOn/EYJ6OIRFYOque1qorzIBvrytPIQB3YzQ== @@ -15915,7 +15915,7 @@ realpath-native@^1.1.0: recast@0.17.2: version "0.17.2" - resolved "https://registry.npmjs.org/recast/-/recast-0.17.2.tgz#f18f18cf20bf3fad4522621a7f9c2ada37276814" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.17.2.tgz#f18f18cf20bf3fad4522621a7f9c2ada37276814" integrity sha512-YHFvn4rBXl8eIjALjUiOV/AP3xFpyGNGNHDw9mAncAWuIdgnBKjbZQ9+P3VlsKcNaNapRVFlTEX1dvDRlYwyxg== dependencies: ast-types "0.12.1" @@ -18978,7 +18978,7 @@ vue-router@^3.1.6: resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.1.6.tgz#45f5a3a3843e31702c061dd829393554e4328f89" integrity sha512-GYhn2ynaZlysZMkFE5oCHRUTqE8BWs/a9YbKpNLi0i7xD6KG1EzDqpHQmv1F5gXjr8kL5iIVS8EOtRaVUEXTqA== -vue-server-renderer@^2.6.10: +vue-server-renderer@^2.6.10, vue-server-renderer@^2.6.11: version "2.6.11" resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.6.11.tgz#be8c9abc6aacc309828a755c021a05fc474b4bc3" integrity sha512-V3faFJHr2KYfdSIalL+JjinZSHYUhlrvJ9pzCIjjwSh77+pkrsXpK4PucdPcng57+N77pd1LrKqwbqjQdktU1A== From 490a82d405299995d44282ff1c0172eb656682f2 Mon Sep 17 00:00:00 2001 From: fangbinwei Date: Wed, 8 Apr 2020 21:13:53 +0800 Subject: [PATCH 07/13] fix(cli,cli-service,cli-test-utils): fix ts declartation 1. rename GeneratorRootOptions to Preset. 2. fix wrong use of type object, use Record instead. 3. support function type of plugin. --- .../cli-service/types/cli-service-test.ts | 7 ++-- packages/@vue/cli-service/types/index.d.ts | 21 ++++++++-- .../cli-test-utils/createTestProject.d.ts | 4 +- .../cli-test-utils/generateWithPlugin.d.ts | 10 ++--- .../types/cli-test-utils-test.ts | 18 ++++++++- packages/@vue/cli/types/cli-test.ts | 9 ++++- packages/@vue/cli/types/index.d.ts | 38 +++++++++++++------ 7 files changed, 77 insertions(+), 30 deletions(-) diff --git a/packages/@vue/cli-service/types/cli-service-test.ts b/packages/@vue/cli-service/types/cli-service-test.ts index 626f7725fe..2f0a1b47a2 100644 --- a/packages/@vue/cli-service/types/cli-service-test.ts +++ b/packages/@vue/cli-service/types/cli-service-test.ts @@ -1,6 +1,6 @@ -import { PluginAPI } from '@vue/cli-service' +import { ServicePlugin } from '@vue/cli-service' -export = (api: PluginAPI) => { +const servicePlugin: ServicePlugin = (api, options) => { const version = api.version api.assertVersion(4) api.assertVersion('^100') @@ -41,7 +41,7 @@ export = (api: PluginAPI) => { api.configureWebpack(config => { return { - devtool: config.devtool ? config.devtool : 'source-map' + devtool: config.devtool || 'source-map' } }) @@ -61,3 +61,4 @@ export = (api: PluginAPI) => { ['babel.config.js', '.browserslistrc'] ) } +export = servicePlugin diff --git a/packages/@vue/cli-service/types/index.d.ts b/packages/@vue/cli-service/types/index.d.ts index 3874a2e89d..db8d121f0c 100644 --- a/packages/@vue/cli-service/types/index.d.ts +++ b/packages/@vue/cli-service/types/index.d.ts @@ -1,10 +1,9 @@ -// Users who do not have --allowSyntheticDefaultExports or --esModuleInterop will get different behavior -// https://github.com/Microsoft/dtslint/blob/master/docs/no-import-default-of-export-equals.md import minimist = require('minimist') import ChainableConfig = require('webpack-chain') import webpack = require('webpack') import WebpackDevServer = require('webpack-dev-server') import express = require('express') // @types/webpack-dev-server depends on @types/express +import { ProjectOptions } from './ProjectOptions' type RegisterCommandFn = (args: minimist.ParsedArgs, rawArgv: string[]) => any @@ -27,7 +26,7 @@ interface CacheConfig { cacheDirectory: string cacheIdentifier: string } -export class PluginAPI { +declare class PluginAPI { id: string service: any @@ -121,4 +120,18 @@ export class PluginAPI { genCacheConfig(id: string, partialIdentifier: any, configFiles?: object | object[]): CacheConfig } -export { ProjectOptions, ConfigFunction } from './ProjectOptions' +/** + * Service plugin serves for modifying webpack config, + * creating new vue-cli service commands or changing existing commands + * + * @param api - A PluginAPI instance + * @param options - An object containing project local options specified in vue.config.js, + * or in the "vue" field in package.json. + */ +type ServicePlugin = ( + api: PluginAPI, + options: ProjectOptions +) => any + +export { ProjectOptions, ServicePlugin, PluginAPI } +export { ConfigFunction } from './ProjectOptions' diff --git a/packages/@vue/cli-test-utils/createTestProject.d.ts b/packages/@vue/cli-test-utils/createTestProject.d.ts index 0edf09dbdc..a8564329d7 100644 --- a/packages/@vue/cli-test-utils/createTestProject.d.ts +++ b/packages/@vue/cli-test-utils/createTestProject.d.ts @@ -1,5 +1,5 @@ import execa = require('execa') // execa@1.0.0 needs @types/execa -import { GeneratorRootOptions } from '@vue/cli' +import { Preset } from '@vue/cli' /** * create project at path `cwd` @@ -19,7 +19,7 @@ declare function createTestProject( * } * } */ - preset: GeneratorRootOptions, + preset: Preset, /** `path.resolve(cwd, name)` will be the project's root directory */ cwd?: string | null, /** diff --git a/packages/@vue/cli-test-utils/generateWithPlugin.d.ts b/packages/@vue/cli-test-utils/generateWithPlugin.d.ts index c07df09473..6998c9c5a4 100644 --- a/packages/@vue/cli-test-utils/generateWithPlugin.d.ts +++ b/packages/@vue/cli-test-utils/generateWithPlugin.d.ts @@ -1,9 +1,9 @@ -import { GeneratorAPI, GeneratorRootOptions } from '@vue/cli' +import { GeneratorAPI, Preset } from '@vue/cli' type ApplyFn = ( api: GeneratorAPI, - options: Record, - rootOptions: GeneratorRootOptions, + options: any, + rootOptions: Preset, invoking: boolean, ) => any interface Plugin { @@ -12,7 +12,7 @@ interface Plugin { /** generator function from plugin */ apply: ApplyFn /** parameter passed to generator function */ - options: Record + options?: any } /** @@ -22,7 +22,7 @@ declare function generateWithPlugin( plugin: Plugin | Plugin[], ): Promise<{ /** package.json Object */ - pkg: object + pkg: Record /** virtual file tree, file path is the key of Object */ files: { [filePath: string]: string | Buffer diff --git a/packages/@vue/cli-test-utils/types/cli-test-utils-test.ts b/packages/@vue/cli-test-utils/types/cli-test-utils-test.ts index 0b923314ba..7ce15e862b 100644 --- a/packages/@vue/cli-test-utils/types/cli-test-utils-test.ts +++ b/packages/@vue/cli-test-utils/types/cli-test-utils-test.ts @@ -82,8 +82,22 @@ async function createTest() { async function testGenerate() { const { pkg, files } = await generateWithPlugin({ id: 'test-plugin', - apply: (api, options, rootOptions, invoking) => {}, - options: {} + apply: (api, options, rootOptions, invoking) => { + if (options.skip) return + console.log(rootOptions.bare, rootOptions.projectName, rootOptions.useConfigFiles, rootOptions.cssPreprocessor) + if (rootOptions.plugins) console.log(rootOptions.plugins['@vue/cli-service']) + if (rootOptions.configs) console.log(rootOptions.configs.vue) + }, + options: { + skip: true + } + }) + const lint = pkg.scripts.lint + const main = files['src/main.js'] + + await generateWithPlugin({ + id: 'test-plugin-no-options', + apply: (api, options, rootOptions, invoking) => {} }) } diff --git a/packages/@vue/cli/types/cli-test.ts b/packages/@vue/cli/types/cli-test.ts index ecb78b8481..c9294c23b6 100644 --- a/packages/@vue/cli/types/cli-test.ts +++ b/packages/@vue/cli/types/cli-test.ts @@ -1,4 +1,4 @@ -import { GeneratorAPI, PromptModuleAPI } from '@vue/cli' +import { GeneratorPlugin, PromptModuleAPI } from '@vue/cli' const testPromptAPI = (cli: PromptModuleAPI) => { cli.injectFeature({ @@ -60,7 +60,7 @@ const testPromptAPI = (cli: PromptModuleAPI) => { }) } -export = (api: GeneratorAPI) => { +const generator: GeneratorPlugin = (api, options, rootOptions, invoking) => { const version = api.cliVersion const cliServiceVersion = api.cliServiceVersion api.assertCliServiceVersion(4) @@ -90,6 +90,9 @@ export = (api: GeneratorAPI) => { 'vue-router-layout': '^0.1.2' } })) + api.extendPackage(pkg => ({ + foo: pkg.foo + 1 + })) api.extendPackage( { fooConfig: { @@ -181,3 +184,5 @@ export = (api: GeneratorAPI) => { const isInvoking = api.invoking } + +export = generator diff --git a/packages/@vue/cli/types/index.d.ts b/packages/@vue/cli/types/index.d.ts index 54e84aa3f1..141d5ae0d3 100644 --- a/packages/@vue/cli/types/index.d.ts +++ b/packages/@vue/cli/types/index.d.ts @@ -33,18 +33,17 @@ interface OnPromptCompleteCb { }, ): void } -interface Feature extends CheckboxChoiceOptions { - [prop: string]: any -} -type GeneratorRootOptions = Partial<{ +type Preset = Partial<{ [props: string]: any + bare: boolean projectName: string useConfigFiles: boolean - plugins: object - configs: object + plugins: Record + configs: Record cssPreprocessor: 'sass' | 'dart-sass' | 'node-sass' | 'less' | 'stylus' }> + declare class PromptModuleAPI { /** inject checkbox choice for feature prompt. */ injectFeature(feature: CheckboxChoiceOptions): void @@ -117,13 +116,13 @@ declare class GeneratorAPI { * if two dependency version ranges don't intersect. */ extendPackage( - fields: object | ((pkg: object) => object), + fields: object | ((pkg: Record) => object), options?: | { - prune?: boolean - merge?: boolean - warnIncompatibleVersions?: boolean - } + prune?: boolean + merge?: boolean + warnIncompatibleVersions?: boolean + } | boolean, ): void @@ -221,4 +220,19 @@ declare class GeneratorAPI { get invoking(): boolean } -export { PromptModuleAPI, GeneratorAPI, GeneratorRootOptions } +/** + * function exported by a generator + * @param api - A GeneratorAPI instance + * @param options - These options are resolved during the prompt phase of project creation, + * or loaded from a saved preset in ~/.vuerc + * @param rootOptions - The entire preset will be passed + * @param invoking - Is the plugin being invoked + */ +type GeneratorPlugin = ( + api: GeneratorAPI, + options: any, + rootOptions: Preset, + invoking: boolean +) => any + +export { PromptModuleAPI, GeneratorAPI, Preset, GeneratorPlugin } From 959087c3fa3ec98e537698637452f2f4c63bf6fa Mon Sep 17 00:00:00 2001 From: fangbinwei Date: Mon, 13 Apr 2020 02:07:33 +0800 Subject: [PATCH 08/13] fix(cli-service,cli-test-utils): fix ts declaration 1. use @types/webpack instead of webpack/declarations. 2. add 'export {}' to the module to shut off automatic exporting. see https://stackoverflow.com/questions/52583603/intentional-that-export-shuts-off-automatic-export-of-all-symbols-from-a-ty. 3. add reference node, so @types/node can be included even typeRoots/types is specified. --- packages/@vue/cli-service/package.json | 1 + packages/@vue/cli-service/types/ProjectOptions.d.ts | 8 +++++--- packages/@vue/cli-service/types/tsconfig.json | 3 +-- packages/@vue/cli-test-utils/createServer.d.ts | 1 + packages/@vue/cli-test-utils/package.json | 1 + yarn.lock | 6 +++--- 6 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/@vue/cli-service/package.json b/packages/@vue/cli-service/package.json index eae81610cc..6a603931fb 100644 --- a/packages/@vue/cli-service/package.json +++ b/packages/@vue/cli-service/package.json @@ -27,6 +27,7 @@ "@soda/friendly-errors-webpack-plugin": "^1.7.1", "@soda/get-current-script": "^1.0.0", "@types/minimist": "^1.2.0", + "@types/webpack": "^4.0.0", "@types/webpack-dev-server": "^3.10.1", "@vue/cli-overlay": "^4.3.0", "@vue/cli-plugin-router": "^4.3.0", diff --git a/packages/@vue/cli-service/types/ProjectOptions.d.ts b/packages/@vue/cli-service/types/ProjectOptions.d.ts index 0b77b42a18..b4c0269e75 100644 --- a/packages/@vue/cli-service/types/ProjectOptions.d.ts +++ b/packages/@vue/cli-service/types/ProjectOptions.d.ts @@ -1,5 +1,5 @@ import ChainableWebpackConfig = require('webpack-chain') -import { WebpackOptions } from 'webpack/declarations/WebpackOptions' +import { Configuration as WebpackOptions } from 'webpack' type PageEntry = string | string[]; @@ -29,7 +29,7 @@ interface CSSOptions { loaderOptions?: LoaderOptions; } -export interface ProjectOptions { +interface ProjectOptions { publicPath?: string; outputDir?: string; assetsDir?: string; @@ -57,4 +57,6 @@ export interface ProjectOptions { pluginOptions?: object; } -export type ConfigFunction = () => ProjectOptions +type ConfigFunction = () => ProjectOptions + +export { ProjectOptions, ConfigFunction } diff --git a/packages/@vue/cli-service/types/tsconfig.json b/packages/@vue/cli-service/types/tsconfig.json index 9ac4ce4303..b4303a29a3 100644 --- a/packages/@vue/cli-service/types/tsconfig.json +++ b/packages/@vue/cli-service/types/tsconfig.json @@ -18,7 +18,6 @@ "types": [], "noEmit": true, "forceConsistentCasingInFileNames": true, - "baseUrl": ".", - "skipLibCheck": true + "baseUrl": "." } } diff --git a/packages/@vue/cli-test-utils/createServer.d.ts b/packages/@vue/cli-test-utils/createServer.d.ts index ac0091055f..c50198e990 100644 --- a/packages/@vue/cli-test-utils/createServer.d.ts +++ b/packages/@vue/cli-test-utils/createServer.d.ts @@ -1,3 +1,4 @@ +/// import * as http from 'http' type Options = { diff --git a/packages/@vue/cli-test-utils/package.json b/packages/@vue/cli-test-utils/package.json index 1e3db3a7e3..78150aaf85 100644 --- a/packages/@vue/cli-test-utils/package.json +++ b/packages/@vue/cli-test-utils/package.json @@ -24,6 +24,7 @@ "dependencies": { "@types/execa": "^0.9.0", "@types/express": "^4.17.4", + "@types/node": "*", "@types/puppeteer": "^1.11.0", "@vue/cli": "^4.3.0", "execa": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index 7f33c7f547..ebaeaefa0e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3087,7 +3087,7 @@ "@types/source-list-map" "*" source-map "^0.6.1" -"@types/webpack@*": +"@types/webpack@*", "@types/webpack@^4.0.0": version "4.41.10" resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.10.tgz#2e1f6b3508a249854efe3dcc7690905ac5ee10be" integrity sha512-vIy0qaq8AjOjZLuFPqpo7nAJzcoVXMdw3mvpNN07Uvdy0p1IpJeLNBe3obdRP7FX2jIusDE7z1pZa0A6qYUgnA== @@ -15593,7 +15593,7 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -puppeteer@1.11.0, puppeteer@^1.11.0: +puppeteer@^1.11.0: version "1.11.0" resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-1.11.0.tgz#63cdbe12b07275cd6e0b94bce41f3fcb20305770" integrity sha512-iG4iMOHixc2EpzqRV+pv7o3GgmU2dNYEMkvKwSaQO/vMZURakwSOn/EYJ6OIRFYOque1qorzIBvrytPIQB3YzQ== @@ -18978,7 +18978,7 @@ vue-router@^3.1.6: resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.1.6.tgz#45f5a3a3843e31702c061dd829393554e4328f89" integrity sha512-GYhn2ynaZlysZMkFE5oCHRUTqE8BWs/a9YbKpNLi0i7xD6KG1EzDqpHQmv1F5gXjr8kL5iIVS8EOtRaVUEXTqA== -vue-server-renderer@^2.6.10, vue-server-renderer@^2.6.11: +vue-server-renderer@^2.6.10: version "2.6.11" resolved "https://registry.yarnpkg.com/vue-server-renderer/-/vue-server-renderer-2.6.11.tgz#be8c9abc6aacc309828a755c021a05fc474b4bc3" integrity sha512-V3faFJHr2KYfdSIalL+JjinZSHYUhlrvJ9pzCIjjwSh77+pkrsXpK4PucdPcng57+N77pd1LrKqwbqjQdktU1A== From b43116b3c234f974d402cf92beb39385c7926c68 Mon Sep 17 00:00:00 2001 From: fangbinwei Date: Sat, 11 Jul 2020 03:44:03 +0800 Subject: [PATCH 09/13] style(cli,cli-service,cli-test-utils): change indent size --- packages/@vue/cli-service/types/tsconfig.json | 39 +++++++++---------- .../@vue/cli-test-utils/types/tsconfig.json | 37 +++++++++--------- packages/@vue/cli/types/tsconfig.json | 37 +++++++++--------- 3 files changed, 55 insertions(+), 58 deletions(-) diff --git a/packages/@vue/cli-service/types/tsconfig.json b/packages/@vue/cli-service/types/tsconfig.json index b4303a29a3..06338ace90 100644 --- a/packages/@vue/cli-service/types/tsconfig.json +++ b/packages/@vue/cli-service/types/tsconfig.json @@ -1,23 +1,22 @@ - { - "files": [ - "cli-service-test.ts", - "index.d.ts", - "ProjectOptions.d.ts" + "files": [ + "cli-service-test.ts", + "index.d.ts", + "ProjectOptions.d.ts" + ], + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" ], - "compilerOptions": { - "module": "commonjs", - "lib": [ - "es6" - ], - "noImplicitAny": true, - "noImplicitThis": true, - "strictNullChecks": true, - "esModuleInterop": true, - "strictFunctionTypes": true, - "types": [], - "noEmit": true, - "forceConsistentCasingInFileNames": true, - "baseUrl": "." - } + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "esModuleInterop": true, + "strictFunctionTypes": true, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": "." + } } diff --git a/packages/@vue/cli-test-utils/types/tsconfig.json b/packages/@vue/cli-test-utils/types/tsconfig.json index 25e61bc4b6..7b031c212c 100644 --- a/packages/@vue/cli-test-utils/types/tsconfig.json +++ b/packages/@vue/cli-test-utils/types/tsconfig.json @@ -1,22 +1,21 @@ - { - "files": [ - "cli-test-utils-test.ts" + "files": [ + "cli-test-utils-test.ts" + ], + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6", + "dom" ], - "compilerOptions": { - "module": "commonjs", - "lib": [ - "es6", - "dom" - ], - "noImplicitAny": true, - "noImplicitThis": true, - "strictNullChecks": true, - "esModuleInterop": true, - "strictFunctionTypes": true, - "types": [], - "noEmit": true, - "forceConsistentCasingInFileNames": true, - "baseUrl": "." - } + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "esModuleInterop": true, + "strictFunctionTypes": true, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": "." + } } diff --git a/packages/@vue/cli/types/tsconfig.json b/packages/@vue/cli/types/tsconfig.json index f1d98433ff..d64e4de3b9 100644 --- a/packages/@vue/cli/types/tsconfig.json +++ b/packages/@vue/cli/types/tsconfig.json @@ -1,22 +1,21 @@ - { - "files": [ - "cli-test.ts", - "index.d.ts" + "files": [ + "cli-test.ts", + "index.d.ts" + ], + "compilerOptions": { + "module": "commonjs", + "lib": [ + "es6" ], - "compilerOptions": { - "module": "commonjs", - "lib": [ - "es6" - ], - "noImplicitAny": true, - "noImplicitThis": true, - "strictNullChecks": true, - "esModuleInterop": true, - "strictFunctionTypes": true, - "types": [], - "noEmit": true, - "forceConsistentCasingInFileNames": true, - "baseUrl": "." - } + "noImplicitAny": true, + "noImplicitThis": true, + "strictNullChecks": true, + "esModuleInterop": true, + "strictFunctionTypes": true, + "types": [], + "noEmit": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": "." + } } From 1fb09d31bf5378e5036f2e7518a879b40d68e755 Mon Sep 17 00:00:00 2001 From: fangbinwei Date: Wed, 15 Jul 2020 01:19:36 +0800 Subject: [PATCH 10/13] refactor(cli,cl-service): use readonly instead of getter in d.ts --- packages/@vue/cli-service/types/index.d.ts | 2 +- packages/@vue/cli/types/index.d.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/@vue/cli-service/types/index.d.ts b/packages/@vue/cli-service/types/index.d.ts index db8d121f0c..ec8796a0d2 100644 --- a/packages/@vue/cli-service/types/index.d.ts +++ b/packages/@vue/cli-service/types/index.d.ts @@ -31,7 +31,7 @@ declare class PluginAPI { service: any - get version(): string + readonly version: string assertVersion(range: number | string): void diff --git a/packages/@vue/cli/types/index.d.ts b/packages/@vue/cli/types/index.d.ts index 141d5ae0d3..470234f399 100644 --- a/packages/@vue/cli/types/index.d.ts +++ b/packages/@vue/cli/types/index.d.ts @@ -65,11 +65,11 @@ declare class GeneratorAPI { */ resolve(..._paths: string[]): string - get cliVersion(): string + readonly cliVersion: string assertCliVersion(range: number | string): void - get cliServiceVersion(): string + readonly cliServiceVersion: string assertCliServiceVersion(range: number | string): void @@ -211,13 +211,13 @@ declare class GeneratorAPI { * Get the entry file taking into account typescript. * */ - get entryFile(): 'src/main.ts' | 'src/main.js' + readonly entryFile: 'src/main.ts' | 'src/main.js' /** * Is the plugin being invoked? * */ - get invoking(): boolean + readonly invoking: boolean } /** From 65c0c2e6e179b5cff426d6af8bfdacabef578f7f Mon Sep 17 00:00:00 2001 From: Binwei Fang Date: Wed, 15 Jul 2020 01:48:26 +0800 Subject: [PATCH 11/13] fix(cli-service): fix type def of genCacheConfig in d.ts Co-authored-by: Haoqun Jiang --- packages/@vue/cli-service/types/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@vue/cli-service/types/index.d.ts b/packages/@vue/cli-service/types/index.d.ts index ec8796a0d2..dfb5e7f2d7 100644 --- a/packages/@vue/cli-service/types/index.d.ts +++ b/packages/@vue/cli-service/types/index.d.ts @@ -117,7 +117,7 @@ declare class PluginAPI { /** * Generate a cache identifier from a number of variables */ - genCacheConfig(id: string, partialIdentifier: any, configFiles?: object | object[]): CacheConfig + genCacheConfig(id: string, partialIdentifier: any, configFiles?: string | string[]): CacheConfig } /** From 50e10b9783b1cb291e80942caed03fdd168500c4 Mon Sep 17 00:00:00 2001 From: fangbinwei Date: Wed, 15 Jul 2020 01:50:25 +0800 Subject: [PATCH 12/13] refactor(cli-test-utils): remove redundant type def in d.ts --- packages/@vue/cli-test-utils/createServer.d.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/@vue/cli-test-utils/createServer.d.ts b/packages/@vue/cli-test-utils/createServer.d.ts index c50198e990..45b1c50c78 100644 --- a/packages/@vue/cli-test-utils/createServer.d.ts +++ b/packages/@vue/cli-test-utils/createServer.d.ts @@ -1,14 +1,11 @@ /// import * as http from 'http' -type Options = { - [props: string]: any +declare function createServer(options: { /** * Set a sub directory to be served */ root: string -} - -declare function createServer(options: Options): http.Server +}): http.Server export = createServer From 35ac3b67840694ddde4de93af65597fa98cffe1d Mon Sep 17 00:00:00 2001 From: fangbinwei Date: Wed, 15 Jul 2020 02:41:53 +0800 Subject: [PATCH 13/13] fix(cli): fix extendPackage type def in d.ts since Function belongs to object, so a Function which return type is not object is still assignable to 'object | () => return type'. we need exclude Function from object. releated: https://github.com/microsoft/TypeScript/issues/38254 https://stackoverflow.com/questions/24613955/is-there-a-type-in-typescript-for-anything-except-functions --- packages/@vue/cli/types/index.d.ts | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/packages/@vue/cli/types/index.d.ts b/packages/@vue/cli/types/index.d.ts index 470234f399..6b4cf5deca 100644 --- a/packages/@vue/cli/types/index.d.ts +++ b/packages/@vue/cli/types/index.d.ts @@ -30,9 +30,16 @@ interface OnPromptCompleteCb { options: { useConfigFiles: boolean plugins: Record - }, + } ): void } +type ExtendPackageOptions = + | { + prune?: boolean + merge?: boolean + warnIncompatibleVersions?: boolean + } + | boolean type Preset = Partial<{ [props: string]: any @@ -116,14 +123,12 @@ declare class GeneratorAPI { * if two dependency version ranges don't intersect. */ extendPackage( - fields: object | ((pkg: Record) => object), - options?: - | { - prune?: boolean - merge?: boolean - warnIncompatibleVersions?: boolean - } - | boolean, + fields: (pkg: Record) => object, + options?: ExtendPackageOptions + ): void + extendPackage( + fields: T extends Function ? never : T, + options?: ExtendPackageOptions ): void /**