如何在 Typescript 中强制使用桶文件

问题描述 投票:0回答:1

我想将模块化引入我的打字稿应用程序并构建不同的模块。在模块内部,我想隐藏不应在模块外部使用的类。我目前每个类都有一个 ts 文件,这需要我导出每个类,因此不会隐藏任何内容。我知道每个打字稿文件都是一个模块,这意味着我可以将一个模块的所有类放入一个文件中,然后导出相关的类。未导出的类将被隐藏,因为它们只能在文件中访问。然而,这会大大降低我的应用程序的可读性和可编辑性,对我来说不值得。

我阅读了桶文件的概念并自己做了一些测试。这就是我描绘简单桶形图案的方式:

文件路径

/myModule1/
    barrel.ts
    MyHiddenClass.ts
    MyExportedClass.ts
/myModule2/
    MyOtherClass.ts

MyHiddenClass.ts

export class MyHiddenClass {
   // some utilities that are only supposed to be used in myModule1
   // export is still needed, so that files in this module can access this file
}

myExportedClass.ts

import { MyHiddenClass } from "./MyHiddenClass";

export class MyExportedClass {
    // do something with MyHiddenClass
    // use me in myModule2
}

barrel.ts

// only export the classes, that are supposed to be used in other modules
export * from './myExportedClass';

MyOtherClass.ts:

// do not import directly from the files, only use the barrel file
import { MyExportedClass } from '../myModule1/barrel'

export class MyOtherClass {
    // do something with MyExportedClass
}

这很好用,但是,这在另一个模块中也仍然有效:

MyOtherClass.ts:

import { MyExportedClass } from "../myModule1/MyExportedClass";
import { MyHiddenClass } from "../myModule1/myHiddenClass";

export class MyOtherClass {
    // do something with MyExportedClass
    // do something that is not intended with MyHiddenClass
 }

所以可以完全忽略桶文件,直接导入所有文件。事实上,在使用 Visual Studio Code 的自动完成功能时,直接导入优先于桶文件。这使得完全错过桶文件并忽略预期的模块化变得非常容易。我觉得,我可以只在模块中插入一个自述文件,它礼貌地要求只导入预期的类,它会产生同样的效果。

因此,我的问题是,是否有可能将每个类都放在一个单独的 ts 文件中,并且仍然使用 typescript 模块化?也许有一种方法可以强制使用桶文件,或者可能以某种方式将目录解释为模块。或者让我知道我是否遗漏了什么并且我的方法没有意义。

提前致谢

typescript modularity barrel-import
1个回答
0
投票

正如一些评论者所建议的那样,我开始将 ESLint 用于 Typescript。我尝试使用 eslint 模块插件中的规则,但它们似乎无法正常工作,所以我现在使用标准规则 no-restricted-imports。我将我的项目重组为树结构,如下所示:

/src
    /modules
        /myModule1
            module.ts
            /myModule1
                MyHiddenClass.ts
                MyExportedClass.ts
                MyExportedClass2.ts
        /myModule2
            module.ts
            /myModule2
                MyOtherClass.ts

每个模块都有一个模块目录的子目录,包含一个名为 module.ts 的桶文件(文件名无关紧要)和另一个包含类实现的子目录。在 implementations 子目录中,每个文件都包含一个导出类。 module.ts 看起来像这样(显然不包括像 MyHiddenClass 这样的模块内部类):

export { MyExportedClass} from "./myModule1/MyExportedClass.ts";
export { MyExportedClass2} from "./myModule1/MyExportedClass2.ts";

没有强制使用 module.ts 文件的技巧是在 eslint 配置文件中执行此规则:

"rules": {
    "no-restricted-imports": [
        "error", 
        {
            "patterns": [
                "*/modules/*/*/*",
                "../*"
            ]
        }
    ]
}

第一条规则防止从实现子目录导入:

//pattern          * /modules/    *    /    *    /       *
//does not match: src/modules/myModule1/module.ts
//does match:     src/modules/myModule1/myModule1/MyHiddenClass.ts

第二条规则防止模块之间的相对导入,这些模块会回避第一条规则,例如从 MyOtherClass.ts 导入:

import { MyHiddenClass} from "../../myModule1/myModule1/MyHiddenClass.ts";

相反,我的导入看起来像这样:

import { MyExportedClass, MyExportedClass2 } from "src/modules/myModule1/module.ts";

MyHiddenClass 因此基本上对其他模块隐藏。它还适用于 Visual Studio Code 的 ESLint 扩展。它会自动生成导入模式并避免 eslint 配置禁止的模式。此外,当前模块中隐藏的类不会出现在自动完成中,因为没有合法的方式导入文件。

© www.soinside.com 2019 - 2024. All rights reserved.