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

zd287kbt  于 2023-05-08  发布在  TypeScript
关注(0)|答案(1)|浏览(192)

我想把模块化引入到我的typescript应用程序中,并构建不同的模块。在模块内部,我想隐藏不应该在模块外部使用的类。我目前为每个类都有一个ts文件,这需要我导出每个类,因此不会隐藏任何东西。我知道每个typescript文件都是一个模块,这意味着我可以将模块的所有类都放在一个文件中,然后导出相关的类。未导出的类将被隐藏,因为它们只能在文件中访问。然而,这将大大降低我的应用程序的可读性和可编辑性,对我来说不值得。
我读了关于桶文件的概念,并做了一些测试自己。下面是我对简化的桶形图案的描述:

文件路径

/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模块化?也许有一种方法可以强制使用桶文件,或者可能以某种方式将目录解释为模块。或者让我知道我是否错过了什么,我的方法没有意义。
先谢谢你了

rsaldnfx

rsaldnfx1#

正如一些评论者所建议的,我开始使用ESLint来处理Typescript。我尝试了eslint模块插件的规则,但它们似乎不能正常工作,所以我现在使用标准规则no-restricted-imports。我把我的项目重组成一个树形结构,就像这样:

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

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

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

不,强制使用模块.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看起来像这样:

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

因此,MyHiddenClass本质上是对其他模块隐藏的。它还可以与Visual Studio Code的ESLint扩展一起工作。它会自动生成导入模式并避免eslint配置禁止的模式。此外,在当前模块中隐藏的类不会在自动完成中显示,因为没有法律的的方法来导入文件。

相关问题