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/commonlibs/node-utilsapps/back-endapps/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.tscode common to all modules needs to be in the first module to compile. - This module cannot be in
node-utils, or elsecommonandfront-endcannot use it. - As
node-utilsneeds thebuild-info.tscode too, at runtime and build time, therefore it must depend oncommonrather 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.