fix: 优化类型提示

This commit is contained in:
winixt 2022-06-22 12:29:18 +08:00
parent 8a67774e46
commit 54d435538c
25 changed files with 290 additions and 271 deletions

View File

@ -3,6 +3,5 @@ import { name } from '../package.json';
export default function (api) { export default function (api) {
api.addConfigType(() => ({ api.addConfigType(() => ({
source: name, source: name,
build: ['ViteBuildConfig'],
})); }));
} }

View File

@ -4,11 +4,12 @@ import {Options as PolyfillOptions } from '@vitejs/plugin-legacy'
import createPlugin from '@vitejs/plugin-vue-jsx' import createPlugin from '@vitejs/plugin-vue-jsx'
import {createHtmlPlugin} from 'vite-plugin-html' import {createHtmlPlugin} from 'vite-plugin-html'
declare module "@fesjs/fes" {
export interface ViteBuildConfig { interface PluginBuildConfig {
viteOption?: UserConfig; viteOption?: UserConfig;
viteVuePlugin?: Options; viteVuePlugin?: Options;
viteVueJsx?: Parameters<typeof createPlugin>[0]; viteVueJsx?: Parameters<typeof createPlugin>[0];
viteLegacy?: PolyfillOptions; viteLegacy?: PolyfillOptions;
viteHtml?: Parameters<typeof createHtmlPlugin>[0] viteHtml?: Parameters<typeof createHtmlPlugin>[0]
}
} }

View File

@ -3,6 +3,5 @@ import { name } from '../../package.json';
export default function (api) { export default function (api) {
api.addConfigType(() => ({ api.addConfigType(() => ({
source: name, source: name,
build: ['WebpackBuildConfig'],
})); }));
} }

View File

@ -7,51 +7,52 @@ interface CopyFileType {
to: string; to: string;
} }
export interface WebpackBuildConfig { declare module "@fesjs/fes" {
analyze?: { interface PluginBuildConfig {
analyzerMode?: 'server' | 'static' | 'disabled'; analyze?: {
analyzerHost?: string; analyzerMode?: 'server' | 'static' | 'disabled';
analyzerPort?: number | 'auto'; analyzerHost?: string;
openAnalyzer?: boolean; analyzerPort?: number | 'auto';
generateStatsFile?: boolean; openAnalyzer?: boolean;
statsFilename?: string; generateStatsFile?: boolean;
logLevel?: 'info' | 'warn' | 'error' | 'silent'; statsFilename?: string;
defaultSizes?: 'stat' | 'parsed' | 'gzip' logLevel?: 'info' | 'warn' | 'error' | 'silent';
}; defaultSizes?: 'stat' | 'parsed' | 'gzip'
chainWebpack?: (memo: Config, args: {env: string, webpack: typeof webpack}) => void; };
copy?: CopyFileType | CopyFileType[]; chainWebpack?: (memo: Config, args: {env: string, webpack: typeof webpack}) => void;
cssLoader?: { copy?: CopyFileType | CopyFileType[];
url?: boolean | ((url: string, resourcePath: string) => boolean); cssLoader?: {
import?: boolean | ({ filter: (url: string, media: string, resourcePath: string) => boolean }); url?: boolean | ((url: string, resourcePath: string) => boolean);
modules?: boolean | string | object; import?: boolean | ({ filter: (url: string, media: string, resourcePath: string) => boolean });
sourceMap?: boolean; modules?: boolean | string | object;
importLoaders?: number; sourceMap?: boolean;
onlyLocals?: boolean; importLoaders?: number;
esModule?: boolean; onlyLocals?: boolean;
localsConvention?: 'asIs' | 'camelCase' | 'camelCaseOnly' | 'dashes' | 'dashesOnly'; esModule?: boolean;
}; localsConvention?: 'asIs' | 'camelCase' | 'camelCaseOnly' | 'dashes' | 'dashesOnly';
devServer?: { };
port?: number; devServer?: {
host?: string; port?: number;
https?: boolean; host?: string;
headers?: object; https?: boolean;
[key: string]: any; headers?: object;
}; [key: string]: any;
devtool?: string; };
exportStatic?: { devtool?: string;
htmlSuffix?: boolean; exportStatic?: {
dynamicRoot?: boolean; htmlSuffix?: boolean;
}; dynamicRoot?: boolean;
externals?: object | string | Function; };
extraBabelPlugins?: []; externals?: object | string | Function;
extraBabelPresets?: []; extraBabelPlugins?: [];
extraPostCSSPlugins?: []; extraBabelPresets?: [];
html?: HtmlWebpackPlugin.Options; extraPostCSSPlugins?: [];
lessLoader?: Record<string, any>; html?: HtmlWebpackPlugin.Options;
nodeModulesTransform?: { lessLoader?: Record<string, any>;
exclude: string[] nodeModulesTransform?: {
}; exclude: string[]
postcssLoader?: Record<string, any>; };
vueLoader?: object; postcssLoader?: Record<string, any>;
vueLoader?: object;
}
} }

View File

@ -56,7 +56,5 @@ export default (api) => {
api.addConfigType(() => ({ api.addConfigType(() => ({
source: name, source: name,
runtime: ['AccessRuntimeConfig'],
build: ['AccessBuildConfig'],
})); }));
}; };

View File

@ -1,14 +1,16 @@
import { Router, NavigationGuard } from 'vue-router'; import { Router, NavigationGuard } from 'vue-router';
export interface AccessBuildConfig { declare module "@fesjs/fes" {
access: { interface PluginBuildConfig {
rules: Record<string, []>; access: {
}; rules: Record<string, []>;
} };
}
export interface AccessRuntimeConfig { interface PluginRuntimeConfig {
access: { access: {
noFoundHandler: (param: { router: Router } & NavigationGuard) => void; noFoundHandler: (param: { router: Router } & NavigationGuard) => void;
unAccessHandler: (param: { router: Router } & NavigationGuard) => void; unAccessHandler: (param: { router: Router } & NavigationGuard) => void;
}; };
}
} }

View File

@ -46,6 +46,5 @@ export default (api) => {
api.addConfigType(() => ({ api.addConfigType(() => ({
source: name, source: name,
build: ['EnumsBuildConfig'],
})); }));
}; };

View File

@ -1,7 +1,9 @@
export interface EnumsBuildConfig { declare module "@fesjs/fes" {
enums: { interface PluginBuildConfig {
[key: string]: [string | number, string | number][] enums: {
[key: string]: [string | number, string | number][]
}
} }
} }

View File

@ -78,7 +78,5 @@ export default (api) => {
api.addConfigType(() => ({ api.addConfigType(() => ({
source: name, source: name,
runtime: ['LayoutRuntimeConfig'],
build: ['LayoutBuildConfig'],
})); }));
}; };

View File

@ -10,29 +10,28 @@ interface Menu {
children?: Menu[] children?: Menu[]
} }
export interface LayoutBuildConfig { declare module "@fesjs/fes" {
layout: { interface PluginBuildConfig {
title: string; layout: {
footer: string; title: string;
theme: 'dark' | 'light'; footer: string;
multiTabs: boolean; theme: 'dark' | 'light';
navigation: 'side' | 'top' | 'mixin'; multiTabs: boolean;
fixedHeader: boolean; navigation: 'side' | 'top' | 'mixin';
fixedSideBar: boolean; fixedHeader: boolean;
sideWidth: number; fixedSideBar: boolean;
menus: Menu[]; sideWidth: number;
}; menus: Menu[];
} };
}
interface PluginRuntimeConfig {
layout: {
export interface LayoutRuntimeConfig { header: boolean;
layout: { sidebar: boolean;
header: boolean; logo: boolean;
sidebar: boolean; customHeader: Component,
logo: boolean; noFoundHandler: (param: { router: Router } & NavigationGuard) => void;
customHeader: Component, unAccessHandler: (param: { router: Router } & NavigationGuard) => void;
noFoundHandler: (param: { router: Router } & NavigationGuard) => void; };
unAccessHandler: (param: { router: Router } & NavigationGuard) => void; }
};
} }

View File

@ -85,6 +85,5 @@ export default (api) => {
api.addConfigType(() => ({ api.addConfigType(() => ({
source: name, source: name,
build: ['LocalBuildConfig'],
})); }));
}; };

View File

@ -1,8 +1,10 @@
export interface LocalBuildConfig { declare module "@fesjs/fes" {
locale: { interface PluginBuildConfig {
locale: string; locale: {
fallbackLocale: string; locale: string;
baseNavigator: boolean; fallbackLocale: string;
legacy: boolean; baseNavigator: boolean;
}; legacy: boolean;
};
}
} }

View File

@ -89,6 +89,5 @@ export default (api) => {
api.addConfigType(() => ({ api.addConfigType(() => ({
source: name, source: name,
build: ['MonacoEditorBuildConfig'],
})); }));
}; };

View File

@ -1,12 +1,14 @@
import type { EditorLanguage } from 'monaco-editor-webpack-plugin/out/languages'; import type { EditorLanguage } from 'monaco-editor-webpack-plugin/out/languages';
import type { EditorFeature } from 'monaco-editor-webpack-plugin/out/features'; import type { EditorFeature } from 'monaco-editor-webpack-plugin/out/features';
export interface MonacoEditorBuildConfig { declare module "@fesjs/fes" {
monacoEditor: { interface PluginBuildConfig {
filename: string; monacoEditor: {
publicPath: string; filename: string;
languages: EditorLanguage[]; publicPath: string;
features: EditorFeature[]; languages: EditorLanguage[];
globalAPI: boolean; features: EditorFeature[];
}; globalAPI: boolean;
};
}
} }

View File

@ -6,14 +6,16 @@ interface AppOption {
props: Record<string, any>; props: Record<string, any>;
} }
export interface QiankunBuildConfig {
qiankun: {
main: {
apps: AppOption[];
lifeCycles?: FrameworkLifeCycles<MicroApp>;
[key: string]: any;
};
micro: {}
};
declare module "@fesjs/fes" {
interface PluginBuildConfig {
qiankun: {
main: {
apps: AppOption[];
lifeCycles?: FrameworkLifeCycles<MicroApp>;
[key: string]: any;
};
micro: {}
};
}
} }

View File

@ -26,6 +26,5 @@ export default (api) => {
api.addConfigType(() => ({ api.addConfigType(() => ({
source: name, source: name,
runtime: ['RequestRuntimeConfig'],
})); }));
}; };

View File

@ -1,18 +1,27 @@
import { AxiosRequestConfig, AxiosResponse } from 'axios'; import { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
import {Ref} from 'vue';
type RequestInterceptor = (value: AxiosRequestConfig) => AxiosRequestConfig | [(value: AxiosRequestConfig) => AxiosRequestConfig, (error: any) => any]; type RequestInterceptor = (value: AxiosRequestConfig) => AxiosRequestConfig | [(value: AxiosRequestConfig) => AxiosRequestConfig, (error: any) => any];
type ResponseInterceptor = (value: AxiosResponse) => AxiosResponse | [(value: AxiosResponse) => AxiosResponse, (error: any) => any]; type ResponseInterceptor = (value: AxiosResponse) => AxiosResponse | [(value: AxiosResponse) => AxiosResponse, (error: any) => any];
interface RequestPluginOption {
export interface RequestRuntimeConfig { mergeRequest: boolean;
request: { cache: boolean | {
responseDataAdaptor?<T>(data: T): T; type: 'ram' | 'sessionStorage' | 'localStorage',
closeResDataCheck?: boolean; cacheTime: number;
requestInterceptors?: RequestInterceptor[]; }
responseInterceptors?: ResponseInterceptor[]; }
errorHandler?: {
[key: string]: (error: { response: AxiosResponse } | AxiosResponse) => void; declare module "@fesjs/fes" {
}; interface PluginRuntimeConfig {
} & AxiosRequestConfig; request: {
dataHandler?(data: any, response: AxiosResponse): any;
errorHandler?(error: AxiosError | {type: string, msg: string, [key: string]: string}): void;
requestInterceptors?: RequestInterceptor[];
responseInterceptors?: ResponseInterceptor[];
} & AxiosRequestConfig;
}
export function request(url: string, data: null | Record<string, any>, options: AxiosRequestConfig & RequestPluginOption ): Promise<any>
export function useRequest(url: string, data: null | Record<string, any>, options: AxiosRequestConfig & RequestPluginOption ): {loadingRef: Ref<boolean>; errorRef: Ref<Error>; dataRef: Ref<any>}
} }

View File

@ -61,6 +61,5 @@ export default (api) => {
api.addConfigType(() => ({ api.addConfigType(() => ({
source: name, source: name,
build: ['VuexBuildConfig'],
})); }));
}; };

View File

@ -1,8 +1,11 @@
export interface VuexBuildConfig {
vuex: { declare module "@fesjs/fes" {
strict: boolean; interface PluginBuildConfig {
devtools: boolean; vuex: {
strict: boolean;
devtools: boolean;
}
} }
} }

View File

@ -69,6 +69,5 @@ export default (api) => {
api.addConfigType(() => ({ api.addConfigType(() => ({
source: name, source: name,
build: ['WindicssBuildConfig'],
})); }));
}; };

View File

@ -1,7 +1,9 @@
import type { Config } from 'windicss/types/interfaces'; import type { Config } from 'windicss/types/interfaces';
export interface WindicssBuildConfig { declare module "@fesjs/fes" {
windicss: { interface PluginBuildConfig {
config: Config windicss: {
config: Config
}
} }
} }

View File

@ -1,14 +1,12 @@
function importsToStr(imports) { function importsToStr(imports) {
return imports.map((imp) => { return imports.map((imp) => {
const { source, build = [], runtime = [] } = imp; const { source } = imp;
return `import {${build.concat(runtime).join(', ')}} from '${source}';`; return `import '${source}';`;
}); });
} }
function genTypeContent(imports) { function genTypeContent(imports) {
return { return {
RUNTIME_TYPES: imports.reduce((previousValue, currentValue) => previousValue.concat(currentValue.runtime || []), []).join(' & '),
BUILD_TYPES: imports.reduce((previousValue, currentValue) => previousValue.concat(currentValue.build || []), []).join(' & '),
imports: importsToStr(imports).join('\n'), imports: importsToStr(imports).join('\n'),
}; };
} }
@ -21,9 +19,6 @@ export default function (api) {
api.onGenerateFiles(async () => { api.onGenerateFiles(async () => {
const typeTpl = ` const typeTpl = `
{{{ imports }}} {{{ imports }}}
export type PluginRuntimeConfig = {{{RUNTIME_TYPES}}};
export type PluginBuildConfig = {{{BUILD_TYPES}}};
`; `;
const importSources = await api.applyPlugins({ const importSources = await api.applyPlugins({
key: 'addConfigType', key: 'addConfigType',

View File

@ -18,75 +18,78 @@ interface ClientRenderOption {
type RenderFunc = () => Promise<App> type RenderFunc = () => Promise<App>
export interface InnerRuntimeConfig {
beforeRender?: (option: BeforeRenderConfig) => BeforeRenderConfig; declare module "@fesjs/fes" {
patchRoutes?: ({ routes }: { routes: RouteRecordRaw[] }) => void; interface PluginBuildConfig {
modifyClientRenderOpts?: (option: ClientRenderOption) => ClientRenderOption; alias?: Record<string, string>,
rootContainer?: (component: DefineComponent, option: { routes: RouteRecordRaw[], plugin: Plugin }) => DefineComponent; autoprefixer?: {
onAppCreated?: ({ app, routes }: { app: App, routes: RouteRecordRaw[] }) => void; /** environment for `Browserslist` */
render?: (defaultRender: RenderFunc) => RenderFunc; env?: string
onRouterCreated?: ({ router }: { router: Router }) => void;
} /** should Autoprefixer use Visual Cascade, if CSS is uncompressed */
cascade?: boolean
export interface InnerBuildConfig { /** should Autoprefixer add prefixes. */
alias?: Record<string, string>, add?: boolean
autoprefixer?: {
/** environment for `Browserslist` */ /** should Autoprefixer [remove outdated] prefixes */
env?: string remove?: boolean
/** should Autoprefixer use Visual Cascade, if CSS is uncompressed */ /** should Autoprefixer add prefixes for @supports parameters. */
cascade?: boolean supports?: boolean
/** should Autoprefixer add prefixes. */ /** should Autoprefixer add prefixes for flexbox properties */
add?: boolean flexbox?: boolean | 'no-2009'
/** should Autoprefixer [remove outdated] prefixes */ /** should Autoprefixer add IE 10-11 prefixes for Grid Layout properties */
remove?: boolean grid?: boolean
/** should Autoprefixer add prefixes for @supports parameters. */ /**
supports?: boolean * list of queries for target browsers.
* Try to not use it.
/** should Autoprefixer add prefixes for flexbox properties */ * The best practice is to use `.browserslistrc` config or `browserslist` key in `package.json`
flexbox?: boolean | 'no-2009' * to share target browsers with Babel, ESLint and Stylelint
*/
/** should Autoprefixer add IE 10-11 prefixes for Grid Layout properties */ overrideBrowserslist?: string | string[]
grid?: boolean
/** do not raise error on unknown browser version in `Browserslist` config. */
/** ignoreUnknownVersions?: boolean
* list of queries for target browsers. };
* Try to not use it. define?: Record<string, string | object>,
* The best practice is to use `.browserslistrc` config or `browserslist` key in `package.json` router?: {
* to share target browsers with Babel, ESLint and Stylelint base?: string;
*/ routes?: RouteRecordRaw[];
overrideBrowserslist?: string | string[] mode?: 'hash' | 'history' | 'memory'
};
/** do not raise error on unknown browser version in `Browserslist` config. */ dynamicImport?: boolean;
ignoreUnknownVersions?: boolean inlineLimit?: number;
}; mock?: boolean | {
define?: Record<string, string | object>, prefix?: string;
router?: { };
base?: string; mountElementId?: string;
routes?: RouteRecordRaw[]; plugins?: string[];
mode?: 'hash' | 'history' | 'memory' presets?: string[];
}; proxy?: {
dynamicImport?: boolean; [apiPrefix: string]: {
inlineLimit?: number; target: string;
mock?: boolean | { changeOrigin?: boolean;
prefix?: string; }
}; };
mountElementId?: string; publicPath?: string;
plugins?: string[]; singular?: boolean;
presets?: string[]; targets?: object;
proxy?: { terserOptions?: object;
[apiPrefix: string]: { title?: string;
target: string; }
changeOrigin?: boolean; interface PluginRuntimeConfig {
} beforeRender?: (option: BeforeRenderConfig) => BeforeRenderConfig;
}; patchRoutes?: ({ routes }: { routes: RouteRecordRaw[] }) => void;
publicPath?: string; modifyClientRenderOpts?: (option: ClientRenderOption) => ClientRenderOption;
singular?: boolean; rootContainer?: (component: DefineComponent, option: { routes: RouteRecordRaw[], plugin: Plugin }) => DefineComponent;
targets?: object; onAppCreated?: ({ app, routes }: { app: App, routes: RouteRecordRaw[] }) => void;
terserOptions?: object; render?: (defaultRender: RenderFunc) => RenderFunc;
title?: string; onRouterCreated?: ({ router }: { router: Router }) => void;
}
export function getRouter(): Router;
} }

View File

@ -1,42 +1,46 @@
import { defineRuntimeConfig } from '@fesjs/fes'; import { defineRuntimeConfig } from '@fesjs/fes';
export default defineRuntimeConfig({ export default defineRuntimeConfig({
request: { request: {},
baseURL: '/ras-mas',
dataHandler(data) {
if (data?.code !== '0') {
if (data.code === '10000') {
console.log('code', data.code);
}
if (data?.code === '20000') {
console.log('code', data.code);
}
throw new Error(data);
}
return data.result ? data.result : data;
},
errorHandler(error) {
if (error.response) {
// 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// 请求已经成功发起,但没有收到响应
// `error.request` 在浏览器中是 XMLHttpRequest 的实例,
// 而在node.js中是 http.ClientRequest 的实例
console.log(error.request);
} else if (error.type) {
// 插件异常
console.log(error.msg);
} else {
// 发送请求时出了点问题
console.log('Error', error.message);
}
console.log(error.config);
},
},
patchRoutes: () => {
console.log('patchRoutes');
},
}); });
// export default defineRuntimeConfig({
// request: {
// baseURL: '/ras-mas',
// dataHandler(data) {
// if (data?.code !== '0') {
// if (data.code === '10000') {
// console.log('code', data.code);
// }
// if (data?.code === '20000') {
// console.log('code', data.code);
// }
// throw new Error(data);
// }
// return data.result ? data.result : data;
// },
// errorHandler(error) {
// if (error.response) {
// // 请求成功发出且服务器也响应了状态码,但状态代码超出了 2xx 的范围
// console.log(error.response.data);
// console.log(error.response.status);
// console.log(error.response.headers);
// } else if (error.request) {
// // 请求已经成功发起,但没有收到响应
// // `error.request` 在浏览器中是 XMLHttpRequest 的实例,
// // 而在node.js中是 http.ClientRequest 的实例
// console.log(error.request);
// } else if (error.type) {
// // 插件异常
// console.log(error.msg);
// } else {
// // 发送请求时出了点问题
// console.log('Error', error.message);
// }
// console.log(error.config);
// },
// },
// patchRoutes: () => {
// console.log('patchRoutes');
// },
// });

View File

@ -1,17 +1,21 @@
// @ts-ignore // @ts-ignore
import type { PluginRuntimeConfig, PluginBuildConfig } from '@@/configType'; import '@@/configType';
// @ts-ignore // // @ts-ignore
export * from '@@/core/coreExports'; // export * from '@@/core/coreExports';
// @ts-ignore // // @ts-ignore
export * from '@@/core/pluginExports'; // export * from '@@/core/pluginExports';
interface RouteMeta { export interface RouteMeta {
name?: string; name?: string;
title?: string; title?: string;
layout?: boolean | { sidebar?: boolean; header?: boolean; logo?: boolean }; layout?: boolean | { sidebar?: boolean; header?: boolean; logo?: boolean };
} }
export interface PluginRuntimeConfig {}
export interface PluginBuildConfig {}
export declare function defineRouteMeta(routeMeta: RouteMeta): RouteMeta; export declare function defineRouteMeta(routeMeta: RouteMeta): RouteMeta;
export function defineBuildConfig(config: PluginBuildConfig ): PluginBuildConfig; export function defineBuildConfig(config: PluginBuildConfig ): PluginBuildConfig;