refactor: 完成运行时类型改造

This commit is contained in:
winixt 2022-03-27 20:10:28 +08:00
parent 8f59d1612f
commit d6703f4a88
15 changed files with 208 additions and 46 deletions

3
.eslintignore Normal file
View File

@ -0,0 +1,3 @@
**/*.ts
lib

View File

@ -1,14 +1,11 @@
module.exports = {
extends: [
'@webank/eslint-config-webank/vue.js'
],
extends: ['@webank/eslint-config-webank/vue.js'],
globals: {
// 这里填入你的项目需要的全局变量
// 这里值为 false 表示这个全局变量不允许被重新赋值,比如:
//
// Vue: false
__DEV__: false
__DEV__: false,
},
rules: {
'vue/comment-directive': 'off',
@ -16,9 +13,9 @@ module.exports = {
'import/no-unresolved': 'off',
'no-restricted-syntax': 'off',
'no-undefined': 'off',
'vue/valid-template-root': 'off'
'vue/valid-template-root': 'off',
},
env: {
jest: true
}
jest: true,
},
};

View File

@ -1,8 +1,11 @@
import { dirname, join, basename, relative, extname } from 'path';
import { compatESModuleRequire, resolve, winPath, pkgUp, lodash } from '@fesjs/utils';
import Logger from '../../logger';
import { PluginType } from '../enums';
const logger = new Logger('fes:compiler');
const RE = {
[PluginType.plugin]: /^(@fesjs\/|@webank\/fes-|fes-)plugin-/,
[PluginType.preset]: /^(@fesjs\/|@webank\/fes-|fes-)preset-/,
@ -24,9 +27,15 @@ function filterPluginAndPreset(type, pkg) {
}
function filterBuilder(pkg) {
return Object.keys(pkg.devDependencies || {})
const builders = Object.keys(pkg.devDependencies || {})
.concat(Object.keys(pkg.dependencies || {}))
.filter((name) => /^@fesjs\/build-/.test(name));
if (builders.length > 1) {
logger.warn(`检测到您使用了多个个 builder: ${builders},当前生效的是 ${builders[0]}, 请保留一个`);
}
return builders.slice(0, 1);
}
export function getPluginsOrPresets(type, opts) {

View File

@ -34,5 +34,6 @@
"@fesjs/compiler": "^2.0.5",
"@fesjs/utils": "^2.0.4",
"axios": "0.21.1"
}
}
},
"typings": "./types.d.ts"
}

View File

@ -2,6 +2,7 @@ import { Logger } from '@fesjs/compiler';
import { readFileSync } from 'fs';
import { join } from 'path';
import { resolvePkg } from '@fesjs/utils';
import { name } from '../package.json';
const logger = new Logger('fes:plugin-request');
@ -65,4 +66,14 @@ export default (api) => {
source: absoluteFilePath,
},
]);
api.addRuntimeType(() => ({
source: name,
specifier: ['RequestRuntimeConfig'],
}));
api.addBuildType(() => ({
source: name,
specifier: ['RequestBuildConfig'],
}));
};

24
packages/fes-plugin-request/types.d.ts vendored Normal file
View File

@ -0,0 +1,24 @@
import { AxiosRequestConfig, AxiosResponse } from 'axios';
export interface RequestBuildConfig {
request: {
dataField: string
}
}
type RequestInterceptor = (value: AxiosRequestConfig) => AxiosRequestConfig | [(value: AxiosRequestConfig) => AxiosRequestConfig, (error: any) => any];
type ResponseInterceptor = (value: AxiosResponse) => AxiosResponse | [(value: AxiosResponse) => AxiosResponse, (error: any) => any];
export interface RequestRuntimeConfig {
request: {
responseDataAdaptor?<T>(data: T): T;
closeResDataCheck?: boolean;
requestInterceptors?: RequestInterceptor[];
responseInterceptors?: ResponseInterceptor[];
errorHandler: {
[key: string]: (error: { response: AxiosResponse } | AxiosResponse) => void;
};
} & AxiosRequestConfig;
}

View File

@ -9,6 +9,7 @@ export default function () {
require.resolve('./plugins/generateFiles/core/exports/coreExports'),
require.resolve('./plugins/generateFiles/core/exports/pluginExports'),
require.resolve('./plugins/generateFiles/fes'),
require.resolve('./plugins/generateFiles/genType'),
// bundle configs
require.resolve('./plugins/features/base'),

View File

@ -3,9 +3,12 @@ import { plugin } from './plugin';
import * as Plugin_{{{ index }}} from '{{{ path }}}';
{{/plugins}}
// 避免编译警告
const defaultKey = 'default';
{{#plugins}}
plugin.register({
apply: Plugin_{{{ index }}},
apply: Plugin_{{{ index }}}[defaultKey] ? Plugin_{{{ index }}}[defaultKey] : Plugin_{{{ index }}},
path: '{{{ path }}}',
});
{{/plugins}}

View File

@ -0,0 +1,52 @@
function importsToStr(imports) {
return imports.map((imp) => {
const { source, specifier } = imp;
if (specifier) {
return `import {${specifier.join(', ')}} from '${source}';`;
}
return '';
});
}
function genTypeContent(name, imports) {
return {
TYP_NAME: name,
TYPES: imports.reduce((previousValue, currentValue) => previousValue.concat(currentValue.specifier || []), []).join(' & '),
imports: importsToStr(imports).join('\n'),
};
}
export default function (api) {
const {
utils: { Mustache },
} = api;
api.onGenerateFiles(async () => {
const runtimeTypeName = 'PluginRuntimeConfig';
const buildTypeName = 'PluginBuildConfig';
const typeTpl = `
{{{ imports }}}
export type {{{TYP_NAME}}} = {{{TYPES}}}
`;
const runtimeImportSources = await api.applyPlugins({
key: 'addRuntimeType',
type: api.ApplyPluginsType.add,
initialValue: [],
});
api.writeTmpFile({
path: 'runtime.d.ts',
content: Mustache.render(typeTpl, genTypeContent(runtimeTypeName, runtimeImportSources)),
});
const buildImportSources = await api.applyPlugins({
key: 'addBuildType',
type: api.ApplyPluginsType.add,
initialValue: [],
});
api.writeTmpFile({
path: 'build.d.ts',
content: Mustache.render(typeTpl, genTypeContent(buildTypeName, buildImportSources)),
});
});
}

View File

@ -14,16 +14,21 @@ export default function (api) {
'addEntryImports',
'addEntryCodeAhead',
'addEntryCode',
'modifyRoutes',
'addRuntimeType',
'addBuildType',
'addTmpGenerateWatcherPaths',
'addBeforeMiddlewares',
'addHTMLHeadScripts',
'addMiddlewares',
'modifyRoutes',
'modifyBundleConfigOpts',
'modifyBundleConfig',
'modifyBabelOpts',
'modifyBabelPresetOpts',
'chainWebpack',
'addTmpGenerateWatcherPaths',
'modifyPublicPathStr',
].forEach((name) => {
api.registerMethod({ name });

View File

@ -1,19 +1,22 @@
export const request = {
errorHandler: {
111() {
console.log('root:111');
},
500() {
console.log('500 error');
},
default(error) {
console.log(error);
const msg = error?.data?.msg || error?.msg;
console.log(msg);
}
}
};
import { defineRuntimeConfig } from '@fesjs/fes';
export function patchRoutes() {
console.log('patchRoutes');
}
export default defineRuntimeConfig({
request: {
errorHandler: {
111() {
console.log('root:111');
},
500() {
console.log('500 error');
},
default(error) {
console.log(error);
const msg = error?.data?.msg || error?.msg;
console.log(msg);
},
},
},
patchRoutes: () => {
console.log('patchRoutes');
},
});

View File

@ -3,7 +3,10 @@
"outDir": "build/dist",
"module": "esnext",
"target": "esnext",
"lib": ["esnext", "dom"],
"lib": [
"esnext",
"dom"
],
"sourceMap": true,
"baseUrl": ".",
"jsx": "preserve",
@ -14,12 +17,15 @@
"suppressImplicitAnyIndexErrors": true,
"noUnusedLocals": true,
"allowJs": true,
"skipLibCheck": true,
"experimentalDecorators": true,
"strict": true,
"paths": {
"@/*": ["./src/*"],
"@@/*": ["./src/.fes/*"]
"@/*": [
"./src/*"
],
"@@/*": [
"./src/.fes/*"
]
}
},
"include": [
@ -29,9 +35,13 @@
"__test__/**/*",
"typings/**/*",
"config/**/*",
".eslintrc.js",
".stylelintrc.js",
".prettierrc.js"
"src/.fes/runtime.d.ts"
],
"exclude": ["node_modules", "build", "dist", "scripts", "src/.fes/*", "webpack", "jest"]
}
"exclude": [
"build",
"dist",
"scripts",
"webpack",
"jest"
]
}

View File

@ -42,10 +42,11 @@
"@fesjs/preset-built-in": "^2.0.22",
"@fesjs/runtime": "^2.0.2",
"@fesjs/utils": "^2.0.4",
"resolve-cwd": "^3.0.0"
"resolve-cwd": "^3.0.0",
"vue-router": "^4.0.1"
},
"engines": {
"node": "^10.12.0 || ^12.0.0 || >= 14.0.0"
},
"types": "types.d.ts"
}
}

View File

@ -1,4 +1,11 @@
export * from '@@/core/coreExports';
// @ts-ignore
export * from '@@/core/pluginExports';
export function defineBuildConfig(params) {
return params;
}
export function defineRuntimeConfig(params) {
return params;
}

View File

@ -1,10 +1,45 @@
import { Component, DefineComponent, App } from 'vue';
import { RouteRecordRaw, Router } from 'vue-router';
import { Plugin } from '@fesjs/runtime';
import { PluginRuntimeConfig } from '@@/runtime';
// @ts-ignore
export * from '@@/core/coreExports';
// @ts-ignore
export * from '@@/core/pluginExports';
export declare function defineRouteMeta(routeMeta: {
interface RouteMeta {
name?: string;
title?: string;
layout?: boolean | { sidebar?: boolean; header?: boolean; logo?: boolean };
});
}
export declare function defineRouteMeta(routeMeta: RouteMeta): RouteMeta;
interface BeforeRenderConfig {
loading: Component;
action: () => Promise<any>;
}
interface ClientRenderOption {
routes: RouteRecordRaw[];
rootElement: string;
defaultTitle: string;
plugin: Plugin;
}
type RenderFunc = () => Promise<App>
interface InnerRuntimeConfig {
beforeRender?: (option: BeforeRenderConfig) => BeforeRenderConfig;
patchRoutes?: ({ routes }: { routes: RouteRecordRaw[] }) => void;
modifyClientRenderOpts?: (option: ClientRenderOption) => ClientRenderOption;
rootContainer?: (component: DefineComponent, option: { routes: RouteRecordRaw[], plugin: Plugin }) => DefineComponent;
onAppCreated?: ({ app, routes }: { app: App, routes: RouteRecordRaw[] }) => void;
render?: (defaultRender: RenderFunc) => RenderFunc;
onRouterCreated?: ({ router }: { router: Router }) => void;
}
export function defineRuntimeConfig(config: InnerRuntimeConfig & PluginRuntimeConfig): InnerRuntimeConfig & PluginRuntimeConfig;