javierbrea / eslint-plugin-boundaries

Eslint plugin checking architecture boundaries between elements
MIT License
506 stars 9 forks source link

Templates for captured values in main micromatch patterns #243

Closed brutus-law closed 1 year ago

brutus-law commented 2 years ago

Describe the bug I'm having trouble figuring out what config to setup for the following structure src/ ├── components/ │ ├── AtomA/ │ │ │ ├── AtomA.jsx │ │ │ └── AtomAForm.jsx │ │ │ └── AtomADisplay.jsx │ ├── AtomB/ │ │ │ ├── AtomB.jsx │ │ │ └── AtomBForm.jsx │ │ │ └── AtomBDisplay.jsx

Instead of index.js files, we do entry file is the same name as the folder. Otherwise similar rules apply that boundaries/entry-point seems to follow: AtomA.jsx can import:

It cannot import:

AtomAForm.jsx can only import children under AtomA folder, so only ./AtomADisplay.jsx

Expected behavior I'd like to be able to do what entry-point looks to be doing, except specify that entry file is the folder name, not index.js

I tried doing this but it doesn't seem to do what I'm expecting and I'm sure I'm missing other stuff:

"boundaries/entry-point": [2, {
      "default": "disallow",
      "rules": [
        {
          "target": ["components"],
          allow: "${componentFolder}.jsx"
        }
      ]
    }

settings: {
   "boundaries/elements": [
      {
        "type": "components",
        "pattern": "src/components/*/*.*",
        "mode": "file",
        "capture": ["componentFolder", "filename"]
      },
    ],
}
javierbrea commented 2 years ago

Hi @brutus-law ,

I understand your requirement, and I think that makes sense as well. Unfortunately, It doesn't work because the plugin does not support replacing captured values in the main micromatch pattern. It only replaces captured values in the matcher options for captured values (when expressing the pattern as an array, with a second element containing an object with matchers for the captured values), for example:

{
      // when file is inside an element of type "components"
      "from": ["components"],
      "allow": [
        // allow importing components of the same family
        ["components", { "family": "${family}" }],
      ]
    },

And, note that it replaces values using the values captured in the "from" element, not in the "target" one, which would be the useful data in the case of the "entry-point" rule.

So, I think that it makes sense to replace captured values also in the main micromatch pattern, as you suggested. But, going a step forward, it also makes sense to be able to replace captured values both from "from" and "target" elements in all rules, otherwise it could be confusing.

Then, your rule may look like:

"boundaries/entry-point": [2, {
    "default": "disallow",
    "rules": [
      {
        "target": ["components"],
         allow: "${target.componentFolder}.jsx"
      }
    ]
  }

I will also open another issue for improving the documentation at this respect, and provide more examples about using templates in patterns.

I think that this new feature will be very powerful, and it will improve and make more flexible the plugin configuration. So, thank you very much for your feedback 😃

brutus-law commented 2 years ago

@javierbrea Ya that sounds like what I was hoping to do. Guess I'll watch for this for the change when you get time to add it.

I actually got that vibe of "you can only do based on the from" when I tried multiple rules, hoping one would let me parse based on the target.

So I guess what I'm saying is this might be helpful on more rules than just boundaries/entry-point but if you wanna start there, that'd be good.

Thanks for the explanation~~~