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

View File

@ -1,8 +1,11 @@
import { dirname, join, basename, relative, extname } from 'path'; import { dirname, join, basename, relative, extname } from 'path';
import { compatESModuleRequire, resolve, winPath, pkgUp, lodash } from '@fesjs/utils'; import { compatESModuleRequire, resolve, winPath, pkgUp, lodash } from '@fesjs/utils';
import Logger from '../../logger';
import { PluginType } from '../enums'; import { PluginType } from '../enums';
const logger = new Logger('fes:compiler');
const RE = { const RE = {
[PluginType.plugin]: /^(@fesjs\/|@webank\/fes-|fes-)plugin-/, [PluginType.plugin]: /^(@fesjs\/|@webank\/fes-|fes-)plugin-/,
[PluginType.preset]: /^(@fesjs\/|@webank\/fes-|fes-)preset-/, [PluginType.preset]: /^(@fesjs\/|@webank\/fes-|fes-)preset-/,
@ -24,9 +27,15 @@ function filterPluginAndPreset(type, pkg) {
} }
function filterBuilder(pkg) { function filterBuilder(pkg) {
return Object.keys(pkg.devDependencies || {}) const builders = Object.keys(pkg.devDependencies || {})
.concat(Object.keys(pkg.dependencies || {})) .concat(Object.keys(pkg.dependencies || {}))
.filter((name) => /^@fesjs\/build-/.test(name)); .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) { export function getPluginsOrPresets(type, opts) {

View File

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

View File

@ -2,6 +2,7 @@ import { Logger } from '@fesjs/compiler';
import { readFileSync } from 'fs'; import { readFileSync } from 'fs';
import { join } from 'path'; import { join } from 'path';
import { resolvePkg } from '@fesjs/utils'; import { resolvePkg } from '@fesjs/utils';
import { name } from '../package.json';
const logger = new Logger('fes:plugin-request'); const logger = new Logger('fes:plugin-request');
@ -65,4 +66,14 @@ export default (api) => {
source: absoluteFilePath, 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/coreExports'),
require.resolve('./plugins/generateFiles/core/exports/pluginExports'), require.resolve('./plugins/generateFiles/core/exports/pluginExports'),
require.resolve('./plugins/generateFiles/fes'), require.resolve('./plugins/generateFiles/fes'),
require.resolve('./plugins/generateFiles/genType'),
// bundle configs // bundle configs
require.resolve('./plugins/features/base'), require.resolve('./plugins/features/base'),

View File

@ -3,9 +3,12 @@ import { plugin } from './plugin';
import * as Plugin_{{{ index }}} from '{{{ path }}}'; import * as Plugin_{{{ index }}} from '{{{ path }}}';
{{/plugins}} {{/plugins}}
// 避免编译警告
const defaultKey = 'default';
{{#plugins}} {{#plugins}}
plugin.register({ plugin.register({
apply: Plugin_{{{ index }}}, apply: Plugin_{{{ index }}}[defaultKey] ? Plugin_{{{ index }}}[defaultKey] : Plugin_{{{ index }}},
path: '{{{ path }}}', path: '{{{ path }}}',
}); });
{{/plugins}} {{/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', 'addEntryImports',
'addEntryCodeAhead', 'addEntryCodeAhead',
'addEntryCode', 'addEntryCode',
'modifyRoutes',
'addRuntimeType',
'addBuildType',
'addTmpGenerateWatcherPaths',
'addBeforeMiddlewares', 'addBeforeMiddlewares',
'addHTMLHeadScripts', 'addHTMLHeadScripts',
'addMiddlewares', 'addMiddlewares',
'modifyRoutes',
'modifyBundleConfigOpts', 'modifyBundleConfigOpts',
'modifyBundleConfig', 'modifyBundleConfig',
'modifyBabelOpts', 'modifyBabelOpts',
'modifyBabelPresetOpts', 'modifyBabelPresetOpts',
'chainWebpack', 'chainWebpack',
'addTmpGenerateWatcherPaths',
'modifyPublicPathStr', 'modifyPublicPathStr',
].forEach((name) => { ].forEach((name) => {
api.registerMethod({ name }); api.registerMethod({ name });

View File

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

View File

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

View File

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

View File

@ -1,4 +1,11 @@
export * from '@@/core/coreExports'; export * from '@@/core/coreExports';
// @ts-ignore // @ts-ignore
export * from '@@/core/pluginExports'; 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 // @ts-ignore
export * from '@@/core/coreExports'; export * from '@@/core/coreExports';
// @ts-ignore // @ts-ignore
export * from '@@/core/pluginExports'; export * from '@@/core/pluginExports';
export declare function defineRouteMeta(routeMeta: { 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 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;