Skip to content

Commit

Permalink
feat: lazy load dirs (#80)
Browse files Browse the repository at this point in the history
> 适配 [ref](cnpm/cnpmcore#680) 接口调整,改为异步加载子文件夹
* 🤖 调整子 `useDirs` 相关逻辑和 `FileTree` 子文件夹渲染逻辑
* 📦 默认不锁直接依赖版本
* 🔐 由于
[validate-npm-package-name](npm/validate-npm-package-name#113)
限制,先锁定版本

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Enhanced `FileTree` component with additional properties for better
directory management.
  
- **Improvements**
- Updated various packages to their latest versions for improved
performance and security.
  - Improved caching and revalidation options in directory fetching.

- **Bug Fixes**
- Fixed issues related to directory fetching by adding new parameters
and updating the fetch URL.
  
- **Chores**
  - Added `@vercel/node` and updated other development dependencies.
  - Added overrides for specific npm packages to ensure compatibility.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
elrrrrrrr authored May 19, 2024
1 parent 4d41519 commit 1404458
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 23 deletions.
25 changes: 15 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,41 @@
"@gravatar/js": "^1.1.1",
"@monaco-editor/loader": "^1.3.3",
"@monaco-editor/react": "^4.4.2",
"@types/react-dom": "18.2.5",
"@vercel/node": "^2.15.5",
"@types/react-dom": "^18.2.5",
"antd": "^5.15.3",
"antd-style": "^3.4.4",
"chart.js": "^4.4.1",
"dayjs": "^1.11.9",
"eslint": "8.44.0",
"eslint-config-next": "13.4.4",
"github-slugger": "^2.0.0",
"giturl": "^2.0.0",
"highlight.js": "^11.8.0",
"lodash": "^4.17.21",
"marked": "^1.1.0",
"next": "13.4.7",
"next": "^13.4.7",
"npm-package-arg": "^11.0.1",
"react": "18.2.0",
"react": "^18.2.0",
"react-chartjs-2": "^5.2.0",
"react-dom": "18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.3.1",
"semver": "^7.5.4",
"swr": "^2.2.0"
},
"repository": "https://github.com/cnpm/cnpmweb.git",
"devDependencies": {
"@vercel/node": "^2.15.5",
"@types/lodash": "^4.14.197",
"@types/node": "20.4.1",
"eslint-config-next": "^13.4.4",
"@types/node": "^20.4.1",
"@types/npm-package-arg": "^6.1.3",
"@types/react": "18.2.14",
"@types/react": "^18.2.14",
"@types/semver": "^7.5.0",
"prettier": "^3.0.3",
"typescript": "5.3.3"
"eslint": "^8.44.0",
"typescript": "^5.3.3"
},
"overrides": {
"npm-package-arg": {
"validate-npm-package-name": "5.0.0"
}
}
}
21 changes: 19 additions & 2 deletions src/components/FileTree/index.tsx
Original file line number Diff line number Diff line change
@@ -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 }) => {
Expand All @@ -15,6 +15,8 @@ interface FileTreeProps {
rootDir: Directory; // 根目录
selectedFile: File | undefined; // 当前选中文件
onSelect: (file: File) => void; // 更改选中时触发事件
pkgName: string;
spec: string;
}

export const FileTree = (props: FileTreeProps) => {
Expand All @@ -25,6 +27,8 @@ interface SubTreeProps {
directory: Directory; // 根目录
selectedFile: File | undefined; // 当前选中文件
onSelect: (file: File) => void; // 更改选中时触发事件
pkgName: string;
spec: string;
}

const SubTree = (props: SubTreeProps) => {
Expand All @@ -39,6 +43,8 @@ const SubTree = (props: SubTreeProps) => {
directory={item as Directory}
selectedFile={props.selectedFile}
onSelect={props.onSelect}
pkgName={props.pkgName}
spec={props.spec}
/>
) : (
<FileDiv
Expand Down Expand Up @@ -91,13 +97,18 @@ const DirDiv = ({
directory,
selectedFile,
onSelect,
pkgName,
spec,
}: {
directory: Directory; // 当前目录
selectedFile: File | undefined; // 选中的文件
onSelect: (file: File) => 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 (
<>
<FileDiv
Expand All @@ -107,7 +118,13 @@ const DirDiv = ({
onClick={() => setOpen(!open)}
/>
{open ? (
<SubTree directory={directory} selectedFile={selectedFile} onSelect={onSelect} />
<SubTree
directory={res || directory}
selectedFile={selectedFile}
onSelect={onSelect}
pkgName={pkgName}
spec={spec}
/>
) : null}
</>
);
Expand Down
24 changes: 16 additions & 8 deletions src/hooks/useFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
}
});
};

Expand Down
14 changes: 11 additions & 3 deletions src/slugs/files/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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' };
Expand All @@ -42,9 +44,15 @@ const Viewer = ({ manifest, version }: PageProps) => {
return (
<div style={{ display: 'flex', marginTop: -16, minHeight: '100%' }}>
<Sidebar>
<FileTree rootDir={rootDir} selectedFile={selectedFile} onSelect={onSelect} />
<FileTree
rootDir={rootDir}
selectedFile={selectedFile}
onSelect={onSelect}
pkgName={manifest.name}
spec={spec}
/>
</Sidebar>
<CodeViewer selectedFile={selectedFile} pkgName={manifest.name} spec={version} />
<CodeViewer selectedFile={selectedFile} pkgName={manifest.name} spec={spec} />
</div>
);
};
Expand Down

0 comments on commit 1404458

Please sign in to comment.