mrdr

0.1.3 • Public • Published

mrdr - Mono repo dev runner

mrdr (pronounced: /mordor/) is a Swiss-army knife for running tasks in a monorepo.

Usage

This app requires a bit of setup, which you probably already have, but let's re-iterate what's needed.

NPM workspace configuration

In your monorepo there's a parent package.json that needs to have your workspaces listed. Given that your project contains 3 packages, a, b and c here's the necessary configuration:

/package.json

{
  "workspaces": [
    "packages/a",
    "packages/b",
    "packages/c"
  ]
}

Individual project configuration

Each project can either be a shared library or an application.

Shared libraries

In the case of a shared library you need to tell it what artifacts are exposed from it. This is standard npm package configuration, but for the sake of completeness here's an example, where package c from the above workspaces definition is a shared library:

/packages/c

{
  "name": "c",
  "exports": {
    ".": {
      "default": "./dist/c.js",
      "require": "./dist/c.umd.cjs",
      "types": "./dist/index.d.ts"
    }
  }
}

Dependencies

Let's assume package a is an application that would like to use package c as a library. The standard way of expressing that dependency is to put it in the list of dependencies:

{
  "name": "a",
  "dependencies": {
    "c": "*"
  }
}

It can also be a devDependency - doesn't matter as long as one of those sections contain the dependency to c.

Scripts

Now to the good part - running builds.

Once you have all your exports and dependencies defined it's time to define scripts that will build your project for both development and final build.

In this example I am going to assume you're going to use vite because if you're still using webpack you should rethink your life, maybe change jobs or just upgrade. It is worth every effort (unless you can't for some technical reason...)

In your common library (c) you define the scripts as follows:

/packages/c/package.json

{
  "scripts": {
    "dev": "vite build -w",
    "build": "vite build"
  }
}

In your application (a) you define them as follows:

/packages/a/package.json

{
  "scripts": {
    "dev": "vite",
    "build": "vite build"
  }
}

This is pretty standard configuration that all examples on the Internet and all the templates will follow - because it is obvious and simple.

Top-level scripts

In the strictest sense you don't need them but it is surely a nice to have thing:

/package.json

{
  "scripts": {
    "dev": "mrdr",
    "build": "mrdr build"
  }
}

Command-line options

mrdr is a very young utility so the options are few at the moment:

Usage: mrdr [options] [command]

Options:
  -V, --version           output the version number
  -h, --help              display help for command

Commands:
  run [options] [script]  Run a task recursively within the monorepo
  ls [options]            List dependencies between projects
  help [command]          display help for command

The run command is for running tasks

Usage: mrdr run [options] [script]

Arguments:
  script                       Script to execute (default: "dev")

Options:
  -q, --quiet                  Be quiet
  -v, --verbose                Be verbose
  -P, --prefix <path>          Workspaces root (default: ".")
  -d, --delay <ms>             Additional miliseconds to wait after the resource is created (default: 200)
  -t, --timeout <s>            Max time in seconds to wait for resources to be generated (default: 30)
  -w, --workspace <workspace>  Run only the given workspace and its dependencies (default: "")
  -C, --clean [task]           Call the "clean" task before building a project; defaults to "clean" task
  --no-wait                    Do not wait for resources to be created (useful for running the "clean" task alone)
  --vite-reload-hack           Install a hack that kicks dependent projects when a dependency is rebuilt
  -h, --help                   display help for command

The ls task is for listing dependencies between projects:

Usage: mrdr ls [options]

List dependencies between projects

Options:
  -w, --workspace <workspace>  Run only the given workspace and its dependencies (default: "")
  -P, --prefix <path>          Workspaces root (default: ".")
  -h, --help                   display help for command

Listing dependencies

It is possible to have the dependencies between projects listed, possibly for debugging

npx mrdr ls

Running tasks

Being in your top-level folder, if you want to run everything in dev mode all you need to do is:

npx mrdr

It will take the dev script from your packages and run it in order from least-dependent to most-dependent.

WARNING! No circular dependency check is done. If you have a case like that, don't use mrdr before you cut them!

You also might want to build your project in the proper sequence:

npx mrdr build

Vite.js hack for reloading projects

At present there is a bug either in vite.js or in vue.js or the hot-reloader for vue.js. The bug manifests in such a way that you need to manually reload the page if a package is used that is located behind a symlink.

Since npm workspaces automatically link packages in the top-level node_modules folder they are always behind a symlink. The hack does a touch on vite.config.js (if it exists) to poke vite to restart the application. It may not be what you need, hence this is an option. Use it if it helps, forget it ever existed if it hurts your feelings

Have fun using mrdr!

Dependencies (6)

Dev Dependencies (1)

Package Sidebar

Install

npm i mrdr

Weekly Downloads

13

Version

0.1.3

License

Apache-2.0

Unpacked Size

19.8 kB

Total Files

9

Last publish

Collaborators

  • padcom