bin+lib esteem

A small and fast monorepo manager for NX workspaces

8 stable releases

1.1.8 Jul 30, 2022
1.1.7 Jul 25, 2022

#807 in Development tools

MIT license

62KB
1.5K SLoC

Rust 1K SLoC Shell 365 SLoC // 0.1% comments

esteem

Make your NX workspaces go easier on your disk.

Why?

This tool exists for a very simple reason - I am a ✨ cheapskate ✨. I would rather spend a weekend developing a tool than pay an additional $5 on Digital Ocean to buy some additional storage and calling it a day.

I present you with esteem!

NX monorepos totally rock, but where they don't is when you need to deploy your projects and now a simple Next app takes up 2GBs of storage because you also had to install dependencies of all other projects in the monorepo. esteem solves this problem by keeping track of each individual project's dependencies while also following NX's single-version policy.

How does it work?

It just keeps track of individual project's dependencies. For existing projects this means a small amount of manual work where you copy the dependencies of a project from package.json to its project.json.

When install-isolated is called for a project, it simple collects the dependencies for that package and writes it to the root package.json. You can then call your package manager's install command and viola! you have a smaller node_modules!

Installation

  • Guided installation:

    curl https://raw.githubusercontent.com/IgnisDa/developrs/main/apps/esteem/install.sh -o install.sh
    # Warning: always examine scripts downloaded from the internet before running them locally.
    bash install.sh
    
  • Manual installation:

    You can also download the appropriate executable from the releases page.

  • CI environments: For example in Dockerfile

    # This script writes to /usr/local/bin/, you can change this via the `--bin-dir` flag
    RUN curl https://raw.githubusercontent.com/IgnisDa/developrs/main/apps/esteem/install.sh | sudo sh -s -- --yes
    

Miscellaneous

Esteem separates dependencies by project scope (project or workspace) and requirement scope (required or development).

Project scopes

The project in which a dependency is to be installed. If it is a project dependency, it is well... exactly that: a project dependency. Project dependencies are written to their corresponding project.json.

A workspace dependency can be treated as a global dependency. They are written to the root workspace.json. These dependencies will always be a part of the final package.json.

Requirement scopes

Think of required and development scopes as analogous to dependencies and devDependencies in npm projects.

Usage

esteem has very few commands of its own; most of the heavy lifting is done by your package manager (npm, yarn, pnpm etc).

Right now esteem is only compatible with NX monorepos (or all projects where there is a root level workspace.json and project level configurations in <project_type>/<project_name>/project.json).

Note: You can always run esteem <subcommand> --help for more information.

init

Prepares new repositories to be used with esteem. This will add an object of this structure to all project.json files and workspace.json.

Note: You don't need to run this command if you don't want to, esteem can handle projects without dependencies key.

{
  "dependencies": {
    "development": [],
    "required": []
  }
}

Now for each project.json, you will have to manually add the dependent packages for that project. So if project server depends on nestjs and prettier, you will have to make these changes.

Eg: apps/server/project.json

{
  "dependencies": {
    "development": ["prettier"],
    "required": ["nestjs"]
  }
}

Here is a project.json from the example repository.

add

It adds a dependency to a project. Eg:

$ esteem add server redis luxon
# your package manager called automatically after making changes to `projects/server/project.json`

Pass the -D flag to add it a development dependency.

workspace add

Same functionality as above but for workspace scoped dependencies.

remove

Removes a dependency from a project taking into account whether other projects are dependent on that dependency.

$ esteem remove server luxon typescript bull
# your package manager called automatically after making changes to `projects/server/project.json`

workspace remove

Same functionality as above but for workspace scoped dependencies.

install-isolated

This command collects ALL the dependencies of a project (and its dependent project) and writes to package.json. This command is meant to be run only on CI environments because it changes your package.json file. It makes a backup of the package.json file. It is your job to call your package manager to install the dependencies.

esteem install-isolated server

It also accepts multiple parameters and resolves all the dependencies. It uses NX Graph under the hood to solve the dependency tree.

Some caveats

  • The lockfile will NOT be in sync with package.json because esteem does not resolve dependencies. However this should not be a problem since dependencies have only been removed and not added (and they were already resolved in the lockfile). However, this means that pnpm install --frozen-lockfile and similar commands WILL fail. Just remove that flag and it should work as expected.

  • If you run the command esteem install-isolated server, the following files are expected to be present (with the paths intact):

    • package.json
    • pnpm-lock.yaml (or your package manager's lockfile)
    • workspace.json
    • apps/server/project.json
    • libs/config/project.json (assuming server depends on config)

    You can refer to these lines of the example repository to see this in action in a Dockerfile.

Example

Bookius is a project where esteem is used in conjunction with Dokku, Github Actions and Docker for deployment. All projects therein are deployed from a single Digital Ocean droplet.

You can consult Dockerfile to see it being used in a docker environment.

Contributing

Your PRs and stars are always welcome.

Dependencies

~7–17MB
~238K SLoC