From 7f4eae3127fafc2552da8ddf3d40d7ecfb39dec8 Mon Sep 17 00:00:00 2001 From: xiaohuoni Date: Tue, 30 Jan 2024 11:37:51 +0800 Subject: [PATCH] fix: eslint error --- .eslintrc.js | 1 + packages/inula-cli/externals.d.ts | 17 +++++ .../builtInPlugins/command/dev/buildDev.ts | 4 +- .../command/generate/generate.ts | 12 ++-- .../src/builtInPlugins/command/proxy/proxy.ts | 2 +- packages/inula-cli/src/cli/cli.ts | 2 +- packages/inula-cli/src/config/Config.ts | 2 +- packages/inula-cli/src/core/Hub.ts | 16 +++-- packages/inula-cli/src/plugin/Plugin.ts | 6 +- packages/inula-cli/src/plugin/PluginAPI.ts | 2 +- packages/inula-cli/src/types/types.ts | 18 ++--- packages/inula-cli/src/utils/mockServer.ts | 12 ++-- packages/inula-cli/src/utils/util.ts | 1 - packages/inula-cli/tsconfig.json | 13 +++- packages/inula-intl/src/core/I18n.ts | 2 +- packages/inula-intl/src/format/Translation.ts | 8 +-- .../inula-intl/src/format/getFormatMessage.ts | 5 +- packages/inula-intl/src/parser/Lexer.ts | 16 ++--- packages/inula-intl/src/parser/mappingRule.ts | 4 +- .../inula-intl/src/parser/parseMappingRule.ts | 7 +- packages/inula-intl/src/parser/parser.ts | 4 +- packages/inula-intl/src/types/interfaces.ts | 4 +- packages/inula-intl/src/types/types.ts | 10 +-- .../inula-intl/src/utils/copyStaticProps.ts | 4 +- .../inula-intl/src/utils/parseRuleUtils.ts | 2 + packages/inula-intl/tests/core/I18n.test.ts | 8 +-- .../tests/utils/eventListener.test.ts | 2 +- .../inula-request/src/core/useIR/useIR.ts | 2 +- .../src/interceptor/InterceptorManager.ts | 2 +- .../inula-request/src/request/fetchRequest.ts | 4 +- .../src/request/ieFetchRequest.ts | 2 +- .../inula-request/src/types/interfaces.ts | 2 +- packages/inula-request/src/types/types.ts | 2 +- .../src/utils/commonUtils/utils.ts | 7 +- .../src/utils/dataUtils/transformData.ts | 2 +- .../utils/headerUtils/convertRawHeaders.ts | 6 +- .../utils/headerUtils/processValueByParser.ts | 2 +- .../src/history/__tests__/history.test.ts | 12 ++-- packages/inula-router/src/router/hooks.ts | 2 +- .../router/matcher/__tests__/lexer.test.ts | 4 +- .../inula-router/src/router/matcher/lexer.ts | 4 +- .../inula-router/src/router/matcher/parser.ts | 72 ++++++++++--------- .../inula-router/src/router/matcher/types.ts | 2 +- .../proxy/handlers/CollectionProxyHandler.ts | 4 +- .../inula/src/inulax/store/StoreHandler.ts | 2 +- packages/inula/src/inulax/types.ts | 24 +++---- packages/inula/src/renderer/ErrorHandler.ts | 32 +++++---- packages/inula/src/renderer/UpdateHandler.ts | 12 +++- .../src/renderer/taskExecutor/RenderQueue.ts | 2 - .../inula/src/renderer/vnode/VNodeCreator.ts | 7 +- 50 files changed, 223 insertions(+), 171 deletions(-) create mode 100644 packages/inula-cli/externals.d.ts diff --git a/.eslintrc.js b/.eslintrc.js index 5e4838ae..936be6cf 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -57,6 +57,7 @@ module.exports = { 'no-constant-condition': 'off', 'no-function-declare-after-return/no-function-declare-after-return': 'error', + '@typescript-eslint/ban-ts-comment': 'warn' }, globals: { isDev: true, diff --git a/packages/inula-cli/externals.d.ts b/packages/inula-cli/externals.d.ts new file mode 100644 index 00000000..2fe4981b --- /dev/null +++ b/packages/inula-cli/externals.d.ts @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Huawei Technologies Co.,Ltd. + * + * openInula is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * + * http://license.coscl.org.cn/MulanPSL2 + * + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +declare module 'crequire'; + diff --git a/packages/inula-cli/src/builtInPlugins/command/dev/buildDev.ts b/packages/inula-cli/src/builtInPlugins/command/dev/buildDev.ts index 9ffccf76..400fbe53 100644 --- a/packages/inula-cli/src/builtInPlugins/command/dev/buildDev.ts +++ b/packages/inula-cli/src/builtInPlugins/command/dev/buildDev.ts @@ -57,7 +57,7 @@ export default (api: API) => { api.applyHook({ name: 'afterStartDevServer' }); }); } else { - api.logger.error("Can't find config"); + api.logger.error('Can\'t find config'); } break; case 'vite': @@ -70,7 +70,7 @@ export default (api: API) => { server.printUrls(); }); } else { - api.logger.error("Can't find config"); + api.logger.error('Can\'t find config'); } break; default: diff --git a/packages/inula-cli/src/builtInPlugins/command/generate/generate.ts b/packages/inula-cli/src/builtInPlugins/command/generate/generate.ts index a556ebf3..777aefe8 100644 --- a/packages/inula-cli/src/builtInPlugins/command/generate/generate.ts +++ b/packages/inula-cli/src/builtInPlugins/command/generate/generate.ts @@ -33,15 +33,17 @@ export default (api: API) => { args._.shift(); } if (args._.length === 0) { - api.logger.warn("Can't find any generate options."); + api.logger.warn('Can\'t find any generate options.'); return; } switch (args._[0]) { case 'jest': - args._.shift(); - const isESM = api.packageJson['type'] === 'module'; - await generateJest(args, api.cwd, isESM); + { + args._.shift(); + const isESM = api.packageJson['type'] === 'module'; + await generateJest(args, api.cwd, isESM); + } break; default: } @@ -50,7 +52,7 @@ export default (api: API) => { }; const generateJest = async (args: yargsParser.Arguments, cwd: string, isESM: boolean) => { - let isTs: boolean = false; + let isTs = false; if (args['ts']) { isTs = true; } else { diff --git a/packages/inula-cli/src/builtInPlugins/command/proxy/proxy.ts b/packages/inula-cli/src/builtInPlugins/command/proxy/proxy.ts index 8a38d1ce..976fa718 100644 --- a/packages/inula-cli/src/builtInPlugins/command/proxy/proxy.ts +++ b/packages/inula-cli/src/builtInPlugins/command/proxy/proxy.ts @@ -25,7 +25,7 @@ export default (api: any) => { initialState: api.userConfig.remoteProxy, fn: async function (args: any, state: any) { if (!state) { - api.logger.error(`Invalid proxy config!`); + api.logger.error('Invalid proxy config!'); return; } const app = express(); diff --git a/packages/inula-cli/src/cli/cli.ts b/packages/inula-cli/src/cli/cli.ts index b33a4521..c01da174 100644 --- a/packages/inula-cli/src/cli/cli.ts +++ b/packages/inula-cli/src/cli/cli.ts @@ -61,7 +61,7 @@ export default async function run() { break; } - let enableDebug: boolean = false; + let enableDebug = false; if (process.env.DEBUG === 'true') { enableDebug = true; diff --git a/packages/inula-cli/src/config/Config.ts b/packages/inula-cli/src/config/Config.ts index 115ac5d8..923f6daf 100644 --- a/packages/inula-cli/src/config/Config.ts +++ b/packages/inula-cli/src/config/Config.ts @@ -89,7 +89,7 @@ export default class Config { getConfigFile(): string | null { const configFileList: string[] = DEFAULT_CONFIG_FILES.map(f => join(this.cwd, f)); - for (let configFile of configFileList) { + for (const configFile of configFileList) { if (existsSync(configFile)) { return configFile; } diff --git a/packages/inula-cli/src/core/Hub.ts b/packages/inula-cli/src/core/Hub.ts index 0c7835f8..531cbe00 100644 --- a/packages/inula-cli/src/core/Hub.ts +++ b/packages/inula-cli/src/core/Hub.ts @@ -46,11 +46,11 @@ export default class Hub { userConfig: UserConfig = {}; packageJson: PackageJSON; stage: ServiceStage = ServiceStage.uninitialized; - buildConfig: { name: string; config: object }[] = []; + buildConfig: { name: string; config: Record }[] = []; pluginManager: Plugin; buildConfigPath: BuildConfig[] = []; - devBuildConfig: object = {}; - compileMode: string = ''; + devBuildConfig: Record = {}; + compileMode = ''; builtInPlugins: string[] = []; pluginPaths: string[] = []; devProxy: DevProxy | null = null; @@ -150,14 +150,15 @@ export default class Hub { async analyzeBuildConfig() { if (this.userConfig.devBuildConfig) { - let { name, path, env } = this.userConfig.devBuildConfig; + let { path } = this.userConfig.devBuildConfig; + const { env } = this.userConfig.devBuildConfig; path = isAbsolute(path) ? path : join(process.cwd(), path); if (!existsSync(path)) { this.logger.warn(`Cant't find dev build config. Path is ${path}`); return; } this.logger.debug(`Find dev build config. Path is ${path}`); - let bc = await loadModule(path); + const bc = await loadModule | ((...args: any[]) => any)>(path); if (bc == undefined) { return; } @@ -196,14 +197,15 @@ export default class Hub { } this.buildConfigPath.forEach(async config => { - let { name, path } = config; + let { path } = config; + const { name } = config; path = isAbsolute(path) ? path : join(process.cwd(), path); if (!existsSync(path)) { this.logger.debug(`Cant't find build config. Path is ${path}`); return; } this.logger.debug(`Find build config. Path is ${path}`); - let bc = await loadModule(path); + const bc = await loadModule | ((...args: any[]) => any)>(path); if (bc == undefined) { return; } diff --git a/packages/inula-cli/src/plugin/Plugin.ts b/packages/inula-cli/src/plugin/Plugin.ts index cc34cdf1..d977bc2e 100644 --- a/packages/inula-cli/src/plugin/Plugin.ts +++ b/packages/inula-cli/src/plugin/Plugin.ts @@ -36,7 +36,7 @@ export interface IPlugin { id: string; key: string; path: string; - apply: Function; + apply: (...args: any[]) => any; } export default class Plugin { @@ -57,7 +57,7 @@ export default class Plugin { } = {}; hub: Hub; logger: Logger; - registerFunction: Function[] = []; + registerFunction: ((...args: any[]) => any)[] = []; // 解决调用this[props]时ts提示属性未知 [key: string]: any; @@ -110,7 +110,7 @@ export default class Plugin { }); for (const obj of objs) { - const module: Function | undefined = await loadModule(obj.path); + const module: ((...args: any[]) => any) | undefined = await loadModule(obj.path); if (module) { try { module(obj.api); diff --git a/packages/inula-cli/src/plugin/PluginAPI.ts b/packages/inula-cli/src/plugin/PluginAPI.ts index 80104853..5ecf59ec 100644 --- a/packages/inula-cli/src/plugin/PluginAPI.ts +++ b/packages/inula-cli/src/plugin/PluginAPI.ts @@ -55,7 +55,7 @@ export default class PluginAPI { this.register(hook); } - registerMethod(fn: Function) { + registerMethod(fn: (...args: any[]) => any) { this.manager.registerFunction.push(fn); } diff --git a/packages/inula-cli/src/types/types.ts b/packages/inula-cli/src/types/types.ts index c1d17e6a..f9de6561 100644 --- a/packages/inula-cli/src/types/types.ts +++ b/packages/inula-cli/src/types/types.ts @@ -19,8 +19,8 @@ import { Logger } from '../utils/logger.js'; import type * as http from 'http'; import type * as express from 'express'; -interface Request extends express.Request {} -interface Response extends express.Response {} +type Request = express.Request; +type Response = express.Response; export interface IDep { [name: string]: string; @@ -37,7 +37,7 @@ export interface IPlugin { id: string; key: string; path: string; - apply: Function; + apply: (...args: any[]) => any; config?: IPluginConfig; isPreset?: boolean; @@ -45,7 +45,7 @@ export interface IPlugin { export interface IPluginConfig { default?: any; - onChange?: string | Function; + onChange?: string | ((...args: any[]) => any); } export interface IHook { @@ -94,7 +94,7 @@ export interface API { (hook: IHook): void; }; registerMethod: { - (method: Function): void; + (method: (...args: any[]) => any): void; }; applyHook: { (opts: applyHookConfig): void; @@ -133,8 +133,8 @@ export interface MockConfig { export interface DevBuildConfig { name: string; path: string; - args?: object; - env?: object; + args?: Record; + env?: Record; devProxy?: DevProxy; } @@ -147,8 +147,8 @@ export interface DevProxy { export interface BuildConfig { name: string; path: string; - args?: object; - env?: object; + args?: Record; + env?: Record; } export type ExportUserConfig = UserConfig | Promise; diff --git a/packages/inula-cli/src/utils/mockServer.ts b/packages/inula-cli/src/utils/mockServer.ts index bac59eb6..07dd9c4f 100644 --- a/packages/inula-cli/src/utils/mockServer.ts +++ b/packages/inula-cli/src/utils/mockServer.ts @@ -38,13 +38,15 @@ function getMocksFile() { const mockFiles = globSync('**/*.js', { cwd: mockDir, }); - let ret = mockFiles.reduce((mocks: any, mockFile: string) => { + const ret = mockFiles.reduce((mocks: any, mockFile: string) => { if (!mockFile.startsWith('_')) { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const file = require(join(mockDir, mockFile)); mocks = { ...mocks, - ...require(join(mockDir, mockFile)), + ...file, }; - console.log('mockFile', require(join(mockDir, mockFile))); + console.log('mockFile', file); } return mocks; @@ -54,8 +56,8 @@ function getMocksFile() { } function generateRoutes(app: any) { - let mockStartIndex = app._router.stack.length, - mocks: Mock = {}; + const mockStartIndex = app._router.stack.length; + let mocks: Mock = {}; try { mocks = getMocksFile(); diff --git a/packages/inula-cli/src/utils/util.ts b/packages/inula-cli/src/utils/util.ts index e19d663c..3c6bdf46 100644 --- a/packages/inula-cli/src/utils/util.ts +++ b/packages/inula-cli/src/utils/util.ts @@ -16,7 +16,6 @@ import { dirname } from 'path'; import { readFileSync, writeFileSync } from 'fs'; import resolve from 'resolve'; -// @ts-ignore import crequire from 'crequire'; import { createRequire } from 'module'; const require = createRequire(import.meta.url); diff --git a/packages/inula-cli/tsconfig.json b/packages/inula-cli/tsconfig.json index 91272098..2e493303 100644 --- a/packages/inula-cli/tsconfig.json +++ b/packages/inula-cli/tsconfig.json @@ -11,9 +11,16 @@ "moduleResolution": "node", "esModuleInterop": true, }, - "include": ["src/**/*"], - "exclude": ["node_modules", "**/*.spec.ts", "./src/template/**/*"], + "include": [ + "src/**/*", + "./externals.d.ts" + ], + "exclude": [ + "node_modules", + "**/*.spec.ts", + "./src/template/**/*" + ], "ts-node": { "esm": true, }, -} \ No newline at end of file +} diff --git a/packages/inula-intl/src/core/I18n.ts b/packages/inula-intl/src/core/I18n.ts index f2b94480..337166d1 100644 --- a/packages/inula-intl/src/core/I18n.ts +++ b/packages/inula-intl/src/core/I18n.ts @@ -117,7 +117,7 @@ export class I18n extends EventDispatcher { formatMessage( id: MessageDescriptor | string, - values: Object | undefined = {}, + values: Record | undefined = {}, { message, context, formatOptions }: MessageOptions = {} ) { return getFormatMessage(this, id, values, { message, context, formatOptions }); diff --git a/packages/inula-intl/src/format/Translation.ts b/packages/inula-intl/src/format/Translation.ts index bbf8d8a0..20f27b77 100644 --- a/packages/inula-intl/src/format/Translation.ts +++ b/packages/inula-intl/src/format/Translation.ts @@ -40,11 +40,11 @@ class Translation { * @param values 需要替换文本占位符的值 * @param formatOptions 需要格式化选项 */ - translate(values: object, formatOptions: FormatOptions = {}): string { + translate(values: Record, formatOptions: FormatOptions = {}): string { const createTextFormatter = ( locale: Locale, locales: Locales, - values: object, + values: Record, formatOptions: FormatOptions, localeConfig: LocaleConfig ) => { @@ -66,13 +66,13 @@ class Translation { return textFormatter; }; - let textFormatter = createTextFormatter(this.locale, this.locales, values, formatOptions, this.localeConfig); + const textFormatter = createTextFormatter(this.locale, this.locales, values, formatOptions, this.localeConfig); // 通过递归方法formatCore进行格式化处理 const result = this.formatMessage(this.compiledMessage, textFormatter); return result; // 返回要格式化的结果 } - formatMessage(compiledMessage: CompiledMessage, textFormatter: Function) { + formatMessage(compiledMessage: CompiledMessage, textFormatter: (...args: any[]) => any) { if (!Array.isArray(compiledMessage)) { return compiledMessage; } diff --git a/packages/inula-intl/src/format/getFormatMessage.ts b/packages/inula-intl/src/format/getFormatMessage.ts index 10daf741..6e34b6f5 100644 --- a/packages/inula-intl/src/format/getFormatMessage.ts +++ b/packages/inula-intl/src/format/getFormatMessage.ts @@ -23,10 +23,11 @@ import creatI18nCache from './cache/cache'; export function getFormatMessage( i18n: I18n, id: MessageDescriptor | string, - values: Object | undefined = {}, + values: Record | undefined = {}, options: MessageOptions = {} ) { - let { message, context, formatOptions } = options; + let { message, context } = options; + const { formatOptions } = options; const cache = i18n.cache ?? creatI18nCache(); if (typeof id !== 'string') { values = values || id.defaultValues; diff --git a/packages/inula-intl/src/parser/Lexer.ts b/packages/inula-intl/src/parser/Lexer.ts index f4a602b1..eee91a80 100644 --- a/packages/inula-intl/src/parser/Lexer.ts +++ b/packages/inula-intl/src/parser/Lexer.ts @@ -19,19 +19,19 @@ import { LexerInterface } from '../types/interfaces'; class Lexer implements LexerInterface { readonly startState: string; readonly states: Record; - private buffer: string = ''; + private buffer = ''; private stack: string[] = []; - private index: number = 0; - private line: number = 1; - private col: number = 1; - private queuedText: string = ''; - private state: string = ''; + private index = 0; + private line = 1; + private col = 1; + private queuedText = ''; + private state = ''; private groups: string[] = []; private error: Record | undefined; private regexp; - private fast: object = {}; + private fast: Record = {}; private queuedGroup: string | null = ''; - private value: string = ''; + private value = ''; constructor(unionReg: Record, startState: string) { this.startState = startState; diff --git a/packages/inula-intl/src/parser/mappingRule.ts b/packages/inula-intl/src/parser/mappingRule.ts index 54bee482..1dff32ec 100644 --- a/packages/inula-intl/src/parser/mappingRule.ts +++ b/packages/inula-intl/src/parser/mappingRule.ts @@ -14,11 +14,11 @@ */ const body: Record = { - doubleapos: { match: "''", value: () => "'" }, + doubleapos: { match: '\'\'', value: () => '\'' }, quoted: { lineBreaks: true, match: /'[{}#](?:[^]*?[^'])?'(?!')/u, - value: src => src.slice(1, -1).replace(/''/g, "'"), + value: src => src.slice(1, -1).replace(/''/g, '\''), }, argument: { lineBreaks: true, diff --git a/packages/inula-intl/src/parser/parseMappingRule.ts b/packages/inula-intl/src/parser/parseMappingRule.ts index 9323378c..5cdaf6f0 100644 --- a/packages/inula-intl/src/parser/parseMappingRule.ts +++ b/packages/inula-intl/src/parser/parseMappingRule.ts @@ -23,8 +23,8 @@ const defaultErrorRule = ruleUtils.getRuleOptions('error', { lineBreaks: true, s // 解析规则并生成词法分析器所需的数据结构,以便进行词法分析操作 function parseRules(rules: Record, hasStates: boolean): Record { let errorRule: Record | null = null; - const fast: object = {}; - let enableFast: boolean = true; + const fast: Record = {}; + let enableFast = true; let unicodeFlag: boolean | null = null; const groups: Record[] = []; const parts: string[] = []; @@ -148,6 +148,7 @@ function parseMappingRule(mappingRule: Record, startState?: string) } }); } + // eslint-disable-next-line rules.splice.apply(rules, splice); j--; } @@ -176,7 +177,7 @@ function parseMappingRule(mappingRule: Record, startState?: string) return new Lexer(mappingAllRules, startState); } -function processFast(match, fast: {}, options) { +function processFast(match, fast: Record, options) { while (match.length && typeof match[0] === 'string' && match[0].length === 1) { const word = match.shift(); fast[word.charCodeAt(0)] = options; diff --git a/packages/inula-intl/src/parser/parser.ts b/packages/inula-intl/src/parser/parser.ts index cf885f67..221a68e3 100644 --- a/packages/inula-intl/src/parser/parser.ts +++ b/packages/inula-intl/src/parser/parser.ts @@ -42,7 +42,7 @@ class Parser { isSelectKeyValid(token: RawToken, type: Select['type'], value: string) { if (value[0] === '=') { if (type === 'select') { - throw new Error(`The key value of the select type is invalid.`); + throw new Error('The key value of the select type is invalid.'); } } else if (type !== 'select') { const values = type === 'plural' ? this.cardinalKeys : this.ordinalKeys; @@ -132,7 +132,7 @@ class Parser { if (checkSelectType(nextToken.value.toLowerCase())) { throw new Error(`Invalid parameter type: ${nextToken.value}`); } - let param = this.parse(isPlural); + const param = this.parse(isPlural); return { type: 'function', diff --git a/packages/inula-intl/src/types/interfaces.ts b/packages/inula-intl/src/types/interfaces.ts index 9aba8fe1..34f9f8a7 100644 --- a/packages/inula-intl/src/types/interfaces.ts +++ b/packages/inula-intl/src/types/interfaces.ts @@ -19,7 +19,7 @@ import Lexer from '../parser/Lexer'; // FormattedMessage的参数定义 export interface FormattedMessageProps extends MessageDescriptor { - values?: object; + values?: Record; tagName?: string; children?(nodes: any[]): any; @@ -203,7 +203,7 @@ export interface InjectedIntl { // 信息格式化 formatMessage( messageDescriptor: MessageDescriptor, - values?: object, + values?: Record, options?: MessageOptions, useMemorize?: boolean ): string; diff --git a/packages/inula-intl/src/types/types.ts b/packages/inula-intl/src/types/types.ts index d5607ab6..917d7f07 100644 --- a/packages/inula-intl/src/types/types.ts +++ b/packages/inula-intl/src/types/types.ts @@ -32,7 +32,7 @@ export type Locale = string; export type Locales = Locale | Locale[]; -export type LocaleConfig = { plurals?: Function }; +export type LocaleConfig = { plurals?: (...arg: any) => any }; export type AllLocaleConfig = Record; @@ -59,7 +59,7 @@ export type Token = Content | PlainArg | FunctionArg | Select | Octothorpe; export type DatePool = Date | string; -export type SelectPool = string | object; +export type SelectPool = string | Record; export type RawToken = { type: string; @@ -76,9 +76,9 @@ export type I18nProviderProps = I18nContextProps & configProps; export type IntlType = { i18n: I18n; - formatMessage: Function; - formatNumber: Function; - formatDate: Function; + formatMessage: (...args: any[]) => any; + formatNumber: (...args: any[]) => any; + formatDate: (...args: any[]) => any; }; export interface InjectedIntlProps { diff --git a/packages/inula-intl/src/utils/copyStaticProps.ts b/packages/inula-intl/src/utils/copyStaticProps.ts index 31e4a1e8..665e2b82 100644 --- a/packages/inula-intl/src/utils/copyStaticProps.ts +++ b/packages/inula-intl/src/utils/copyStaticProps.ts @@ -73,7 +73,9 @@ function copyStaticProps(targetComponent: T, sourceComponent: U): T { try { // 在一个已有的targetComponent对象上增加sourceComponent的属性 Object.defineProperty(targetComponent, key, Object.getOwnPropertyDescriptor(sourceComponent, key)!); - } catch (e) {} + } catch (e) { + console.log('Error occurred while copying static props:', e); + } } }); diff --git a/packages/inula-intl/src/utils/parseRuleUtils.ts b/packages/inula-intl/src/utils/parseRuleUtils.ts index a28bd1f7..f950510b 100644 --- a/packages/inula-intl/src/utils/parseRuleUtils.ts +++ b/packages/inula-intl/src/utils/parseRuleUtils.ts @@ -32,12 +32,14 @@ const checkSticky = () => typeof new RegExp('')?.sticky === 'boolean'; // 转义正则表达式中的特殊字符 function transferReg(s: string): string { + // eslint-disable-next-line return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); } // 计算正则表达式中捕获组的数量 function getRegGroups(s: string): number { const re = new RegExp('|' + s); + // eslint-disable-next-line return re.exec('')?.length! - 1; } diff --git a/packages/inula-intl/tests/core/I18n.test.ts b/packages/inula-intl/tests/core/I18n.test.ts index e33c7e82..77079664 100644 --- a/packages/inula-intl/tests/core/I18n.test.ts +++ b/packages/inula-intl/tests/core/I18n.test.ts @@ -90,19 +90,19 @@ describe('I18n', () => { }); it('._ allow escaping syntax characters', () => { const messages = { - "My ''name'' is '{name}'": "Mi ''nombre'' es '{name}'", + 'My \'\'name\'\' is \'{name}\'': 'Mi \'\'nombre\'\' es \'{name}\'', }; const i18n = new I18n({ locale: 'es', messages: { es: messages }, }); - expect(i18n.formatMessage("My ''name'' is '{name}'")).toEqual("Mi 'nombre' es {name}"); + expect(i18n.formatMessage('My \'\'name\'\' is \'{name}\'')).toEqual('Mi \'nombre\' es {name}'); }); it('._ should format message from catalog', function () { const messages = { Hello: 'Salut', - id: "Je m'appelle {name}", + id: 'Je m\'appelle {name}', }; const i18n = new I18n({ locale: 'fr', @@ -110,7 +110,7 @@ describe('I18n', () => { }); expect(i18n.locale).toEqual('fr'); expect(i18n.formatMessage('Hello')).toEqual('Salut'); - expect(i18n.formatMessage('id', { name: 'Fred' })).toEqual("Je m'appelle Fred"); + expect(i18n.formatMessage('id', { name: 'Fred' })).toEqual('Je m\'appelle Fred'); }); it('should return the formatted date and time', () => { diff --git a/packages/inula-intl/tests/utils/eventListener.test.ts b/packages/inula-intl/tests/utils/eventListener.test.ts index c72af6cf..17e0f43b 100644 --- a/packages/inula-intl/tests/utils/eventListener.test.ts +++ b/packages/inula-intl/tests/utils/eventListener.test.ts @@ -43,7 +43,7 @@ describe('eventEmitter', () => { expect(listener).not.toBeCalled(); }); - it("should do nothing when even doesn't exist", () => { + it('should do nothing when even doesn\'t exist', () => { const unknown = jest.fn(); const emitter = new EventEmitter(); diff --git a/packages/inula-request/src/core/useIR/useIR.ts b/packages/inula-request/src/core/useIR/useIR.ts index 97879ba5..21131de4 100644 --- a/packages/inula-request/src/core/useIR/useIR.ts +++ b/packages/inula-request/src/core/useIR/useIR.ts @@ -38,7 +38,7 @@ const useIR = ( Inula.useEffect(() => { const fetchData = async () => { try { - let result = await irClient.query(url, config, options); + const result = await irClient.query(url, config, options); document.addEventListener('request', handleRequest(result)); setData(result); // 未设置轮询查询时展示一次 diff --git a/packages/inula-request/src/interceptor/InterceptorManager.ts b/packages/inula-request/src/interceptor/InterceptorManager.ts index 3543c069..ad53f9f3 100644 --- a/packages/inula-request/src/interceptor/InterceptorManager.ts +++ b/packages/inula-request/src/interceptor/InterceptorManager.ts @@ -48,7 +48,7 @@ class InterceptorManager implements IrInterceptorManager { this.handlers = []; } - forEach(func: Function) { + forEach(func: (...arg: any) => any) { utils.forEach(this.handlers, function forEachHandler(h: any) { if (h !== null) { func(h); diff --git a/packages/inula-request/src/request/fetchRequest.ts b/packages/inula-request/src/request/fetchRequest.ts index 5f25e803..51a318a2 100644 --- a/packages/inula-request/src/request/fetchRequest.ts +++ b/packages/inula-request/src/request/fetchRequest.ts @@ -23,7 +23,7 @@ import CancelError from '../cancel/CancelError'; export const fetchRequest = (config: IrRequestConfig): Promise => { return new Promise((resolve, reject) => { - let { + const { method = 'GET', baseURL, url, @@ -40,7 +40,7 @@ export const fetchRequest = (config: IrRequestConfig): Promise => { signal, } = config; - let controller = new AbortController(); + const controller = new AbortController(); if (!signal) { signal = controller.signal; } diff --git a/packages/inula-request/src/request/ieFetchRequest.ts b/packages/inula-request/src/request/ieFetchRequest.ts index c360e65b..a1d55c2f 100644 --- a/packages/inula-request/src/request/ieFetchRequest.ts +++ b/packages/inula-request/src/request/ieFetchRequest.ts @@ -21,7 +21,7 @@ import { Method, ResponseType } from '../types/types'; export const ieFetchRequest = (config: IrRequestConfig): Promise => { return new Promise((resolve, reject) => { - let { + const { method = 'get', baseURL, url, diff --git a/packages/inula-request/src/types/interfaces.ts b/packages/inula-request/src/types/interfaces.ts index 93a964dc..cf5ea949 100644 --- a/packages/inula-request/src/types/interfaces.ts +++ b/packages/inula-request/src/types/interfaces.ts @@ -231,7 +231,7 @@ export interface IrInterceptorManager { clear(): void; // 过滤跳过迭代器 - forEach(func: Function): void; + forEach(func: (...arg: any) => any): void; } export interface IrErrorInterface { diff --git a/packages/inula-request/src/types/types.ts b/packages/inula-request/src/types/types.ts index 5edc6390..f096ed0d 100644 --- a/packages/inula-request/src/types/types.ts +++ b/packages/inula-request/src/types/types.ts @@ -39,7 +39,7 @@ export type IrTransformer = (data: any, headers?: IrHeaders) => any; // Headers export type HeaderMap = Record; -export type HeaderMatcher = boolean | RegExp | Function; +export type HeaderMatcher = boolean | RegExp | ((...args: any[]) => any); // Promise 成功和拒绝类型 export type FulfilledFn = (value: T) => T | Promise; // 泛型确保了拦截器链中各个环节之间的一致性,避免数据类型不匹配引发的错误 diff --git a/packages/inula-request/src/utils/commonUtils/utils.ts b/packages/inula-request/src/utils/commonUtils/utils.ts index d96ce0fc..f162363e 100644 --- a/packages/inula-request/src/utils/commonUtils/utils.ts +++ b/packages/inula-request/src/utils/commonUtils/utils.ts @@ -23,7 +23,7 @@ import { Callback, FilterFunc, PropFilterFunc } from '../../types/types'; * * @returns {any} 新的函数,当这个新的函数被调用时,它会调用 func 函数,并使用 apply() 方法将 thisArg 作为上下文对象,将传递的参数作为 func 函数的参数传递给它 */ -function bind(func: Function, thisArg: any): (...args: any[]) => any { +function bind(func: (...args: any[]) => any, thisArg: any): (...args: any[]) => any { return (...args: any[]) => func.apply(thisArg, args); } @@ -107,7 +107,7 @@ const checkHTMLForm = createTypeChecker('HTMLFormElement'); */ function forEach( input: T | T[] | Record | null | undefined, - func: Function, + func: (...args: any[]) => any, options: { includeAll?: boolean } = {} ): void { if (input === null || input === undefined) { @@ -194,7 +194,7 @@ function extendObject( * @returns {string[]} 所有属性名数组 */ function getAllPropertyNames(obj: Record): string[] { - let result: string[] = []; + const result: string[] = []; let currentObj = obj; while (currentObj) { const propNames = Object.getOwnPropertyNames(currentObj); @@ -406,6 +406,7 @@ function objectToQueryString(obj: Record) { const all = (promises: Array>): Promise => Promise.all(promises); function spread(callback: Callback): (arr: any[]) => T { + // eslint-disable-next-line return (arr: any[]): T => callback.apply(null, arr); } diff --git a/packages/inula-request/src/utils/dataUtils/transformData.ts b/packages/inula-request/src/utils/dataUtils/transformData.ts index 363ae9a8..fb2f5ec5 100644 --- a/packages/inula-request/src/utils/dataUtils/transformData.ts +++ b/packages/inula-request/src/utils/dataUtils/transformData.ts @@ -17,7 +17,7 @@ import IrHeaders from '../../core/IrHeaders'; import defaultConfig from '../../config/defaultConfig'; import { IrRequestConfig, IrResponse } from '../../types/interfaces'; -function transformData(inputConfig: IrRequestConfig, func: Function, response?: IrResponse) { +function transformData(inputConfig: IrRequestConfig, func: (...arg: any) => any, response?: IrResponse) { const config = inputConfig || defaultConfig; const context = response || config; const headers = IrHeaders.from(context.headers); diff --git a/packages/inula-request/src/utils/headerUtils/convertRawHeaders.ts b/packages/inula-request/src/utils/headerUtils/convertRawHeaders.ts index 439d3dfc..6b6d739a 100644 --- a/packages/inula-request/src/utils/headerUtils/convertRawHeaders.ts +++ b/packages/inula-request/src/utils/headerUtils/convertRawHeaders.ts @@ -20,9 +20,9 @@ function convertRawHeaders(rawHeaders: string): HeaderMap { if (rawHeaders) { rawHeaders.split('\n').forEach((item: string) => { - let i = item.indexOf(':'); - let key = item.substring(0, i).trim().toLowerCase(); - let val = item.substring(i + 1).trim(); + const i = item.indexOf(':'); + const key = item.substring(0, i).trim().toLowerCase(); + const val = item.substring(i + 1).trim(); if (!key || (convertedHeaders[key] && key !== 'set-cookie')) { return; diff --git a/packages/inula-request/src/utils/headerUtils/processValueByParser.ts b/packages/inula-request/src/utils/headerUtils/processValueByParser.ts index 67bdc999..fcc33cf0 100644 --- a/packages/inula-request/src/utils/headerUtils/processValueByParser.ts +++ b/packages/inula-request/src/utils/headerUtils/processValueByParser.ts @@ -38,7 +38,7 @@ function processValueByParser(key: string, value: any, parser?: HeaderMatcher): return parseKeyValuePairs(value); } if (utils.checkFunction(parser)) { - return (parser as Function)(value, key); + return (parser as (value: any, key: string) => any)(value, key); } if (utils.checkRegExp(parser)) { return (parser as RegExp).exec(value)?.filter(item => item !== undefined); diff --git a/packages/inula-router/src/history/__tests__/history.test.ts b/packages/inula-router/src/history/__tests__/history.test.ts index 3d6dbb83..8c92c2ce 100644 --- a/packages/inula-router/src/history/__tests__/history.test.ts +++ b/packages/inula-router/src/history/__tests__/history.test.ts @@ -18,14 +18,14 @@ import { createPath } from '../utils'; describe('createPath', () => { describe('given only a pathname', () => { it('returns the pathname unchanged', () => { - let path = createPath({ pathname: 'https://google.com' }); + const path = createPath({ pathname: 'https://google.com' }); expect(path).toBe('https://google.com'); }); }); describe('given a pathname and a search param', () => { it('returns the constructed pathname', () => { - let path = createPath({ + const path = createPath({ pathname: 'https://google.com', search: '?something=cool', }); @@ -35,7 +35,7 @@ describe('createPath', () => { describe('given a pathname and a search param without ?', () => { it('returns the constructed pathname', () => { - let path = createPath({ + const path = createPath({ pathname: 'https://google.com', search: 'something=cool', }); @@ -45,7 +45,7 @@ describe('createPath', () => { describe('given a pathname and a hash param', () => { it('returns the constructed pathname', () => { - let path = createPath({ + const path = createPath({ pathname: 'https://google.com', hash: '#section-1', }); @@ -55,7 +55,7 @@ describe('createPath', () => { describe('given a pathname and a hash param without #', () => { it('returns the constructed pathname', () => { - let path = createPath({ + const path = createPath({ pathname: 'https://google.com', hash: 'section-1', }); @@ -65,7 +65,7 @@ describe('createPath', () => { describe('given a full location object', () => { it('returns the constructed pathname', () => { - let path = createPath({ + const path = createPath({ pathname: 'https://google.com', search: 'something=cool', hash: '#section-1', diff --git a/packages/inula-router/src/router/hooks.ts b/packages/inula-router/src/router/hooks.ts index c89b95ba..55b976c6 100644 --- a/packages/inula-router/src/router/hooks.ts +++ b/packages/inula-router/src/router/hooks.ts @@ -29,7 +29,7 @@ function useLocation() { return useContext(RouterContext).location; } -function useParams

(): Params

| {}; +function useParams

(): Params

| Record; function useParams() { const match = useContext(RouterContext).match; return match ? match.params : {}; diff --git a/packages/inula-router/src/router/matcher/__tests__/lexer.test.ts b/packages/inula-router/src/router/matcher/__tests__/lexer.test.ts index e35313dd..f6741216 100644 --- a/packages/inula-router/src/router/matcher/__tests__/lexer.test.ts +++ b/packages/inula-router/src/router/matcher/__tests__/lexer.test.ts @@ -38,9 +38,9 @@ describe('path lexer Test', () => { expect(tokens).toStrictEqual([{ type: 'delimiter', value: '/' }]); }); - it(`don't start with a slash`, () => { + it('don\'t start with a slash', () => { const func = () => lexer('abc.com'); - expect(func).toThrow(Error(`Url must start with "/".`)); + expect(func).toThrow(Error('Url must start with "/".')); }); it('dynamic params test', () => { diff --git a/packages/inula-router/src/router/matcher/lexer.ts b/packages/inula-router/src/router/matcher/lexer.ts index 2cba36f8..77144e24 100644 --- a/packages/inula-router/src/router/matcher/lexer.ts +++ b/packages/inula-router/src/router/matcher/lexer.ts @@ -26,9 +26,9 @@ export function lexer(path: string): Token[] { return tokens; } - let urlPath = cleanPath(path); + const urlPath = cleanPath(path); if (urlPath !== '*' && !urlPath.startsWith('/')) { - throw new Error(`Url must start with "/".`); + throw new Error('Url must start with "/".'); } const getLiteral = () => { diff --git a/packages/inula-router/src/router/matcher/parser.ts b/packages/inula-router/src/router/matcher/parser.ts index 969228d7..9ea88fa7 100644 --- a/packages/inula-router/src/router/matcher/parser.ts +++ b/packages/inula-router/src/router/matcher/parser.ts @@ -84,7 +84,7 @@ export function createPathParser

(pathname: string, option: ParserOp * @param currentIdx */ const lookToNextDelimiter = (currentIdx: number): boolean => { - let hasOptionalParam: boolean = false; + let hasOptionalParam = false; while (currentIdx < tokens.length && tokens[currentIdx].type !== TokenType.Delimiter) { if (tokens[currentIdx].value === '?' || tokens[currentIdx].value === '*') { hasOptionalParam = true; @@ -98,8 +98,10 @@ export function createPathParser

(pathname: string, option: ParserOp const nextToken = tokens[tokenIdx + 1]; switch (token.type) { case TokenType.Delimiter: - const hasOptional = lookToNextDelimiter(tokenIdx + 1); - pattern += `/${hasOptional ? '?' : ''}`; + { + const hasOptional = lookToNextDelimiter(tokenIdx + 1); + pattern += `/${hasOptional ? '?' : ''}`; + } break; case TokenType.Static: pattern += token.value.replace(REGEX_CHARS_RE, '\\$&'); @@ -111,28 +113,30 @@ export function createPathParser

(pathname: string, option: ParserOp scores.push(MatchScore.static); break; case TokenType.Param: - // 动态参数支持形如/:param、/:param*、/:param?、/:param(\\d+)的形式 - let paramRegexp = ''; - if (nextToken) { - switch (nextToken.type) { - case TokenType.LBracket: - // 跳过当前Token和左括号 - tokenIdx += 2; - while (tokens[tokenIdx].type !== TokenType.RBracket) { - paramRegexp += tokens[tokenIdx].value; + { + // 动态参数支持形如/:param、/:param*、/:param?、/:param(\\d+)的形式 + let paramRegexp = ''; + if (nextToken) { + switch (nextToken.type) { + case TokenType.LBracket: + // 跳过当前Token和左括号 + tokenIdx += 2; + while (tokens[tokenIdx].type !== TokenType.RBracket) { + paramRegexp += tokens[tokenIdx].value; + tokenIdx++; + } + paramRegexp = `(${paramRegexp})`; + break; + case TokenType.Pattern: tokenIdx++; - } - paramRegexp = `(${paramRegexp})`; - break; - case TokenType.Pattern: - tokenIdx++; - paramRegexp += `(${nextToken.value === '*' ? '.*' : BASE_PARAM_PATTERN})${nextToken.value}`; - break; + paramRegexp += `(${nextToken.value === '*' ? '.*' : BASE_PARAM_PATTERN})${nextToken.value}`; + break; + } } + pattern += paramRegexp ? `(?:${paramRegexp})` : `(${BASE_PARAM_PATTERN})`; + keys.push(token.value); + scores.push(MatchScore.param); } - pattern += paramRegexp ? `(?:${paramRegexp})` : `(${BASE_PARAM_PATTERN})`; - keys.push(token.value); - scores.push(MatchScore.param); break; case TokenType.WildCard: keys.push(token.value); @@ -167,13 +171,13 @@ export function createPathParser

(pathname: string, option: ParserOp return null; } const matchedPath = reMatch[0]; - let params: Params

= {}; - let parseScore: number[] = Array.from(scores); + const params: Params

= {}; + const parseScore: number[] = Array.from(scores); for (let i = 1; i < reMatch.length; i++) { - let param = reMatch[i]; - let key = keys[i - 1]; + const param = reMatch[i]; + const key = keys[i - 1]; if (key === '*' && param) { - let value = param.split('/'); + const value = param.split('/'); if (!Array.isArray(params['*'])) { params['*'] = value; } else { @@ -212,11 +216,13 @@ export function createPathParser

(pathname: string, option: ParserOp path += params[token.value]; break; case TokenType.WildCard: - let wildCard = params['*']; - if (wildCard instanceof Array) { - path += wildCard.join('/'); - } else { - path += wildCard; + { + const wildCard = params['*']; + if (wildCard instanceof Array) { + path += wildCard.join('/'); + } else { + path += wildCard; + } } break; case TokenType.Delimiter: @@ -250,7 +256,7 @@ export function matchPath

( const patterns = Array.isArray(pattern) ? [...pattern] : [pattern]; const matchedResults: Matched

[] = []; for (const item of patterns) { - const parser = createPathParser(item, option); + const parser = createPathParser

(item, option); const matched = parser.parse(pathname); if (matched) { matchedResults.push(matched); diff --git a/packages/inula-router/src/router/matcher/types.ts b/packages/inula-router/src/router/matcher/types.ts index badd0a44..03ad1871 100644 --- a/packages/inula-router/src/router/matcher/types.ts +++ b/packages/inula-router/src/router/matcher/types.ts @@ -56,7 +56,7 @@ type ParseParam = Param extends `:${infer R}` ? { [K in R]: string; } - : {}; + : Record; type MergeParams, OtherParam extends Record> = { readonly [Key in keyof OneParam | keyof OtherParam]?: string; diff --git a/packages/inula/src/inulax/proxy/handlers/CollectionProxyHandler.ts b/packages/inula/src/inulax/proxy/handlers/CollectionProxyHandler.ts index c0f35926..7a913d34 100644 --- a/packages/inula/src/inulax/proxy/handlers/CollectionProxyHandler.ts +++ b/packages/inula/src/inulax/proxy/handlers/CollectionProxyHandler.ts @@ -20,10 +20,10 @@ import { createWeakMapProxy } from './WeakMapProxy'; import { createMapProxy } from './MapProxy'; export function createCollectionProxy( - rawObj: Object, + rawObj: Record, listener: { current: (...args) => any }, hookObserver = true -): Object { +): ProxyHandler> { if (isWeakSet(rawObj)) { return createWeakSetProxy(rawObj, listener, hookObserver); } diff --git a/packages/inula/src/inulax/store/StoreHandler.ts b/packages/inula/src/inulax/store/StoreHandler.ts index ef0d37a7..ce355d32 100644 --- a/packages/inula/src/inulax/store/StoreHandler.ts +++ b/packages/inula/src/inulax/store/StoreHandler.ts @@ -311,7 +311,7 @@ export function createStore, A extends UserActions } // 函数组件中使用的hook -export function useStore, C extends UserComputedValues>( +export function useStore, A extends UserActions, C extends UserComputedValues>( id: string ): StoreObj { const storeObj = storeMap.get(id); diff --git a/packages/inula/src/inulax/types.ts b/packages/inula/src/inulax/types.ts index 3dfb0a66..2814218c 100644 --- a/packages/inula/src/inulax/types.ts +++ b/packages/inula/src/inulax/types.ts @@ -31,7 +31,7 @@ export interface IObserver { clearByVNode: (vNode: any) => void; } -export type StoreConfig, C extends UserComputedValues> = { +export type StoreConfig, A extends UserActions, C extends UserComputedValues> = { id?: string; state?: S; actions?: A; @@ -41,22 +41,22 @@ export type StoreConfig, C extends Us }; }; -export type UserActions = { +export type UserActions> = { [K: string]: ActionFunction; }; -export type ActionFunction = (this: StoreObj, state: S, ...args: any[]) => any; +export type ActionFunction> = (this: StoreObj, state: S, ...args: any[]) => any; -export type StoreActions> = { +export type StoreActions, A extends UserActions> = { [K in keyof A]: Action; }; -type Action, S extends object> = ( +type Action, S extends Record> = ( this: StoreObj, ...args: RemoveFirstFromTuple> ) => ReturnType; -export type StoreObj, C extends UserComputedValues> = { +export type StoreObj, A extends UserActions, C extends UserComputedValues> = { $s: S; $a: StoreActions; $c: UserComputedValues; @@ -66,7 +66,7 @@ export type StoreObj, C extends UserC $unsubscribe: (listener: (mutation) => void) => void; } & { [K in keyof S]: S[K] } & { [K in keyof A]: Action } & { [K in keyof C]: ReturnType }; -export type PlannedAction> = { +export type PlannedAction, F extends ActionFunction> = { action: string; payload: any[]; resolve: ReturnType; @@ -78,21 +78,21 @@ type RemoveFirstFromTuple = T['length'] extends 0 ? I : []; -export type UserComputedValues = { +export type UserComputedValues> = { [K: string]: ComputedFunction; }; -type ComputedFunction = (state: S) => any; +type ComputedFunction> = (state: S) => any; -export type AsyncAction, S extends object> = ( +export type AsyncAction, S extends Record> = ( this: StoreObj, ...args: RemoveFirstFromTuple> ) => Promise>; -export type QueuedStoreActions> = { +export type QueuedStoreActions, A extends UserActions> = { [K in keyof A]: AsyncAction; }; -export type ComputedValues> = { +export type ComputedValues, C extends UserComputedValues> = { [K in keyof C]: ReturnType; }; diff --git a/packages/inula/src/renderer/ErrorHandler.ts b/packages/inula/src/renderer/ErrorHandler.ts index 16895fc3..6d98a099 100644 --- a/packages/inula/src/renderer/ErrorHandler.ts +++ b/packages/inula/src/renderer/ErrorHandler.ts @@ -105,25 +105,27 @@ export function handleRenderThrowError(sourceVNode: VNode, error: any) { return; } case ClassComponent: - const ctor = vNode.type; - const instance = vNode.realNode; - if ( - (vNode.flags & DidCapture) === InitFlag && - (typeof ctor.getDerivedStateFromError === 'function' || - (instance !== null && typeof instance.componentDidCatch === 'function')) - ) { - FlagUtils.markShouldCapture(vNode); + { + const ctor = vNode.type; + const instance = vNode.realNode; + if ( + (vNode.flags & DidCapture) === InitFlag && + (typeof ctor.getDerivedStateFromError === 'function' || + (instance !== null && typeof instance.componentDidCatch === 'function')) + ) { + FlagUtils.markShouldCapture(vNode); - // Class捕捉到异常,触发一次刷新 - const update = createClassErrorUpdate(vNode, error); - pushUpdate(vNode, update); + // Class捕捉到异常,触发一次刷新 + const update = createClassErrorUpdate(vNode, error); + pushUpdate(vNode, update); - launchUpdateFromVNode(vNode); + launchUpdateFromVNode(vNode); - // 有异常处理类,把抛出异常的节点的Interrupted标志去掉,继续走正常的绘制流程 - FlagUtils.removeFlag(sourceVNode, Interrupted); + // 有异常处理类,把抛出异常的节点的Interrupted标志去掉,继续走正常的绘制流程 + FlagUtils.removeFlag(sourceVNode, Interrupted); - return; + return; + } } break; default: diff --git a/packages/inula/src/renderer/UpdateHandler.ts b/packages/inula/src/renderer/UpdateHandler.ts index 3e906082..c3623753 100644 --- a/packages/inula/src/renderer/UpdateHandler.ts +++ b/packages/inula/src/renderer/UpdateHandler.ts @@ -53,19 +53,25 @@ export function pushUpdate(vNode: VNode, update: Update) { // 根据update获取新的state function calcState(vNode: VNode, update: Update, inst: any, oldState: any, props: any): any { switch (update.type) { - case UpdateState.Override: + case UpdateState.Override: { const content = update.content; return typeof content === 'function' ? content.call(inst, oldState, props) : content; + } case UpdateState.ForceUpdate: vNode.isForceUpdate = true; return oldState; - case UpdateState.Error: + case UpdateState.Error: { FlagUtils.removeFlag(vNode, ShouldCapture); FlagUtils.markDidCapture(vNode); - case UpdateState.Update: const updateContent = update.content; const newState = typeof updateContent === 'function' ? updateContent.call(inst, oldState, props) : updateContent; return newState === null || newState === undefined ? oldState : { ...oldState, ...newState }; + } + case UpdateState.Update: { + const updateContent = update.content; + const newState = typeof updateContent === 'function' ? updateContent.call(inst, oldState, props) : updateContent; + return newState === null || newState === undefined ? oldState : { ...oldState, ...newState }; + } default: return oldState; } diff --git a/packages/inula/src/renderer/taskExecutor/RenderQueue.ts b/packages/inula/src/renderer/taskExecutor/RenderQueue.ts index 9467a732..37cfe0a7 100644 --- a/packages/inula/src/renderer/taskExecutor/RenderQueue.ts +++ b/packages/inula/src/renderer/taskExecutor/RenderQueue.ts @@ -40,8 +40,6 @@ function callRenderQueue() { } renderQueue = null; - } catch (error) { - throw error; } finally { isCallingRenderQueue = false; } diff --git a/packages/inula/src/renderer/vnode/VNodeCreator.ts b/packages/inula/src/renderer/vnode/VNodeCreator.ts index 142bac33..6c318cfc 100644 --- a/packages/inula/src/renderer/vnode/VNodeCreator.ts +++ b/packages/inula/src/renderer/vnode/VNodeCreator.ts @@ -60,10 +60,13 @@ function newVirtualNode(tag: VNodeTag, key?: null | string, vNodeProps?: any, re return new VNode(tag, vNodeProps, key as null | string, realNode); } -function isClassComponent(comp: Function) { +type FunctionType = typeof Function; + +function isClassComponent(comp: FunctionType) { // 如果使用 getPrototypeOf 方法获取构造函数,不能兼容业务组组件继承组件的使用方式,会误认为是函数组件 // 如果使用静态属性,部分函数高阶组件会将类组件的静态属性复制到自身,导致误判为类组件 // 既然已经兼容使用了该标识符,那么继续使用 + // @ts-ignore return comp.prototype?.isReactComponent === true; } @@ -74,7 +77,7 @@ export function getLazyVNodeTag(lazyComp: any): string { } else if (lazyComp !== undefined && lazyComp !== null && typeLazyMap[lazyComp.vtype]) { return typeLazyMap[lazyComp.vtype]; } - throw Error("Inula can't resolve the content of lazy"); + throw Error('Inula can\'t resolve the content of lazy'); } // 创建processing