Let's imagine a list of posts and a post form.
The list has a person filter to show posts of that person only. And a new post has a person field that can be specified as the author of that post.
So, here could be the pseudo-code for the list:
import { Person } from "../person/filter.jsx"
return <List
filters={<>
<Person />
</>}
/>
And the pseudo-code for the form:
import { Person } from "../person/field.jsx"
return <Form
inputs={<>
<Person />
</>}
/>
Now if we move the person's filter and field to its own module, and try to have a barrel file, we encounter a problem.
Two named exports with the same name can not exist in a file
So, our index.jsx
file would look like:
import PersonFilter from "../person/filter.jsx"
import PersonField from "../person/field.jsx"
export { PersonFilter }
export { PersonField }
And our pseudo-codes would become:
import { PersonFilter } from "persons"
return <List
filters={<>
<PersonFilter />
</>}
/>
And
import { PersonField } from "persons"
return <Form
inputs={<>
<PersonField />
</>}
/>
While this is still readable, it's less semantically correct. There is no need to suffix the Person component with the word Filter
when we are dealing with a list. Also, there is no need to suffix it with the word Field
when we are inside a form. A human can understand the context.
I recommend that we add a capability to make imports context-aware. When I say import { Person } from "persons"
and I am inside a list file, this should import the filter, and not the field.
How should it know the context? We can have many ways. One that comes to my mind is via configuration. In a config file, we can define contexts and import rules. This could be a pseudo-code in a pseudo-config file:
{
"contexts": [
{
"name": "list",
"files": ".*list.jsx",
"rules": {
"postFixImportIfNotFound": "Filter"
}
},
{
"name": "form",
"files": ".*form.jsx",
"rules": {
"postFixImportIfNotFound": "Field"
}
}
]
}
For large systems, this helps code semantics a lot. An enterprise software easily has more than 500 lists and forms. This improvement can help code become more readable. The aforementioned pseudo-code would become:
import { Person } from "persons"
return <List
filters={<>
<Person />
</>}
/>
And
import { Person } from "persons"
return <Form
inputs={<>
<Person />
</>}
/>