【问题标题】:How to recursively export all from folders in node js project?如何递归地从节点 js 项目中的文件夹中导出所有内容?
【发布时间】:2022-06-21 03:16:38
【问题描述】:

在我的 React JS 项目中,我配置了一个 jsconfig.json,这样我就可以递归地导出嵌套目录并从基本目录导入特定的导出,如下所示:

jsconfig.json:

{
  "compilerOptions": {
    "jsx": "react",
    "baseUrl": "src"
  }
}

项目文件夹结构:

react-app
  src
    common
    index.js
      services
        ServiceA.js
        ServiceB.js
        index.js
      components
        ComponentA.jsx
        index.js
    pages
      pageA
        PageA.jsx
        index.js
    App.jsx
    index.js
    

现在在每个index.js 中,我将从每个文件/文件夹中导出所有内容。所以例如在common/services/index.js:

export * from 'common/services/ServiceA.js';
export * from 'common/services/ServiceB.js';

common/index.js:

export * from 'common/services';
export * from 'common/components';

现在,如果我需要从 ServiceA.js 导出的 PageA.jsx 文件中的 ServiceA,我可以按如下方式导入它:

// PageA.jsx
import {
  ServiceA
} from 'common';
// ServiceA.js
export class ServiceA {
  doStuff () {
    // do stuff
  }
}

如何设置我的 NodeJS 服务器项目以允许类似的导出和导入?

我想这样做是为了 FE 和 BE 之间的一致性,这样我就可以轻松地将任何 FE 代码移植到我的 BE 项目中,而无需对导出和导入进行任何重大更改。

编辑:我设法使用我授予赏金的 Besworks 的答案让它工作,但是 VS Code Intellisense 不会从导入语句导航到导出定义,直到我添加了一个项目根目录中的jsconfig.json

{
    "compilerOptions": {
        "baseUrl": "./src",
        "paths": {
            "#common" : ["./common/index.js"]
        }
    }
}

【问题讨论】:

    标签: javascript node.js reactjs


    【解决方案1】:

    您可以在您的package.jsonmap exports

    {
      "name": "@your-namespace/your-package",
      ...
      "exports": {
        ".": "./index.js",
        "./common": "./common/index.js"
      }
    }
    

    然后你可以按名称引用导出:

    import { YourClass } from '@your-namespace/your-package';
    import { AnotherClass } from '@your-namespace/your-package/common';
    

    或者,如果您的子模块只需要从您的包中访问,您可以映射imports 而不是exports,这不需要您的包名称,但必须以# 字符开头。您也不需要明确指定每个子模块,您可以使用通配符替换文件夹中的所有内容:

    {
      "name": "your-package",
      ...
      "imports": {
        "#common": "./common/index.js",
        "#common/services": "./common/services/index.js",
        "#common/services/*": "./common/services/*.js",
        "#shortcut": "./deeply/nested/path/to/module.js"
      }
    }
    

    并使用它们:

    import { YourClass } from '#common';
    import * from '#common/services';
    import { AnotherClass } from '#common/services/ServiceA';
    import something from '#shortcut';
    

    在上面的示例中,#common 将是对 ./common/index.js 的引用,#common/services/ServiceA 将指向 ./common/services/ServiceA.js

    【讨论】:

    • 欣赏答案,但这是唯一的方法,如果我有多个级别的嵌套文件夹,例如/services in common 我还必须将 ./common/services/index.js 添加到导出中,对于任何其他文件夹也是如此,我还必须在所有导入前添加 @{namespace}。难道不能像我在 ReactJS 项目中那样使用导出和导入吗?
    • 我用有关映射imports 而不是exports 的信息更新了我的答案,这可能更接近您正在寻找的信息。
    • 谢谢,我试试看,想必我得把类型改成模块才能使用导入和导出
    • 另外,我不想明确地从嵌套文件夹(例如 ./common/services)导入,而只是从 ./common 导入,它递归地从所有嵌套文件夹/文件导出,正如我在我的问题。
    • 所以只需将"#common/*": "./common/*/index.js" 添加到imports。然后您可以访问 ./common/ 下的任何路径,例如 #common/deeply/nested/module,它将指向 ./common/deeply/nested/module/index.js
    【解决方案2】:

    你不应该导出所有的包。

    nodejs 模块/包 import/require 负责所有依赖项和模块缓存。

    非常类似于 - https://www.youtube.com/watch?v=-5wpm-gesOY ;)

    【讨论】:

    • 我没有注意到我的 ReactJS 项目中有任何问题,即在每个文件夹中都有一个 index.js,从所有同级文件/文件夹中导出所有文件。
    • @MShakeG,好的,现在尝试将其打包到生产套件中,并在您按照自己的方式或正确方式进行操作时比较最终尺寸的差异。
    • @MShakeG - 来自 python 的禅宗(但它适用于任何地方) - “显式优于隐式。” (见,peps.python.org/pep-0020
    • 嗯,我已经开发了很多大型生产 React 应用程序,这些应用程序管理导出和导入,正如我所描述的那样,没有明显的膨胀。
    • @MShakeG,伙计,做任何你想做的事,只要记住这些导入/要求机制的存在是有原因的,我敢打赌他们比你更快更好地完成任务,没有冒犯.
    【解决方案3】:

    如果您的节点项目在package.json 中使用"type": "module",则文件结构完全相同。但是,从 ES 模块中的索引文件导入仍然是一个实验标志:

    https://nodejs.org/api/esm.html#customizing-esm-specifier-resolution-algorithm

    所以你必须使用例如:

    node --experimental-specifier-resolution=node src/index.js
    

    $ tree src/
    src/
    ├── common
    │   ├── index.js
    │   ├── ServiceA.js
    │   └── ServiceB.js
    ├── index.js
    └── other
        ├── index.js
        ├── OtherA.js
        └── OtherB.js
    

    src/index.js

    import { serviceA, serviceB } from './common';
    import { otherA, otherB } from './other';
    
    serviceA();
    serviceB();
    otherA();
    otherB();
    

    src/common/index.js

    export * from './ServiceA';
    export * from './ServiceB';
    

    `src/common/ServiceA.js'

    export const serviceA = () => console.log('***** ServiceA');
    

    【讨论】:

    • 请注意,您仍然需要模块之间的相对路径。在您的 react 项目中,babel 和/或 webpack 将您的所有文件都放入(概念上)一个大文件中,因此磁盘上的路径之间的关系被完全消除了。这与 node 根本不同,因为文件结构是在生产服务器上维护的。如果您愿意,您也可以将 webpack 用于节点项目,但我个人不会,如果唯一的原因是避免使用一些 ../..
    猜你喜欢
    • 2013-10-11
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    • 2011-09-15
    • 1970-01-01
    • 2022-01-23
    相关资源
    最近更新 更多