polylith

2025-03-14T05:47:58.798859Z

For those who use polylith extensively, where do you declare component-dependent libraries? I'm writing them in component/deps.edn directly. For instance if a specific component A uses library a, I declare 'a' under A/deps.edn. When writing codes with repl on, however, since it is recommended to use :dev alias which includes all bricks, it is hard to distinguish which library I need to add specifically to the component. The library 'a' could have been used for component B, so when developing there is no issue. The problem comes when including bricks into projects and building them; often times the dependencies aren't found and I need to add them manually. Perhaps there's a poly command solving this problem? or how do you deal with this issue?

seancorfield 2025-03-14T05:51:17.306669Z

Components do not declare their dependencies on other components.

seancorfield 2025-03-14T05:52:20.146199Z

A component's deps.edn file should only list external libraries. The projects' deps.edn files are where component dependencies should be listed -- development (the :dev alias) is a project, which is why it lists all component dependencies.

seancorfield 2025-03-14T05:55:57.180319Z

The projects' deps.edn do not declare external libraries in general (those are only in the components' deps.edn files). The exception is if you have some cross-cutting libraries where you want the same version "everywhere". At work, the only external libraries declared in our projects' deps.edn files -- including the workspace-level under the :dev alias -- are log4j2 stuff and the MySQL JDBC driver. Those are indirect dependencies. In each component that references next.jdbc, for example, we declare that as in the component's deps.edn.

seancorfield 2025-03-14T05:57:35.103399Z

If code in a component references an external library, then that library should be declared in that component's deps.edn file -- which automatically makes it available in the REPL via :dev and in projects that use that component.

seancorfield 2025-03-14T05:57:57.818319Z

Does that help @tlonist.sang?

2025-03-14T06:02:47.543549Z

The point I'm making here is precisely about the external libraries in a component. Let's say I need to add hato library to a component A. Of course I should add it to A's deps.edn file, but since I'm working with a repl that's defined under :dev, which includes all other components (some of which MAY have hato), I can continue writing codes without having to add hato to component A. I was asking what I could do so that I can always make sure to add hato library to the component A.

seancorfield 2025-03-14T06:16:52.611159Z

I just do it based on inspection: if the code references a library, I add it to the deps.edn file. I guess you could run something like athos/clj-check in each project folder to check each project compiles, which would highlight if a project was missing transitive library deps, but I don't think you can do much on a per-component basis.

✅ 1
seancorfield 2025-03-14T06:17:38.437479Z

A component on its own isn't compilable (b/c it doesn't declare its components' dependencies, only its libraries).

seancorfield 2025-03-14T06:19:12.579859Z

Since library dependencies can be provided only in projects' deps.edn files (instead of components' deps.edn files) -- such as my example of log4j2 or MySQL -- there's no way to determine that a component is "missing" a library dep, only if a project is missing it.

seancorfield 2025-03-14T06:21:11.543129Z

We have about 200 deps.edn files in our repo at work. About 150k lines of Clojure, 20 bases, 20 projects, 160 components. I'm sure we have some components that are missing library deps, but are always used with another component that has that dep, so we just don't notice.

seancorfield 2025-03-14T06:24:37.157159Z

TL;DR: no, there's no poly solution to this, and no possible solution in general -- and it's not really proved to be a real problem for us at work, despite the size of our codebase and the huge number of external libraries we depend on.

👍 1
✅ 1
2025-03-14T06:44:38.898569Z

Got it. If I understand correctly, what you are saying is that as long as project-wise dependencies are resolved (properly included), you don't think it is a problem and has never been one, am I right?

seancorfield 2025-03-14T06:48:58.164929Z

Yeah, I understand that you can "get away with" not adding the library dependency to every component and then tripping over it in a specific project, because it doesn't happen to depend on a component that brings that library in but does use the component that you forgot to add it to -- but in reality, it's not much a of a problem in general. I've had it happen a few times, and found the problem the next time I build a project with AOT and get an error. Mostly, I just try to be really aware of what I add to my ns forms and make sure I add those libraries to deps.edn immediately.

seancorfield 2025-03-14T06:50:40.404459Z

There cannot be an automated solution to this because there's no mapping from namespaces or imported class names to the group/artifact of a library, so there's no way to tell whether a given reference is satisfied or not -- short of compiling/running the code.

✅ 1
2025-03-14T06:54:59.654389Z

Got it. I was actually doing it that way; but wanted to know if there's a common practice around it. Thanks

imre 2025-03-14T09:24:07.663249Z

> Since library dependencies can be provided only in projects' deps.edn files (instead of components' deps.edn files) Is this really the case though? I thought this only applied to component dependencies

namenu 2025-03-14T12:06:33.547449Z

My experience goes along with Sean. Missing dependencies can easily be found at build time and/or CI. However, you can be screwed up nicely by optionally loaded libraries (e.g. hato without cheshire)

🙌 1