From baa53b2bfe53d7a73237d47bd5887f104a2ee5c7 Mon Sep 17 00:00:00 2001 From: elrrrrrrr Date: Sun, 19 May 2024 11:02:05 +0800 Subject: [PATCH] feat: lazy load sub dir --- package.json | 5 +++++ src/components/FileTree/index.tsx | 21 +++++++++++++++++++-- src/hooks/useFile.ts | 24 ++++++++++++++++-------- src/slugs/files/index.tsx | 14 +++++++++++--- 4 files changed, 51 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 04b9dc9..b3d45ef 100644 --- a/package.json +++ b/package.json @@ -45,5 +45,10 @@ "prettier": "^3.0.3", "eslint": "^8.44.0", "typescript": "^5.3.3" + }, + "overrides": { + "npm-package-arg": { + "validate-npm-package-name": "5.0.0" + } } } diff --git a/src/components/FileTree/index.tsx b/src/components/FileTree/index.tsx index 26b33e9..c72d085 100644 --- a/src/components/FileTree/index.tsx +++ b/src/components/FileTree/index.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { getIcon } from './icon'; -import type { Directory, File } from '@/hooks/useFile'; +import { useDirs, type Directory, type File } from '@/hooks/useFile'; import { createStyles } from 'antd-style'; const useStyles = createStyles(({ token, css }) => { @@ -15,6 +15,8 @@ interface FileTreeProps { rootDir: Directory; // 根目录 selectedFile: File | undefined; // 当前选中文件 onSelect: (file: File) => void; // 更改选中时触发事件 + pkgName: string; + spec: string; } export const FileTree = (props: FileTreeProps) => { @@ -25,6 +27,8 @@ interface SubTreeProps { directory: Directory; // 根目录 selectedFile: File | undefined; // 当前选中文件 onSelect: (file: File) => void; // 更改选中时触发事件 + pkgName: string; + spec: string; } const SubTree = (props: SubTreeProps) => { @@ -39,6 +43,8 @@ const SubTree = (props: SubTreeProps) => { directory={item as Directory} selectedFile={props.selectedFile} onSelect={props.onSelect} + pkgName={props.pkgName} + spec={props.spec} /> ) : ( void; // 点击事件 + pkgName: string; + spec: string; }) => { let defaultOpen = selectedFile?.path.includes(directory.path); const [open, setOpen] = useState(defaultOpen); + const { data: res } = useDirs({ fullname: pkgName, spec }, directory.path, !open); return ( <> setOpen(!open)} /> {open ? ( - + ) : null} ); diff --git a/src/hooks/useFile.ts b/src/hooks/useFile.ts index 851998b..eef82ad 100644 --- a/src/hooks/useFile.ts +++ b/src/hooks/useFile.ts @@ -40,14 +40,22 @@ function sortFiles(files: (File | Directory)[]) { }); } -export const useDirs = (info: PkgInfo) => { - return useSwr(`dirs: ${info.fullname}_${info.spec}`, async () => { - return fetch(`${REGISTRY}/${info.fullname}/${info.spec}/files?meta`) - .then((res) => res.json()) - .then((res) => { - sortFiles(res.files); - return Promise.resolve(res); - }); +export const useDirs = (info: PkgInfo, path = '', ignore = false) => { + // https://github.com/cnpm/cnpmcore/issues/680 + // 请求文件路径存在性能问题,手动关闭 revalidate ,拆分多次请求 + return useSwr(ignore ? null : `dirs: ${info.fullname}_${info.spec}_${path}`, { + revalidateOnFocus: false, + revalidateOnReconnect: false, + // 本地缓存优先 + refreshInterval: 0, + fetcher: async () => { + return fetch(`${REGISTRY}/${info.fullname}/${info.spec}/files${path}/?meta`) + .then((res) => res.json()) + .then((res) => { + sortFiles(res.files); + return Promise.resolve(res); + }); + } }); }; diff --git a/src/slugs/files/index.tsx b/src/slugs/files/index.tsx index 4395874..c042d2a 100644 --- a/src/slugs/files/index.tsx +++ b/src/slugs/files/index.tsx @@ -14,9 +14,11 @@ const Viewer = ({ manifest, version }: PageProps) => { `/package/${manifest.name}/files/*?version=${version || 'latest'}`, ); + const spec = version || 'latest'; + const { data: rootDir, isLoading } = useDirs({ fullname: manifest.name, - spec: version || 'latest', + spec, }); let selectedFile = _selectedFile || { path: `/${path || 'package.json'}`, type: 'file' }; @@ -42,9 +44,15 @@ const Viewer = ({ manifest, version }: PageProps) => { return (
- + - +
); };