Skip to content

Technical Guidelines

Kristof Vandenbroucke edited this page Jan 19, 2024 · 8 revisions

Technical Guidelines for developers

Lerna

Lerna is a popular tool for managing JavaScript projects with multiple packages, optimizing the workflow around managing multi-package repositories with git and your package manager.

Installation

Before you can use Lerna, you need to install it globally on your machine:

npm install --g lerna

Basic Usage

  1. Bootstrap the project Lerna allows you to link any cross-dependencies, install all node_modules for each package, and also hoist common dependencies to the root of your project:
npm run bootstrap
  1. Add a new package You can add a new package to the monorepo with the lerna create command:
lerna create package-name
  1. Installing modules To install dependencies across all packages in a Lerna-managed monorepo, you can use the lerna add command. This command adds a package to the packages in the monorepo.
lerna add package-name --scope=some-package

Replace package-name with the name of the package you want to install, and some-package with the name of the specific package(s) you want to add the dependency to. If you want to add the dependency to all packages, you can omit the --scope flag:

lerna add package-name

This command will add the specified package as a dependency in all of your Lerna packages.

FAQ

If I add a module inside the package.json of the monorepo, will it be added to all packages?

No, adding a module to the package.json of the root of your monorepo will not automatically add it to all of your packages. The root package.json and the package.json files in each package are separate. If you add a module to the devDependencies or dependencies in the root package.json, it will only be installed at the root level. It will not be available to the individual packages unless you specifically import it in those packages.

Can I run all tests inside the project simultaneously?

Yes, you can use the lerna run test command or more specifically call one of the test-scripts defined in the root package.json of the monorepo.

"scripts": {
    "test:unit": "lerna run test:unit",
    "test:integration": "lerna run test:integration",
}

Aliases

module-alias is a handy tool that allows you to create custom module paths and aliases within your project. This can be particularly useful in larger projects or monorepos, where relative paths can become complex and hard to manage.

Alias Configuration

Next, you'll need to add your custom paths and aliases to your package.json file. Add a _moduleAliases object to your package.json file, where the keys are your aliases and the values are the paths they should resolve to:

  "_moduleAliases": {
    "@oslo-core": "./lib"
  },

In this example, @oslo-core will resolve to the lib directory.

Note: The paths are relative to the location of the package.json file.

Usage in TypeScript

In your TypeScript files, you can now use these aliases in your import statements:

import type { IConfiguration } from '@oslo-core/interfaces/IConfiguration';

Registering Aliases at Runtime

module-alias needs to register the aliases at runtime. To do this, add the following line to the main entry point of your application:

import 'module-alias/register';

In our setup, this will typically be in the runner.ts file or in the index.ts, depending on the package.

TypeScript Configuration

For TypeScript to understand these aliases, you'll need to add a paths option to your tsconfig.json file:

{
  "compilerOptions": {
    "baseUrl": ".", // This must be specified if "paths" is.
    "paths": {
      "@oslo-converter-uml-ea/*": ["packages/oslo-converter-uml-ea/lib/*"],
      "@oslo-core/*": ["packages/oslo-core/lib/*"],
      "@oslo-extractor-uml-ea/*": ["packages/oslo-extractor-uml-ea/lib/*"],
      "@oslo-converter-stakeholders/*": [
        "packages/oslo-converter-stakeholders/lib/*"
      ],
      "@oslo-generator-jsonld-context/*": [
        "packages/oslo-generator-jsonld-context/lib/*"
      ],
      "@oslo-generator-rdf-vocabulary/*": [
        "packages/oslo-generator-rdf-vocabulary/lib/*"
      ],
      "@oslo-generator-respec-html/*": [
        "packages/oslo-generator-respec-html/lib/*"
      ]
    }
  }
}

Note: The paths in tsconfig.json should mirror the paths in your package.json file, but with an extra /* at the end of both the keys and values.

Now, both TypeScript and module-alias understand your custom module paths and aliases. If you were to add a package to this monorepo, you'll need to:

  1. Add a new alias in the tsconfig.json mentioned before
  2. Install the module-alias as a devDependency
  3. Add a _moduleAliases object inside your package.json
  4. Import the module in the root of your new package
  5. Use the alias in your code and you're good to go!