Appendix A - Dependency Management
Dependency Management
package.json
Explained
Each ADITO package (either of type "project"
or "module"
) contains a package.json
file. This file defines the module type, its dependencies, compatible platform version, scripts, and metadata for publication. Understanding and configuring this file correctly is essential for modular development.
Project vs. Module
"type": "project"
: Used for the top-level package. It may include only system-level configuration and operational settings. It defines"dependencies"
and must not use"peerDependencies"
."type": "module"
: Used for all logic-bearing packages. Modules can contain own functionality and reference other modules via"peerDependencies"
.
Dependencies vs. PeerDependencies
dependencies
:- Used in
"project"
and parent modules. - Installed automatically via
npm install
. - Used to aggregate or collect other modules.
- Used in
peerDependencies
:- Used in functional
"modules"
to declare runtime requirements. - Not installed automatically.
- Must be provided by the consuming project or parent module.
- Used in functional
A "project"
package must never use "peerDependencies"
. Doing so will prevent the project from being executed correctly.
Overrides
The "overrides"
field in package.json
allows you to:
- Temporarily replace a required dependency with a specific version
- Bypass version mismatches in dependent modules for testing
Overrides are not recommended for production. Use them only during development.
Engines
The "engines"
field restricts the version of the ADITO core platform this module can run with:
"engines": {
"adito": ">=2024.1.0-RC <2024.1.1"
}
Scripts
The "scripts"
section allows the definition of npm scripts, e.g.:
"scripts": {
"npm install symlinks": "npm install --install-links=false",
"startMariaDB": "node ./scripts/mariaDB.js"
}
These scripts appear in the Designer's NodeJS Run Configuration dropdown.
node_modules
Folder
The node_modules
folder is automatically created when running npm install
. It contains all installed dependencies defined in the project's package.json
, including dependencies
, devDependencies
, and peerDependencies
.
Dependencies under the @aditosoftware
namespace are installed into the node_modules/@aditosoftware
subdirectory. These include the source code of referenced modules that match the versions declared in the consuming module's package.json
.
Local Modules and Symlinks
Local modules allow direct referencing of sibling packages during development. This is useful when working on multiple modules in parallel and testing changes across them. Instead of publishing each change to a package registry, you can reference the source code directly. To do so, specify a relative path in the version
field of your package.json
:
"@aditosoftware/activity": "../activity"
This setup allows real-time access to the source code of the local module without requiring repeated calls to npm install
.
Enabling Local Linking
To enable local module resolution with symbolic links, configure the .npmrc
file by adding the following entry:
install-links=true
This instructs npm
to link local modules instead of copying them. As a result, changes in the source module are reflected immediately in the referencing module.
Once configured, local modules will be symlinked into the node_modules
directory instead of being copied.
Symlinks ensure that changes to the local module are immediately reflected in the referencing module.
Forcing Updates with Package Lock
npm may not automatically update to the latest minor version of a module if a compatible version is already locked in package-lock.json
.
In such cases, you can override this behavior with:
npm update --package-lock-only --package-lock=false
This updates package-lock.json
to match the latest compatible version as defined in package.json
.
Then run:
npm clean-install
This reinstalls all packages using the updated package-lock.json
.
Always verify version consistency between package.json
and package-lock.json
when working with local modules.
File Structure
Example folder layout:
basic-project/
├── node_modules/
│ └── @aditosoftware/
│ ├── contact/
│ ├── activity/
│ └── utility/
├── package.json
└── .npmrc
Example
Suppose module activity
declares a peerDependency
on the module contact
. As a result, the source code of Organisation_entity
from contact
will be available in the following location inside activity
:
…\AditoProjects\activity\node_modules\@aditosoftware\contact\entity\Organisation_entity
In the ADITO Designer, dependent modules appear under the folder External Libraries. Models (e.g., Entities) originating from these modules are annotated with their source module and version, such as @aditosoftware/activity:1.0.0
, providing clear traceability.
Module Resolution
npm install
reads the full dependency tree as defined in allpackage.json
files.- Peer dependencies must be resolved by another module higher in the graph.
- Modules can be reused across branches of the dependency graph, forming a Directed Acyclic Graph (DAG).
When modules are symlinked, you can test changes in-place without republishing.
The node_modules
folder can be safely deleted at any time. It is excluded from version control via .gitignore
. Re-running npm install
will fully restore its contents.
Dependency Tree
In a modularized ADITO project, the nesting of project and module packages can quickly become complex and difficult to manage. The dependency tree provides a structured overview of the relationships between modules and helps identify potential issues in the project architecture.
A dependency tree shows the hierarchical structure of an ADITO project, starting from the top-level project module and including all referenced modules, as defined in each module’s package.json
. It is a valuable tool for analyzing module relationships and identifying structural issues.
You can visualize the dependency tree using the command npm ls --all
, which lists all installed modules, including their full dependency paths.
Viewing the Dependency Tree in ADITO Designer
-
Open the top-level project module in the ADITO Designer.
- If not available locally, clone it from Git:
File → New Project → Clone from Git Repository
Example URL:https://gitlab.adito.de/xrm-modules/basic-project
- If not available locally, clone it from Git:
-
In the project’s
package.json
, add a custom script:"scripts": {
"show-dependency-tree": "npm ls --all"
} -
Run
npm install
using the context menu ofpackage.json
→ NodeJS. -
In the Run Configuration dropdown, select show-dependency-tree and execute the script.
The output will appear in the NodeJS output window.
Figure: Dependency tree output in the ADITO Designer
The dependency structure is printed to the NodeJS output. The keyword deduped
indicates that a dependency is shared and not duplicated. See the npm dedupe documentation for details.
@aditosoftware/basic-project
├─ @aditosoftware/contactmanagement
│ ├─ @aditosoftware/activity
│ │ ├─ @aditosoftware/root (deduped)
│ │ └─ @aditosoftware/utility (deduped)
│ └─ @aditosoftware/contact
│ ├─ @aditosoftware/attribute
│ └─ @aditosoftware/keyword
└─ @aditosoftware/platform
└─ @aditosoftware/utility
Figure: Example structure extracted from npm ls --all
output.
Use this tree to verify shared module usage, such as whether utility
is deduplicated or installed redundantly.
This tree view helps you understand the full module structure of your project without manually inspecting each package.json
. It is especially useful for debugging dependency conflicts and verifying correct resolution.
To inspect the dependency tree for a specific module, repeat the same process in the context of that module’s folder. This provides a focused view on its direct and transitive dependencies.
Folder "External Libraries"
In the Designer’s "Projects" window, the folder External Libraries appears at the bottom of the project tree. It contains all modules that are listed as dependencies of the current project. These modules are made available automatically and do not need to be cloned manually.
This view allows direct access to the models of dependent modules for inspection or reference. If changes are made to these models, they are not written into the original module. Instead, a corresponding modification is created in the referencing module, as described in Modifications.
Find Function Scopes
The Find feature, accessible from the root node’s context menu, offers multiple search scopes:
- Selection or Current Project: Searches only within the currently selected module.
- Open Projects: Searches within the current module and all its dependencies listed under External Libraries.