【问题标题】:read folder tree and convert the tree into an object读取文件夹树并将树转换为对象
【发布时间】:2019-07-08 20:47:17
【问题描述】:

我有以下文件夹结构:

+---controllers
|   |   index.js
|   |   
|   +---api
|   |       index.js
|   |       test.js
|   |       
|   \---routes
|       |   index.js
|       |   
|       \---partials
|           |   index.js
|           |   
|           +---bugs
|           +---compatibility
|           +---documentation
|           |       amd.js
|           |       api.js
|           |       jquery.js
|           |       options.js
|           |       usage.js
|           |       
|           \---installation

我正在尝试从树中创建一个如下所示的对象:

{
    api: {
        index: require("index.js"),
        test: require("test.js")
    },
    routes: {
        index: require("index.js"),
        partials: {
            index: require("index.js"),
            bugs: {},
            compatibility: {},
            documentation: {
                amd: require("amd.js"),
                api: require("api.js"),
                jquery: require("jquery.js"),
                options: require("options.js"),
                usage: require("usage.js")
            },
            installation: {}
        }
    }
}

我只是想不出这样做的逻辑,我只设法用以下代码获得了一个树数组:

/**
 * Controllers
 */

var path = require("path"),
    util = require("util"),
    fs = require("fs"),
    wrench = require("wrench");

var controllers = {},
    tree = wrench.readdirSyncRecursive(path.resolve(__dirname, "./")).filter(function (value) {
        return value !== "index.js";
    });


var key,
    i = tree.length - 1;

while (i >= 0) {

    key = tree[i];

    console.log(fs.lstatSync(path.resolve(__dirname, key)).isDirectory(), key.split(path.sep));

    i--;
}

module.exports = controllers;

我不太确定在开始循环文件夹树后应该如何创建对象,但我想只有在我有一些递归函数的情况下才能做到这一点?

编辑

我尝试这样做的原因是因为我试图为我的快速应用程序提供某种动态路由。

在我的快速申请中,我会有类似的东西:

application.get("/api/index", controllers.api.index);
application.get("/api/test", controllers.api.test);
application.get("/", controllers.routes.index);
application.get("/partials/", controllers.routes.partials.index);
application.get("/partials/documentation/amd", controllers.routes.partials.documentation.amd);

...

这些文件中的每一个都会导出类似于以下内容的内容:

exports.index = function (request, response) {
    return response.render("index");
};

取决于文件的位置,可能还有更多逻辑(以防有模型需要加载)。

所以可能有比我正在尝试的更好的管理动态路线的方法,如果是这样,我愿意接受建议。

【问题讨论】:

    标签: node.js recursion fs


    【解决方案1】:

    我为你的情况想出了一个递归文件遍历器。

    var fs = require('fs');
    var filetree = {};
    
    var walkDirectory = function(path, obj) {
      var dir = fs.readdirSync(path);
      for (var i = 0; i < dir.length; i++) {
        var name = dir[i];
        var target = path + '/' + name;
    
        var stats = fs.statSync(target);
        if (stats.isFile()) {
          if (name.slice(-3) === '.js') {
            obj[name.slice(0, -3)] = require(target);
          }
        } else if (stats.isDirectory()) {
          obj[name] = {};
          walkDirectory(target, obj[name]);
        }
      }
    };
    
    walkDirectory('./controllers', filetree);
    console.log(filetree);
    

    该函数将扫描目录,如果文件是脚本,则将其加载。如果是目录,该函数会将目录引用传递给自己并再次执行相同的操作。

    【讨论】:

    • 刚刚测试过,它工作得很好:) 再做几件事,是否可以排除根index.js 文件?与routesapi 处于同一级别的那个?因为将走的脚本将在该索引文件中。此外,每个文件都使用exports.nameOfFunction 将导出函数返回到require。所以所有的对象都会有类似{ api: { test: { test: function () { ... } } } }的东西我们可以把最后两个对象扁平化为一个,所以它最终会像:{ api: { test: function () { ... } } }
    • 如果您不想要index.js,则将name !== 'index.js' 作为条件添加到if (name.slice(-3) === '.js')。此外,对象应该已经像这样被展平,因为函数应该分配给module.exports,而不仅仅是exports
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多