Context-aware imports

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 />
    </>}
/>

Hi @Nefcanto!

The core JavaScript language specification does not actually prescribe how any import is resolved. That is left to the "host" to decide what the string represents. The only thing that the specification does say is that if a file imports the same string more than once then they must all resolve to the same module.

What you're describing sounds closer to things like GitHub - WICG/import-maps: How to control the behavior of JavaScript imports

1 Like

@aclaymore thank you for the explanation. So I should ask for this feature from Node.js for example or from library authors or from some organizations like the link you sent. Am I right? In case of React for example, should I talk to Node.js team, or React team?

In Node it's already possible to augment module resolution: Modules: node:module API | Node.js v23.1.0 Documentation

For the web, this can be emulated by using a bundler such as esbuild, vite, or webpack - these have plugin APIs that also support module resolution customisation.

It might be worth building these so people can try the ideas out and iterate on the design.
For it to be standardised it would likely need collaboration between a many different teams working on different platforms. Again, having a working example can help advertise the project to find people to collaborate with.