Skip to main content

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.
  • peerDependencies:
    • Used in functional "modules" to declare runtime requirements.
    • Not installed automatically.
    • Must be provided by the consuming project or parent module.
warning

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
tip

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 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.

tip

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.

warning

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 all package.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).
note

When modules are symlinked, you can test changes in-place without republishing.

info

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

  1. 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
  2. In the project’s package.json, add a custom script:

    "scripts": {
    "show-dependency-tree": "npm ls --all"
    }
  3. Run npm install using the context menu of package.jsonNodeJS.

  4. In the Run Configuration dropdown, select show-dependency-tree and execute the script.

    The output will appear in the NodeJS output window.

show dependency tree 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.

tip

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.

tip

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.