Prevent imports outside module except through index
Asked Answered
C

2

7

Is there a simple solution (lint rule perhaps?) which can help enforce clean code imports through index files? I'd like to prevent importing code from "cousin" files, except if it is made available through an index file.

Ex:

- app
  + dogs
  | + index.ts  
  | + breeds
  | |  + retriever.ts
  | |  + schnauzer.ts
  | + activities
  |    + playing.ts
  |    + walking.ts
  + cats
    + index.ts
    + breeds
    |  + siamese.ts
    |  + persion.ts
    + activities
       + sleeping.ts
       + hunting.ts  

Importing from the perspective of cats/activities/hunting.ts:

import { sleeping } from './sleeping'       // VALID - inside same folder
import { siamese } from '../breeds/siamese' // VALID - inside cats module
import { playing } from '../../dogs'        // VALID - importing from an index

import { retriever} from '../../dogs/activities/breeds' // INVALID - cousin file outside module possibly not exported from index
Candidate answered 22/10, 2021 at 15:57 Comment(0)
D
5

You can use eslint's import/no-internal-modules rule and configure separate .eslintrc rules per "root" module.

In your dogs folder, create a new .eslintrc file with this contents:

{
  "rules": {
    "import/no-internal-modules": [ "error", {
      "allow": [ "app/dogs/**", "app/*" ],
    } ]
  }
}

This means any js/ts file within the dogs folder (or any sub folder of dogs) may import files from its own package OR any package like /cats

Do the same for your cats and any other "root" module.

De answered 22/10, 2021 at 16:14 Comment(1)
i don't think this works as expected. for me, I can still import from other directories under app. also shouldn't this stop you importing 3rd party npm packages?Intertwine
C
2

The eslint no-restricted-imports rule can be used to provide custom rules for import patterns. This pattern prevents anything 2+ levels up and then 2+ levels down, which prevents cousin imports.

"no-restricted-imports": [
  "warn",
  {
    "patterns": [
      {
        "group": ["**/../../[a-zA-Z]*/[a-zA-Z]*/**"],
        "message": "File not exposed from the module. Consider exporting it from an index"
      }
    ]
  }
]
Candidate answered 22/10, 2021 at 16:58 Comment(1)
where is this created at the root or in the module?Intertwine

© 2022 - 2024 — McMap. All rights reserved.