Support for monorepo in Gleam CLI #3859
ghivert
started this conversation in
Ideas & suggestions
Replies: 1 comment 4 replies
-
Thoughts on making inheritance from the workspace Top-level workspace [workspace]
packages = [
"package_1",
"package_2"
]
[workspace.package]
gleam = "1.6.0"
license = "MIT"
authors = ["Author #1", "Author #2"]
[workspace.package.repository]
type = "github"
user = "ghivert"
repo = "redraw"
[workspace.dependencies]
gleam_stdlib = ">= 0.43.0 and < 2.0.0"
[workspace.dev-dependencies]
gleeunit = ">= 1.2.0 and < 2.0.0" Then in a package's gleam.workspace = true
authors.workspace = true
license.workspace = true
repository = { workspace = true, path = "path/to/this/package" }
[dependencies]
gleam_stdlib = { workspace = true }
glint = "1.1.0"
[dev-dependencies]
gleeunit = { workspace = true } This is the approach that Cargo takes. |
Beta Was this translation helpful? Give feedback.
4 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Why monorepo in the first place?
Many Gleam users nowadays seems to be building their project as a monorepo. And it makes sense, because monorepo for Gleam seems like a natural thing. Because we need to share types between frontend and backend in the first place, but also because sometimes we need to vendor some dependencies for example. Path dependency notably helps on that subject, and it's regularly the solution proposed when newcomers experiment with code sharing.
Moreover, it's often desired to be able to bundle everything in one single repository, because it easy maintenance, it easy support for developers (only one repo to pull, one repo to keep in sync, etc.), and it easy git management.
After working on few projects on Gleam, most of them running in production daily (and as such, with some experience on the subject), I think it's the correct time to start discussion about the inclusion of some monorepo tooling in the Gleam CLI, and where to put boundaries between what should be (hypothetically) bundled in the Gleam CLI, and what should be handled from the outside world.
Some personal opinions
I have some opinions about monorepo in general & be happy to discuss about it. I think it's a nice place to start to already propose some key things to take in consideration, while of course, everything is subject to modification. 🙂
dotenv
ormise
for example). It's often easier to manage it from the outside, and while it can be bundled in the tooling, a lot of toolings are already managing them in a great way.sketch
,redraw
orglitr
are doing), having a way to simply manage & share them is a huge gain.An idea to start exploration
Like many monorepo tooling, I think it would make sense to use a configuration file, at the root of the project. Something like
gleam.toml
, maybe with a different name if we prefer to keepgleam.toml
for single projects. I like the idea to usegleam.toml
though, because it allows to start the project as a simple experimentation, and then switch to a monorepo when it's needed. (For information, that's what Yarn or NPM are doing, by relying onpackage.json
as configuration file.)The root
gleam.toml
would define the Gleam version provided (but does not take care of installation or anything, let's delegate this tomise
,asdf
, or other package managers), and every package would use it. In case an inconsistency is found in a package or dependency, warn immediately.I think we could define a monorepo at root with a slightly different
gleam.toml
. We could keep the existing fields, and add a fieldworkspace = true
. Once activated, the folder and every children folders will start to behave as monorepo. Taking inspiration from others monorepo management tools, I think it makes sense to consider the root folder acts as a "Workspace". A workspace is a collection of packages and services, that could compile, lint, execute scripts and potentially run for services.A workspace could simply define projects, whether as a key-value pair dict, or an array of global regex to auto-detect Gleam projects. For every referenced service, Gleam build tool will consider it as workspace-wide available package.
Once the build tool is aware of the different packages in the monorepo, we could introduce a new command,
workspace
, to run commands in a specific sub-project.gleam workspace package add gleam_http
would addgleam_http
directly in thepackage/gleam.toml
.Having the support for scripts is important for me, because as Gleam users, we have to rely on codegen, but also on database migrations or others stuff. I think it would be a gain to have a centralized place to define everything. For example, having an
interfaces
package defining JSON Typedef, with a script indicating how to build it would be a way to gain time. I think a key-value dict would be enough for this simple use case as a start.It would also be nice to let sub-projects define scripts, and as such, that would let
gleam workspace
command run script in sub-projects too.How the monorepo dependencies should be handled
Once the monorepo structure is made, the Gleam CLI would centralized all build artifacts, whether they're Erlang or JS at the root of the monorepo, and all dependencies would be centralized at the root of the monorepo too. Every time we need to use a package in the monorepo as a dependency, instead of relying on path dependency, we could define it as
package = {workspace = "package" }
, and the build would instantly use the artifacts already compiled in the global cache. That would speed up compile time for every services, and would solve inconsistencies.Every time a package would be modified, the build tool could also rebuild the dependent packages.
An example of what
gleam.toml
could look likeAn idea for extensions
I think it would also be worth it to let the Gleam CLI to accept plugins to run. That would help to support multiple targets, for example. If in a single monorepo, we support both Erlang & JavaScript and we got some TypeScript compilation, it would be nice to have a plugin managing the TypeScript compilation directly. Instead of having to manage every flavour of JavaScript (TypeScript, PureScript, ClojureScript, anything really), we could simply allow the Gleam build tool to call a plugin with some lifecycle hooks, and let the plugin work on its own.
Beta Was this translation helpful? Give feedback.
All reactions