Enforcing the Arrow of Dependency

Brett Uglow
2 min readJun 18, 2020

Back at YOW Conference in 2018, I had the pleasure of listening to Neal Ford from ThoughtWorks, talking about Evolutionary Architecture. In a nutshell, this concept is about how to build software which can change over time, just as requirements and environments change over time.

One of the sub-concepts was the idea of building “fitness functions” into systems, which could validate that certain architectural-features were being adhered to. For example, you may want to ensure that the system has a response time under 3 seconds. You could build a fitness function to verify this by using monitoring software, alerts and a dashboard to view the response times over a period of time.

In Neal’s talk, he gave an example of a Java library which could be used to address incorrect coupling between modules. This is a common problem in software development, and I had been searching for an equivalent in the JavaScript eco-system. As it turns out, there is a way to detect and enforce certain coupling patterns in JavaScript — eslint-plugin-import!

Zones

eslint-plugin-import has a rule called “import/no-restricted-paths”, which does exactly what I want. (And it’s been there since 2016 🤦‍♂).

Let’s say you have a folder structure like this:

my-project
├── not-shared
│ └── foo.js
│ └── baz.js
└── shared
└── api.js
└── utils.js

…and you want to make sure that the code in shared does not depend on any code in not-shared . You could implement this rule in your eslint config file:

{
rules: {
'import/no-restricted-paths': [
'error',
{ zones: [{ target: './shared', from: './not-shared' }]
}]
}
}

This zones entry says, “when linting a file inside ./shared, if the file imports a file from ./not-shared , that’s an error”.

Enjoy the time savings!

If you are a tech lead on a web/JavaScript project, this can help steer your team into making better decisions when organising and writing their code. By encoding the dependency-rules this way, you can avoid a lot of unnecessary refactoring. Eslint is also pretty easy to setup and use (if you aren’t already using it).

Enjoy!

--

--

Brett Uglow

Life = Faith + Family + Others + Work + Fun, Work = Software engineering + UX + teamwork + learning, Fun = travelling + hiking + games + …