-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Module resolution #19
Comments
I'm thinking about a (dramatic) rework of
It's top level exports would look like this:
It will of course evolve a bit as eg FunctionDescription becomes a bigger deal. Internally, it caches in-memory, so that nothing is loaded twice. I don't think any of the project-level abstractions should be exposed. A lot of the analysis done here will probably end up being used by the compiler: this thing needs to build and describe the runtime environment of a running job. I am still not really sure how module versions fit into this. Specifiers can include a version number when speaking to unpkg. But I feel like mapped paths should be handling versioning? If pointing to MODULES_HOME or even an explicit path, the version is irrelevant, I just want to use that thing. ChangesWhat changes because of this?
These all seem like positive changes |
Closing as a lot of these ideas have found their way into the code through the repo or ongoing |
A design ticket to help me straighten out some spaghetti in my head.
We have a requirement to dynamically load the dependencies of a job (ie, the adaptors it relies on, but maybe also more generally any other npm packages it may import.
For example, a job will often include the line
import { fn } from '@openfn/language-common'
. But where do we actually load@openfn/language-common
from?Because the same job my run in various places, and because different tools need to analyse this code, the resolution of this path is quite complicated.
Clients
So who needs to resolve the module
@openfn/language-common?
Also note that Lightning's code editing tools need to know what modules are imported to provide code assist and intelligence. This in practice builds on the compiler, but Lightning itself may want to pre-load module definitions or documentation for its own tooling.
So at a high level, a runtime manager (devtools or lightning) needs to be able to specify the path to a module, and the runtime and compiler both need to respect whatever path is provided.
Oh, yeah, and we need to worry about versioning as well.
Module loading rules
We can potentially provide a number of ways to provide a mapping to a module, most of them oriented around the devtools CLI.
Here are the options to resolve
@openfn/x
(without versioning):@openfn/x
from${MODULES_HOME}/@openfn/x
. The idea here is that a developer creates a local folder with their own adaptors in, sets this as an env var, and so automatically loads local language adaptors. Difficulty: If the module is@openfn/x
, then in the node_module folder, you need to have a@openfn
dir and then anx
dir inside it. Which is fine but quite an awkward setup.import('@openfn/x)
If monorepo and modules_home are both set, we probably use modules_home as it's more specific.
Since there's so much complexity in module resolution, the tooling needs to be really clear about where it's loading modules form.
MODULES_HOME may have another use. If a job has arbitarary node dependencies (ie
axios
orlodash
), those need to be installed somewhere. They're not dependencies of the CLI and shouldn't be served by the CLI's node_modules. Nor the runtime's. So arbitraryWhat do we need?
There's a lot of mapping rules here and I don't want to have to write and test them in several places (the CLI, runtime and compiler may each need to do this!).
So we need to provide a single function, which accepts options from a runtime manager. Something like:
Where does this live? It's a dependency of compiler and runtime, but not really part of either. The CLI needs it to preload module exports. It could go in a generic utils package but it's a bit lost. So maybe a
module-resolver
?I think it's literally just one function, I'm not sure what else it needs to do. I suppose we could push more logic into it?
loadDTs()
loadModule()
loadSyntheticModules()
Once you start doing that there's actually quite a close relationship to
describe-package
. Maybe that needs to evolve into like a module-helper or module-manager or something. This, I think, is part of the answer.The text was updated successfully, but these errors were encountered: