UNPKG

@cl1107/keep-alive

Version:

fork from @alitajs/keep-alive,support pnpm

280 lines (267 loc) 8.52 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { default: () => src_default }); module.exports = __toCommonJS(src_exports); var import_path = require("path"); // src/utils/getLayoutContent.tsx var getLayoutContent_default = (keepalive, path) => `import React from 'react'; const KeepAliveLayout = (props:any) => { return React.createElement(require('${path}').default, { keepalive:[${keepalive}], ...props }) } export {KeepAliveLayout} `; // src/utils/getKeepAliveLayout.tsx var getKeepAliveLayout_default = (absTmpPath) => ` import React from 'react'; import { getRoutes } from '${absTmpPath}/core/routes'; import { setLayoutInstance } from './KeepAliveModel'; import pathToRegexp from 'path-to-regexp'; import { matchRoutes } from 'react-router-config'; import * as app from '@/app'; const runTimeConfig = app; const isKeepPath = (aliveList:any[],path:string)=>{ let isKeep = false; aliveList.map(item=>{ if(item === path){ isKeep = true; } if(item instanceof RegExp && item.test(path)){ isKeep = true; } if(typeof item === 'string' && item.toLowerCase() === path){ isKeep = true; } }) return isKeep; } const getKeepAliveViewMap = (routeList:any[],aliveList:any[])=>{ let keepAliveMap = {}; function find(routess: any[], list:any[]) { if(!routess|| !list ){ return routess; } return routess.map(element => { if (!Array.isArray(element.routes)&&isKeepPath(list,element.path?element.path.toLowerCase():'')) { element.recreateTimes = 0; keepAliveMap[element.path.toLowerCase()] = element; }else{ element.routes = find(element.routes,aliveList); } return element; }); } find(routeList,aliveList) return keepAliveMap; } const getView = ( pathname: string, keepAliveViewMap: { [key: string]: any }, ) => { let View; for (const key in keepAliveViewMap) { if (pathToRegexp(key).test(pathname)) { View = keepAliveViewMap[key] break; } } return View; }; interface PageProps { location: { pathname: string; }; } export default class BasicLayout extends React.PureComponent<PageProps> { constructor(props: any) { super(props); this.keepAliveViewMap = getKeepAliveViewMap(getRoutes(), props.keepalive); const patchKeepAlive = async (func: (config: anyd[]) => any[]) => { const keepalive = await func(props.keepalive); this.keepAliveViewMap = getKeepAliveViewMap(getRoutes(), keepalive); } this.patchKeepAlive = patchKeepAlive; this.state = { keepaliveConfig: props.keepalive, keepAliveViewMap: this.keepAliveViewMap }; // TODO: \u4E34\u65F6\u652F\u6301\u52A8\u6001\u7684 keepalive\uFF0C\u5C06 map \u653E\u5230 state \u4E2D\uFF0C\u975E\u5E38\u4E0D\u53CB\u597D this.init(); } async init() { if (runTimeConfig?.getKeepAlive) { try { const keepaliverumtime = await runTimeConfig?.getKeepAlive(this.state.keepaliveConfig); this.keepAliveViewMap = getKeepAliveViewMap(getRoutes(), keepaliverumtime); this.setState({ keepaliveConfig: keepaliverumtime, keepAliveViewMap: this.keepAliveViewMap }) } catch (error) { console.error(error); } } } componentDidMount() { setLayoutInstance(this); } keepAliveViewMap = {}; alivePathnames: string[] = []; render() { const { location: { pathname }, } = this.props; const { keepAliveViewMap } = this.state; const showKeepAlive = !!getView(pathname, keepAliveViewMap); if (showKeepAlive) { const index = this.alivePathnames.findIndex( tPathname => tPathname === pathname.toLowerCase(), ); if (index === -1) { this.alivePathnames.push(pathname.toLowerCase()); } } return ( <> {this.alivePathnames.map(curPathname => { const currentView = getView(curPathname, this.keepAliveViewMap); const { component: View, recreateTimes } = currentView; const matchRoute = matchRoutes([currentView], curPathname)[0]; const pageProps: any = { ...this.props,...matchRoute }; return View ? ( <div id={\`BasicLayout-\${curPathname}\`} key={ curPathname + recreateTimes } style={{ height: '100%', width: '100%', position: 'relative', overflow: 'hidden auto' }} className="rumtime-keep-alive-layout" hidden={curPathname !== pathname.toLowerCase()} > <View {...pageProps} /> </div> ) : null; })} <div hidden={showKeepAlive} style={{ height: '100%', width: '100%', position: 'relative', overflow: 'hidden auto' }} className="rumtime-keep-alive-layout-no"> {!showKeepAlive && this.props.children} </div> </> ) } } `; // src/utils/getModelContent.tsx var getModelContent_default = () => ` // @ts-nocheck import pathToRegexp from 'path-to-regexp'; interface LayoutInstanceProps { alivePathnames: string[], keepAliveViewMap: {} } let LayoutInstance: LayoutInstanceProps; function dropByCacheKey(pathname: string) { if (LayoutInstance) { const { alivePathnames, keepAliveViewMap } = LayoutInstance; const index = alivePathnames.findIndex(item => item === pathname?.toLowerCase()); if (index !== -1) { alivePathnames.splice(index, 1); // \u7528\u6765\u5F53\u4F5Ckey\uFF0C\u53EA\u6709key\u53D1\u751F\u53D8\u5316\u624D\u4F1Aremout\u7EC4\u4EF6 for (const key in keepAliveViewMap) { if (pathToRegexp(key).test(pathname?.toLowerCase())) { keepAliveViewMap[key].recreateTimes += 1; break; } } } } } function patchKeepAlive(fn: (config: any[]) => any[]) { if (LayoutInstance) { LayoutInstance.patchKeepAlive(fn); } } const setLayoutInstance = (value: any) => { LayoutInstance = value } const getLayoutInstance = () => LayoutInstance; export { setLayoutInstance, getLayoutInstance, dropByCacheKey, patchKeepAlive } `; // src/index.ts var DIR_NAME = "keep-alive"; var MODEL_NAME = "KeepAlive"; var RELATIVE_MODEL = (0, import_path.join)(DIR_NAME, MODEL_NAME); var src_default = (api) => { if (!api.userConfig.keepalive) return; api.describe({ key: "keepalive", config: { default: {}, schema(joi) { return joi.array(); }, onChange: api.ConfigChangeType.regenerateTmpFiles } }); const configStringify = (config) => { return config.map((item) => { if (item instanceof RegExp) { return item; } return `'${item}'`; }); }; api.addRuntimePluginKey(() => "getKeepAlive"); api.onGenerateFiles(() => { api.writeTmpFile({ path: (0, import_path.join)(DIR_NAME, "KeepAliveLayout.tsx"), content: getKeepAliveLayout_default(api.paths.absTmpPath || "") }); api.writeTmpFile({ path: (0, import_path.join)(DIR_NAME, "KeepAlive.tsx"), content: getLayoutContent_default(configStringify(api.userConfig.keepalive), "./KeepAliveLayout") }); api.writeTmpFile({ path: (0, import_path.join)(DIR_NAME, "KeepAliveModel.tsx"), content: getModelContent_default() }); }); api.addUmiExports(() => [ { specifiers: ["KeepAliveLayout"], source: `../${RELATIVE_MODEL}` }, { specifiers: [ "setLayoutInstance", "getLayoutInstance", "dropByCacheKey", "patchKeepAlive" ], source: `../${(0, import_path.join)(DIR_NAME, "KeepAliveModel")}` } ]); }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = {});