Skip to content

Instantly share code, notes, and snippets.

@beeman
Last active October 1, 2021 08:40
Show Gist options
  • Save beeman/e03140f815b4b45f049c3ebc6c4f1445 to your computer and use it in GitHub Desktop.
Save beeman/e03140f815b4b45f049c3ebc6c4f1445 to your computer and use it in GitHub Desktop.
Schematic to sort your projects and paths in nx.json, workspace.json (or angular.json) and tsconfig

How to sort the projects and paths in your Nx Workspace

This is now availble on NPM:

yarn add -D @nxpm/cli
yarn nxpm-stack lint

Why?

When adding a new project to an Nx Workspace, the projects gets added to the bottom of the projects in nx.json and {workspace/angular}.json.

While this is not a problem per-se, it can cause issues when several developers create new projects and want to merge them in around the same time.

In order to fix this, it makes sense to sort these projects by name, and do it automatically on commit.

Added benefit is that it keeps the files neat and clean.

How?

Step 1

Inside your Nx Workspace, create a new workspace-schematic:

nx generate @nrwl/workspace:workspace-schematic projects-sort

Step 2

Replace the content of tools/schematics/projects-sort/index.ts with the followin code:

import { chain, Rule, SchematicContext, Tree } from '@angular-devkit/schematics'
import { readJsonInTree } from '@nrwl/workspace'

function getFileContents(tree: Tree, ctx: SchematicContext, filename: string) {
  if (!tree.exists(filename)) {
    ctx.logger.fatal(`Cannot find ${filename}`)
    return tree
  }
  return readJsonInTree(tree, filename)
}

function sortItems(items: Record<string, unknown>) {
  return Object.keys(items)
    .sort()
    .reduce((acc, curr) => ({ ...acc, [curr]: items[curr] }), {})
}

function sortPaths(filename): Rule {
  return (tree, ctx) => {
    const file = getFileContents(tree, ctx, filename)

    const updated = {
      ...file,
      compilerOptions: {
        ...file.compilerOptions,
        paths: sortItems(file?.compilerOptions?.paths),
      },
    }

    tree.overwrite(filename, JSON.stringify(updated, null, 2))
    ctx.logger.info(`Sorted Paths in ${filename}`)
    return tree
  }
}

function sortProjects(filename: string): Rule {
  return (tree, ctx) => {
    const file = getFileContents(tree, ctx, filename)

    const updated = { ...file, projects: sortItems(file?.projects) }

    tree.overwrite(filename, JSON.stringify(updated, null, 2))
    ctx.logger.info(`Sorted Projects in ${filename}`)
    return tree
  }
}

export default function (): Rule {
  return chain([
    sortPaths('tsconfig.base.json'),
    sortProjects('nx.json'),
    sortProjects('workspace.json'),
  ])
}

Step 3

You can now run the workspace schematic like this:

yarn workspace-schematic projects-sort && yarn format:write

Run it automatically

If you want to run this check automatically, you can configure husky and lint-staged:

  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "nx.json": [
      "yarn workspace-schematic projects-sort",
      "yarn format:write"
    ]
  }

Why do all this manually?

This is a first implementation, I will most likely add this to https://nxpm.dev/ at some point.

You don't have to do it manually, you can now install it:

yarn add -D @nxpm/cli
yarn nxpm-stack lint

Feel free to ping me if you have any questions or comments: https://twitter.com/beeman_nl

@MkMan
Copy link

MkMan commented Aug 5, 2021

Just used your cli using npx npx -p @nxpm/cli nxpm-stack lint 👌 Thanks heaps ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment