Open tukusejssirs opened 1 year ago
@MRIIOT, just a quick note: moving to use Nx monorepo is much easier than using Nest (obviously). There are some guides to adopt Nx, from which the one that we might want to use is Manual migration of existing code bases. The first and basic task is simple create a new Nx workspace within the repo and move apps and libs to the workspace. That should be a trivial task, however, there might be some changes required.
@bburns describe the impact on setup scripts, setup folder structure, general installation and usage workflow.
services/
seem to be separate apps, therefore I suggest to rename that folder toapps/
, probably using Nx;
they're all running at same time and interacting like services, not independent apps, so i liked that term - that's how they're referred to in the docs also. an app to me is more like something user-facing. so would prefer to keep as services.
nx looks good - their default structure is
foo/
├── packages/
├── nx.json
└── package.json
should we stick with packages? or i guess can call it whatever we want?
might also want a services/common folder for common code, though not sure how that would work with building docker images, eg the adapter image, which would need to install this common package code
shell/
is just another app (or a collection of apps?), thus it (they all?) should be moved into separate folder(s) withinapps/
:
i do think shell should stay top-level, eg for discoverability
consider moving from BASH to JS/TS; consider using Commander.js;
would love to do that - they started as tiny shell scripts and grew to ugly bash code which i don't like. it's a matter of time/budget.
'setups'
- I am not sure if
setups/
should be part of the codebase, maybe we should move it todocs/
and there might not be neededexample/
folder at all;- I think we should remove/move this folder;
sounds good - i'd left the example setup in there for when user tries out l99, and as a base for new setups (using 'l99 init foo' command), but could pull it out to a setup-example repo, and add the instruction to do 'l99 download example' to the docs, and the l99 init command could make sure example setup is downloaded as a base to copy from.
volumes/
:
- I am not sure what is
volumes/
used for, however, it seems to be just some Grafana config, thus consider moving it in that app (inapps/
) that needs this.- I think we should remove/move this folder;
good idea - can move to services/grafana.
If we want to use Nx, it has a distinction between apps and libraries. AFAIK, most of the apps (like drivers) we have, are libraries actually, therefore those would reside in
libs/
folder under Nx. Other apps (or microservices) would live underapps/
.
have you developed plugins with nx? is that how you would do it?
i kept the plugins in the relevant service for simplicity, eg https://github.com/Ladder99/ladder99/blob/main/services/adapter/src/drivers/modbus.js
if a client wants to develop custom drivers they can keep them in their setup folder (code to search there not yet implemented tho).
so - would need further exploration for this - can leave where they are for now.
I really like Nx monorepo. I understand that this change is quite fundamental and @bburns would need to learn a new tool (actually, a few of them: ESLint, Nx, potentially Nest), however, I really think it would ease are work in the long-term.
it all sounds good!
describe the impact on setup scripts, setup folder structure, general installation and usage workflow.
i don't think it would have too much impact, other than what was noted above -
scripts - prefer to leave in shell folder setup folders - can stay same place, same structure - just move example setup out of this repo installation - don't know yet - otto? usage - should be same
services/
seem to be separate apps, therefore I suggest to rename that folder toapps/
, probably using Nx;they're all running at same time and interacting like services, not independent apps, so i liked that term - that's how they're referred to in the docs also. an app to me is more like something user-facing. so would prefer to keep as services.
In Nx and Nest terminology, an app can be any kind of app, be it a CLI app, web server, microservice, …
nx looks good - their default structure is
foo/ ├── packages/ ├── nx.json └── package.json
Well, in practice, we could name the src
/apps
/libs
folder(s) whatever we want, however, both Nest and Nx uses src/
folder name as the source folder containing all data of a single app.
When there is only a single app in a Nest or Nx workspace, the src/
folder is in the repo root folder.
However, when there are at least two apps (or one app and one library) in either Nest or Nx workspace, the folder structure changes so that there is apps
folder for all apps and libs
folder for all libraries.
apps
├── app1
│ └── src
└── app2
└── src
libs
├── lib1
│ └── src
└── lib2
└── src
should we stick with packages? or i guess can call it whatever we want?
I suggest to keep the folder structure with default folder names.
might also want a services/common folder for common code, though not sure how that would work with building docker images, eg the adapter image, which would need to install this common package code
As I have already said above, services are apps too from Nx/Nest point of view.
What is common
folder for? I presume I’d contain some libraries. In Nx, we can have import libraries from within the monorepo under a predefined prefix, like in @ladder/libName
, the prefix is @ladder
. We could have multiple prefices in a monorepo, although it is usually only one. Is that the use case for your suggested common
folder?
As for building docker images and compiling code, it is usually all built/compiled into dist/
folder (it could be changed though). Every app has a separate subfolder (e.g. apps/ladder
app is compiled into dist/ladder
). By default, Nx uses Webpack, thus all libraries are ‘copied’ (built) into the the apps (all apps that import that library) unless we configure the library to be buildable. However, until an app/lib is moved into Nx workspace, it could be built whatever way we want (i.e. we do the steps, like build/start/publish, manually, ideally using a script that is defined in package.json
).
shell/
is just another app (or a collection of apps?), thus it (they all?) should be moved into separate folder(s) withinapps/
:i do think shell should stay top-level, eg for discoverability
Scripts could stay in a scripts/
folder, however, we might want to port the BASH scripts (esp the CLI app) into JS (e.g. using Nest + Nest Commander), then is should be moved to apps/cli
and it might be installable via @ladder/cli
from NPM.
consider moving from BASH to JS/TS; consider using Commander.js;
would love to do that - they started as tiny shell scripts and grew to ugly bash code which i don't like. it's a matter of time/budget.
Yeah, I actually dislike BASH (apart of some quick, short-term stuff), as it is not maintainable in the long run and untestable (at least I don’t know of any BASH test framework).
'setups'
- I am not sure if
setups/
should be part of the codebase, maybe we should move it todocs/
and there might not be neededexample/
folder at all;- I think we should remove/move this folder;
sounds good - i'd left the example setup in there for when user tries out l99, and as a base for new setups (using 'l99 init foo' command), but could pull it out to a setup-example repo, and add the instruction to do 'l99 download example' to the docs, and the l99 init command could make sure example setup is downloaded as a base to copy from.
Yeah, from example point of view, example/
folder makes sense, however, IMHO all examples should be in docs/
.
IMHO l99 init
should generate new configuration from code snippets stored in the l99 init
script itself (or a BASH/JS file it sources/imports). I understand l99 download
command and it is useful, however, IMHO there should a single default config used by l99 init
and then the user either provide the values using command options (e.g. --grafana-ip 1.2.3.4
) or env vars (e.g. GRAFANA_IP=1.2.3.4
) or l99 init
should prompt for the config values or the default should be used (using l99 init -y
where -y
is to assume yes). That said, I still have no idea about how it actually works in l99
.
If we want to use Nx, it has a distinction between apps and libraries. AFAIK, most of the apps (like drivers) we have, are libraries actually, therefore those would reside in
libs/
folder under Nx. Other apps (or microservices) would live underapps/
.have you developed plugins with nx? is that how you would do it?
No, I haven’t developed a Nx plugin yet, but I use some pre-built plugins like @nrwl/nest:application
to generate a Nest app or @nrwl/nest:library
to generate a Nest library (and @nrwl/nest:remove
to remove a Nest app or library). Here is a list of Nx plugins.
However, I think you talk about libraries (in Nx/Nest terminology), e.g. a Modbus driver. And yes, I have build some libraries. :wink:
I call your drivers (and other, non-app stuff in l99
) libraries. Yes, from some point of view, they are l99
plugins, however, in general I’d call them libraries, although they are not to be used by other apps.
if a client wants to develop custom drivers they can keep them in their setup folder (code to search there not yet implemented tho).
I am sort of lost: what custom drivers you mean a client could develop? IMHO a l99
plugin system could be developed for this purpose if we wanted to, however, I see no (current) use case for this (I might be wrong and I might misunderstant your comment).
scripts - prefer to leave in shell folder setup folders - can stay same place, same structure - just move example setup out of this repo installation - don't know yet - otto? usage - should be same
I’d say, for now, we should keep everything as it is, then later (when we find some time for this) decide which (single) app/library to move to Nx workspace, setup the build system, etc, and only then will @bburns actually see what does it mean to work in an Nx monorepo. :wink: After than, we could move apps and libraries one by one, modifying the config as needed, potentially port the shell scripts (a sort of l99
CLI app) to JS (or TypeScript? :wink:).
You seem to have multiple packages in a single repository, but the repository structure is a bit confusing. Below is a suggested structure:
apps/
:services/
seem to be separate apps, therefore I suggest to rename that folder toapps/
, probably using Nx;shell/
is just another app (or a collection of apps?), thus it (they all?) should be moved into separate folder(s) withinapps/
:docs/
:design/
seems to be part of documentation, therefore it should be moved (or merged) intodocs/
(see #215);libs/
:example/
:setups/
should be part of the codebase, maybe we should move it todocs/
and there might not be neededexample/
folder at all;volumes/
:volumes/
used for, however, it seems to be just some Grafana config, thus consider moving it in that app (inapps/
) that needs this.If we want to use Nx, it has a distinction between apps and libraries. AFAIK, most of the apps (like drivers) we have, are libraries actually, therefore those would reside in
libs/
folder under Nx. Other apps (or microservices) would live underapps/
.I really like Nx monorepo. I understand that this change is quite fundamental and @bburns would need to learn a new tool (actually, a few of them: ESLint, Nx, potentially Nest), however, I really think it would ease are work in the long-term. Currently, Brian does all the hard work, however, why should we do something that is already created for us. Moreover, this tooling helps us generate some boilerplates, helps with testing, structuring, validating the code, building CRUD methods, APIs, etc. Currently, it is a bit of a mess (structurally and codewise too). On the other, Brian seem to do well, which means he’s an experienced programmer. :wink: