Monorepo structure#
monorepo
|- apps
|- @mykomap/front-end
|- @mykomap/back-end
|- Dataset class instance for each dataset that needs a deployed backend
|- single ts-rest/Fastify server shared across all datasets
|- script to generate data for each dataset, consumed by the back-end server
|- libs
|- @mykomap/common
|- API ts-rest contract + OpenAPI spec
|- prop defs code (used by both front-end and back-end)
|- @mykomap/node-utils
|- common code that relies on the NodeJS runtime e.g. file utilities
Dependencies#
The build order, set in the build
runscript of the root package.json
is:
libs/common
libs/node-utils
apps/back-end
apps/front-end
This is because there is some common code used to label the builds,
defined in a file build-info.ts
. This ensures the labelling is
generated in a consistent way in all the modules.
Where does this code go? This gets complicated, as some modules are by
design free of NodeJS dependencies, and since those are transitory,
libs/common
cannot have runtime NodeJS dependent
dependencies. (Although, it does have devDependencies
on
node-utils
, because the tests it uses file-utils.ts
defined
there).
However: the build-info.ts
code necessarily needs to run
git-depend
to obtain information about the build, if only at build
time.
Which means:
- The
build-info.ts
code common to all modules needs to be in the first module to compile. - This module cannot be in
node-utils
, or elsecommon
andfront-end
cannot use it. - As
node-utils
needs thebuild-info.ts
code too, at runtime and build time, therefore it must depend oncommon
rather than vice versa.
Other modules can then depend on common
to get the build-info.ts
code, and only need to pull in the spawnSync
function from NodeJS in
their vite.config.ts
files, so the node dependency is only implicit
and at build time.
Ideas#
- Use monorepo manager (e.g. Nx, Turborepo) to manage builds
- Use git subtree, so we can publish sub-folders of the monorepo as independent repos that others can use. We can set this up later if required, but for now try to ensure repositories are not tightly coupled unecessarily.
- Differentiate between maps and datasets: currently a map's data and config is associated with a single dataset on the backend. We may want to unlink these so that 2 maps can share the same dataset with differnet config, or a map can show multiple datasets. This could be done in the future.
- Allow back-end code to be imported into the front-end for map builds that don't need a separate back-end.