Skip to content

Commit 725ca41

Browse files
feat(cli,cli-service,cli-test-utils): add ts declaration (#5356)
Co-authored-by: Haoqun Jiang <[email protected]>
1 parent 82d65e1 commit 725ca41

20 files changed

+1070
-13
lines changed

packages/@vue/cli-service/package.json

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
"@intervolga/optimize-cssnano-plugin": "^1.0.5",
2727
"@soda/friendly-errors-webpack-plugin": "^1.7.1",
2828
"@soda/get-current-script": "^1.0.0",
29+
"@types/minimist": "^1.2.0",
30+
"@types/webpack": "^4.0.0",
31+
"@types/webpack-dev-server": "^3.11.0",
2932
"@vue/cli-overlay": "^4.4.6",
3033
"@vue/cli-plugin-router": "^4.4.6",
3134
"@vue/cli-plugin-vuex": "^4.4.6",

packages/@vue/cli-service/types/ProjectOptions.d.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import ChainableWebpackConfig from 'webpack-chain'
2-
import { WebpackOptions } from 'webpack/declarations/WebpackOptions'
1+
import ChainableWebpackConfig = require('webpack-chain')
2+
import { Configuration as WebpackOptions } from 'webpack'
33

44
type PageEntry = string | string[];
55

@@ -29,7 +29,7 @@ interface CSSOptions {
2929
loaderOptions?: LoaderOptions;
3030
}
3131

32-
export interface ProjectOptions {
32+
interface ProjectOptions {
3333
publicPath?: string;
3434
outputDir?: string;
3535
assetsDir?: string;
@@ -57,4 +57,6 @@ export interface ProjectOptions {
5757
pluginOptions?: object;
5858
}
5959

60-
export type ConfigFunction = () => ProjectOptions
60+
type ConfigFunction = () => ProjectOptions
61+
62+
export { ProjectOptions, ConfigFunction }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { ServicePlugin } from '@vue/cli-service'
2+
3+
const servicePlugin: ServicePlugin = (api, options) => {
4+
const version = api.version
5+
api.assertVersion(4)
6+
api.assertVersion('^100')
7+
api.getCwd()
8+
api.resolve('src/main.js')
9+
api.hasPlugin('eslint')
10+
api.registerCommand(
11+
'lint',
12+
{
13+
description: 'lint and fix source files',
14+
usage: 'vue-cli-service lint [options] [...files]',
15+
options: {
16+
'--format [formatter]': 'specify formatter (default: codeframe)'
17+
},
18+
details: 'For more options, see https://eslint.org/docs/user-guide/command-line-interface#options'
19+
},
20+
args => {
21+
require('./lint')(args, api)
22+
}
23+
)
24+
api.registerCommand('lint', args => {})
25+
26+
api.chainWebpack(webpackConfig => {
27+
if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test') {
28+
webpackConfig.devtool('cheap-module-eval-source-map')
29+
30+
webpackConfig.plugin('hmr').use(require('webpack/lib/HotModuleReplacementPlugin'))
31+
32+
webpackConfig.output.globalObject(`(typeof self !== 'undefined' ? self : this)`)
33+
}
34+
})
35+
36+
api.configureWebpack(config => {
37+
config.output = {
38+
path: 'test-dist-2'
39+
}
40+
})
41+
42+
api.configureWebpack(config => {
43+
return {
44+
devtool: config.devtool || 'source-map'
45+
}
46+
})
47+
48+
api.resolveWebpackConfig()
49+
50+
api.resolveWebpackConfig(api.resolveChainableWebpackConfig())
51+
52+
const { cacheIdentifier, cacheDirectory } = api.genCacheConfig(
53+
'babel-loader',
54+
{
55+
'@babel/core': require('@babel/core/package.json').version,
56+
'@vue/babel-preset-app': require('@vue/babel-preset-app/package.json').version,
57+
'babel-loader': require('babel-loader/package.json').version,
58+
modern: !!process.env.VUE_CLI_MODERN_BUILD,
59+
browserslist: api.service.pkg.browserslist
60+
},
61+
['babel.config.js', '.browserslistrc']
62+
)
63+
}
64+
export = servicePlugin
+137-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,137 @@
1-
export { ProjectOptions, ConfigFunction } from './ProjectOptions'
1+
import minimist = require('minimist')
2+
import ChainableConfig = require('webpack-chain')
3+
import webpack = require('webpack')
4+
import WebpackDevServer = require('webpack-dev-server')
5+
import express = require('express') // @types/webpack-dev-server depends on @types/express
6+
import { ProjectOptions } from './ProjectOptions'
7+
8+
type RegisterCommandFn = (args: minimist.ParsedArgs, rawArgv: string[]) => any
9+
10+
type RegisterCommandOpts = Partial<{
11+
description: string
12+
usage: string
13+
options: {
14+
[flags: string]: string
15+
}
16+
details: string
17+
}>
18+
19+
type WebpackChainFn = (chainableConfig: ChainableConfig) => void
20+
21+
type webpackRawConfigFn = ((config: webpack.Configuration) => webpack.Configuration | void) | webpack.Configuration
22+
23+
type DevServerConfigFn = (app: express.Application, server: WebpackDevServer) => void
24+
25+
interface CacheConfig {
26+
cacheDirectory: string
27+
cacheIdentifier: string
28+
}
29+
declare class PluginAPI {
30+
id: string
31+
32+
service: any
33+
34+
readonly version: string
35+
36+
assertVersion(range: number | string): void
37+
38+
/**
39+
* Current working directory.
40+
*/
41+
getCwd(): string
42+
43+
/**
44+
* Resolve path for a project.
45+
*
46+
* @param _path - Relative path from project root
47+
* @return The resolved absolute path.
48+
*/
49+
resolve(_path: string): string
50+
51+
/**
52+
* Check if the project has a given plugin.
53+
*
54+
* @param id - Plugin id, can omit the (@vue/|vue-|@scope/vue)-cli-plugin- prefix
55+
* @return `boolean`
56+
*/
57+
hasPlugin(id: string): boolean
58+
59+
/**
60+
* Register a command that will become available as `vue-cli-service [name]`.
61+
*
62+
* @param name
63+
* @param [opts]
64+
* @param fn
65+
*/
66+
registerCommand(name: string, fn: RegisterCommandFn): void
67+
registerCommand(name: string, opts: RegisterCommandOpts, fn: RegisterCommandFn): void
68+
69+
/**
70+
* Register a function that will receive a chainable webpack config
71+
* the function is lazy and won't be called until `resolveWebpackConfig` is
72+
* called
73+
*
74+
* @param fn
75+
*/
76+
chainWebpack(fn: WebpackChainFn): void
77+
78+
/**
79+
* Register
80+
* - a webpack configuration object that will be merged into the config
81+
* OR
82+
* - a function that will receive the raw webpack config.
83+
* the function can either mutate the config directly or return an object
84+
* that will be merged into the config.
85+
*
86+
* @param fn
87+
*/
88+
configureWebpack(fn: webpackRawConfigFn): void
89+
90+
/**
91+
* Register a dev serve config function. It will receive the express `app`
92+
* instance of the dev server.
93+
*
94+
* @param fn
95+
*/
96+
configureDevServer(fn: DevServerConfigFn): void
97+
98+
/**
99+
* Resolve the final raw webpack config, that will be passed to webpack.
100+
*
101+
* @param [chainableConfig]
102+
* @return Raw webpack config.
103+
*/
104+
resolveWebpackConfig(chainableConfig?: ChainableConfig): webpack.Configuration
105+
106+
/**
107+
* Resolve an intermediate chainable webpack config instance, which can be
108+
* further tweaked before generating the final raw webpack config.
109+
* You can call this multiple times to generate different branches of the
110+
* base webpack config.
111+
* See https://github.com/mozilla-neutrino/webpack-chain
112+
*
113+
* @return ChainableWebpackConfig
114+
*/
115+
resolveChainableWebpackConfig(): ChainableConfig
116+
117+
/**
118+
* Generate a cache identifier from a number of variables
119+
*/
120+
genCacheConfig(id: string, partialIdentifier: any, configFiles?: string | string[]): CacheConfig
121+
}
122+
123+
/**
124+
* Service plugin serves for modifying webpack config,
125+
* creating new vue-cli service commands or changing existing commands
126+
*
127+
* @param api - A PluginAPI instance
128+
* @param options - An object containing project local options specified in vue.config.js,
129+
* or in the "vue" field in package.json.
130+
*/
131+
type ServicePlugin = (
132+
api: PluginAPI,
133+
options: ProjectOptions
134+
) => any
135+
136+
export { ProjectOptions, ServicePlugin, PluginAPI }
137+
export { ConfigFunction } from './ProjectOptions'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"files": [
3+
"cli-service-test.ts",
4+
"index.d.ts",
5+
"ProjectOptions.d.ts"
6+
],
7+
"compilerOptions": {
8+
"module": "commonjs",
9+
"lib": [
10+
"es6"
11+
],
12+
"noImplicitAny": true,
13+
"noImplicitThis": true,
14+
"strictNullChecks": true,
15+
"esModuleInterop": true,
16+
"strictFunctionTypes": true,
17+
"types": [],
18+
"noEmit": true,
19+
"forceConsistentCasingInFileNames": true,
20+
"baseUrl": "."
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { PromptModuleAPI } from '@vue/cli'
2+
3+
interface CliPromptModule {
4+
(api: PromptModuleAPI): void
5+
}
6+
7+
declare function assertPromptModule(
8+
module: CliPromptModule | CliPromptModule[],
9+
expectedPrompts: object[],
10+
expectedOptions: object,
11+
opts?: {
12+
pluginsOnly?: boolean
13+
},
14+
): Promise<void>
15+
16+
export = assertPromptModule
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Application } from 'express'
2+
3+
declare function createJSONServer(
4+
/**
5+
* Either a path to a json file (e.g. 'db.json') or an object in memory
6+
*
7+
* Default:
8+
*{
9+
* 'posts': [
10+
* { 'id': 1, 'title': 'json-server', 'author': 'typicode' }
11+
* ],
12+
* 'comments': [
13+
* { 'id': 1, 'body': 'some comment', 'postId': 1 }
14+
* ],
15+
* 'profile': { 'name': 'typicode' }
16+
*}
17+
*/
18+
data?: string | object,
19+
): Application
20+
21+
export = createJSONServer
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/// <reference types="node" />
2+
import * as http from 'http'
3+
4+
declare function createServer(options: {
5+
/**
6+
* Set a sub directory to be served
7+
*/
8+
root: string
9+
}): http.Server
10+
11+
export = createServer
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import execa = require('execa') // [email protected] needs @types/execa
2+
import { Preset } from '@vue/cli'
3+
4+
/**
5+
* create project at path `cwd`
6+
*/
7+
declare function createTestProject(
8+
/**
9+
* project name
10+
*/
11+
name: string,
12+
/**
13+
* manual preset used to generate project.
14+
*
15+
* Example:
16+
* {
17+
* plugins: {
18+
* '@vue/cli-plugin-babel': {}
19+
* }
20+
* }
21+
*/
22+
preset: Preset,
23+
/** `path.resolve(cwd, name)` will be the project's root directory */
24+
cwd?: string | null,
25+
/**
26+
* if init git repo
27+
*
28+
* Default:`true`
29+
*/
30+
initGit?: boolean,
31+
): Promise<{
32+
/** test project's root path */
33+
dir: string
34+
/** test if project contains the file */
35+
has: (file: string) => boolean
36+
/** read the content for the file */
37+
read: (file: string) => Promise<string>
38+
/** write file to project */
39+
write: (file: string, content: any) => Promise<void>
40+
/** execa command at root path of project */
41+
run: (command: string, args?: ReadonlyArray<string>) => execa.ExecaChildProcess
42+
/** delete the file of project */
43+
rm: (file: string) => Promise<void>
44+
}>
45+
46+
export = createTestProject
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { GeneratorAPI, Preset } from '@vue/cli'
2+
3+
type ApplyFn = (
4+
api: GeneratorAPI,
5+
options: any,
6+
rootOptions: Preset,
7+
invoking: boolean,
8+
) => any
9+
interface Plugin {
10+
/** package name from plugin */
11+
id: string
12+
/** generator function from plugin */
13+
apply: ApplyFn
14+
/** parameter passed to generator function */
15+
options?: any
16+
}
17+
18+
/**
19+
* invoke generator function, and generate file tree in memory
20+
*/
21+
declare function generateWithPlugin(
22+
plugin: Plugin | Plugin[],
23+
): Promise<{
24+
/** package.json Object */
25+
pkg: Record<string, any>
26+
/** virtual file tree, file path is the key of Object */
27+
files: {
28+
[filePath: string]: string | Buffer
29+
}
30+
}>
31+
32+
export = generateWithPlugin

0 commit comments

Comments
 (0)