STRUCTURE OF A MONOREPO
A monorepo can contain multiple applications (here: apps) whereas each application has access to shared set of packages. Bear in mind that this is already an opinionated monorepo structure:
- apps/
--- app-one
--- app-two
- packages/
--- package-one
--- package-two
--- package-three
A package, which is just a folder, can be anything from UI components (e.g. framework specific components) over functions (e.g. utilities) to configuration (e.g. ESLint, TypeScript):
- apps/
--- app-one
--- app-two
- packages/
--- ui
--- utilities
--- eslint-config
--- ts-config
A package can be a dependency of another package. For example, the ui package may use functions from the utilities package and therefore the ui package depends on the utilities package. Both, ui and utilities package, may use configuration from the other *-config packages.
The apps are usually not dependent on each other, instead they only opt-in packages. If packages depend on each other, a monorepo pipeline (see Monorepo Tools) can enforce scenarios like "start ui build only if the utilities build finished successfully".
Since we are speaking about a JavaScript/TypeScript monorepo here, an app can be a JavaScript or TypeScript application whereas only the TypeScript applications would make use of the shared ts-config package (or create their own config or use a mix of both).
Applications in apps don't have to use shared packages at all. It's opt-in and they can choose to use their internal implementations of UI components, functions, and configurations. However, if an application in apps decides to use a package from packages as dependency, they have to define it in their package.json file:
{
"dependencies": {
"ui": "*",
"utilities": "*",
"eslint-config": "*"
},
}
Applications in apps are their own entity and therefore can be anything from a SSR application (e.g. Next.js) to a CSR application (e.g. CRA/Vite).
In other words: applications in apps do not know about being an repo in a monorepo, they just define dependencies. The monorepo (see Workspaces in Monorepos) decides then whether the dependency is taken from the monorepo (default) or from a registry (fallback, e.g. npm registry).
Reversely, this means that an application can be used without being part of the monorepo as well. The only requirement is that all its dependencies (here: ui, utilities, eslint-config) are published on a registry like npm, because when used as a standalone application there is no monorepo with shared dependencies anymore (see Versioning with Monorepos).
'Basic Coding Info > Monorepo' 카테고리의 다른 글
What is a Monorepo? (0) | 2022.06.08 |
---|