简体   繁体   中英

Disallow barrel file imports within the same library in Nrwl Nx

Suppose we have an app and a library in Nrwl Nx .

/apps
  /myApp

/libs
  /myLib
    /components
       /my.component.ts
       /other.component.ts
    /index.ts

I have already set tags in nx.json and nx-enforce-module-boundaries rule to block importing the app inside the lib. It works and this part is fine.

Another thing I wanted to do is enforcing using barrel files within libraries. So I created a path in tsconfig.ts

"paths": {
   "@myNs/my-lib": ["libs/myLib/index.ts"]
}

I faced the problem. Suppose we have something exported from index.ts .

// index.ts
export { MyComponent } from './components/my.component';

Now if we use some autoimporting IDE feature (eg from WebStorm or VS Code ). They will be importing MyComponent using the path @myNs/my-lib - and this is expected, because I have just configured it like so.

A real problem appears when I want to autoimport something inside myLib (these imports should be relative, not @myNs/my-lib ) - according to logic and this article ( [Interesting article here] ):

Never let a lib import from its own Barrel file

The TypeScript modules within a particular lib should not care what functionality that lib exposes, so it shouldn't use its own barrel file at any point.

If a module imports something from its own barrel file, it almost always results in circular reference errors. Therefore, imports from inside of the module should use relative path imports.

So I found a workaround to block TS path-like imports inside lib. I have added a rule inside libs/myLib/tslint.json :

"rules": {
   "import-blacklist": [true, "@myNs/my-lib"]
}

Anyway, it doesn't fix autoimporting feature, just disallows to use wrong imports inside the lib.

Another problem is there are still wrong imports allowed. Suppose OtherComponent wants to import MyComponent Then there are three possibilities:

import { MyComponent } from './my.component'; // the correct way
import { MyComponent } from '.'; // not the best, but also the correct way
import { MyComponent } from '..'; // using barrel file - not correct (look at the citation above), but still successfuly validated by TSLint

Questions:

  1. How to disallow barrel file imports inside the same lib?
  2. How to configure IDEs to have relative paths inside lib and TypeScript paths outside ( @myNs/my-lib )?

Here's the setting in IntelliJ. I am seeing this work correctly in v2020.1.

在 IntelliJ 下的 Editor > Code Style > Typescript 中设置名为“使用来自 tsconfig.json 的路径映射”设置为“仅在指定路径之外的文件中”

I like the rule @Nickson created however, and think it's a good idea to add to prevent errors!

No one answered, so I decided to create a simple TSLint rule to handle this case: import-blacklist-extended

Rule works fine in Nrwl monorepo, but it could be optimized and some mechanisms could be resolved better. Feel free to create issues and PRs on Github if any changes are needed for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM