这个工具主要是为了方便在写文章的时候,展示自己的项目的目录结构,或者在 README 文件中介绍项目使用的,上传文件夹后可以生成目录结构,支持一键复制。

image.png

您可以通过以下链接访问:目录树生成器 - 在线使用open in new window

Next.js

是一个 React 全栈框架,它不仅可以用于构建服务器端渲染(SSR),也支持支持静态渲染。

webkitdirectory

HTMLInputElement.webkitdirectory  是一个反应了 HTML 属性  webkitdirectoryopen in new window  的属性,其指示  <input>open in new window  元素应该让用户选择文件目录而非文件。在选择文件目录后,该目录及其整个内容层次结构将包含在所选项目集内。可以使用  webkitEntries (en-US)open in new window  属性获取选定的文件系统条目。
———————MDN

简而言之 利用这属性,我们可以在浏览器中上传文件夹,并获取到文件的目录结构。

可以看一个简单的栗子 🌰 jcodeopen in new window

这个功能,也有一个兼容问题,具体参考这个:

image.png

有一些老版本的浏览器和安卓端火狐浏览器不支持的无法使用该功能。

数据转换

我们要将原数据转换一下

-   Java/main/main.java
-   Java/main/main.class
-   Java/hello/HelloWorld.class
-   Java/hello/HelloWorld.java
-   Java/OOP/xx.js
-   Java/OOP/Person.class
-   Java/OOP/oop.class
-   Java/OOP/oop.java
1
2
3
4
5
6
7
8

转换为:

{
    "name": "Java",
    "type": "folder",
    "contents": [
        {
            "name": "main",
            "type": "folder",
            "contents": [
                {
                    "name": "main.java",
                    "type": "file"
                },
                {
                    "name": "main.class",
                    "type": "file"
                }
            ]
        },
        {
            "name": "hello",
            "type": "folder",
            "contents": [
                {
                    "name": "HelloWorld.class",
                    "type": "file"
                },
                {
                    "name": "HelloWorld.java",
                    "type": "file"
                }
            ]
        },
        {
            "name": "OOP",
            "type": "folder",
            "contents": [
                {
                    "name": "xx.js",
                    "type": "file"
                },
                {
                    "name": "Person.class",
                    "type": "file"
                },
                {
                    "name": "oop.class",
                    "type": "file"
                },
                {
                    "name": "oop.java",
                    "type": "file"
                }
            ]
        }
    ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

将路径结构转化为对象结构,方便我们的后续逻辑处理,转化方法是:

function convertToDirectoryStructure(fileList) {
  const directory = {
    name: "App",
    type: "folder",
    contents: [],
  };

  for (let i = 0; i < fileList.length; i++) {
    const pathSegments = fileList[i].webkitRelativePath.split("/");
    let currentDirectory = directory;

    for (let j = 0; j < pathSegments.length; j++) {
      const segment = pathSegments[j];
      const isDirectory = j < pathSegments.length - 1;

      let existingEntry = currentDirectory.contents.find((entry) => entry.name === segment);
      if (!existingEntry) {
        existingEntry = { name: segment };
        if (isDirectory) {
          existingEntry.type = "folder";
          existingEntry.contents = [];
        } else {
          existingEntry.type = "file";
        }
        currentDirectory.contents.push(existingEntry);
      }

      currentDirectory = existingEntry;
    }
  }

  return directory.contents[0];
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

最终效果

最后我们再加上一个一键复制的功能,就完成了。

jcodeopen in new window

最后我是将功能优化后部署到了 GitHub Pagas 上,如何将 Next.js 部署到 GitHub Pages,可以看看我的这篇 如何将 Next.js 部署到 Github Pagesopen in new window

最后希望大家多多使用,给个 star,GitHub 地址:dir-treeopen in new window