Quantcast
Channel: ANGULARarchitects
Viewing all articles
Browse latest Browse all 32

NX Release – The NPM Butler

$
0
0

Ever wrestled with managing shared libraries in a monorepo? You're not alone! As we explore in our workshops, Strategic Design (DDD) has transformed how we handle shared resources, particularly design systems. These design systems are the unsung heroes of consistent user experiences across enterprise applications, maintained by dedicated platform teams who ensure every component meets the highest standards.

Gone are the days of tedious manual releases and custom deployment scripts. Enter NX - a game-changing tool that streamlines our entire workflow and perfectly complements our architecture. Let me show you how it's revolutionizing the way we handle npm package deployment.

Let's explore a powerful NX feature that improves developer experience (DX) by examining a small Angular project.

We're creating an Nx monorepo for our enterprise company where a dedicated team develops a design system for use across all business units. The architect has chosen to create a monorepo with fine-grained npm packages. Our @robotui namespace requires these npm packages: core, i18n, themes, datatable, and components. In the future, we may add more packages or switch to a package-per-component approach.

Building and publishing releases with proper changelogs can be challenging in a traditional monorepo (whether using Angular CLI or npm workspaces).

But lets create our monorepo first:

npx create-nx-workspace@latest angular-monorepo --preset=angular-monorepo

Just use esbuild, css, ssr false and github actions.

Now we need to generate our library using NX generators, for simplicity we skiping tests and inline styles and templates.

nx g @nx/angular:library --directory=packages/core --name=core --publishable=true --importPath=@robotui/core --inlineStyle=true --inlineTemplate=true --simpleName=true --skipTests=true

nx g @nx/angular:library --directory=packages/i18n --name=i18n --publishable=true --importPath=@robotui/i18n --inlineStyle=true --inlineTemplate=true --simpleName=true --skipTests=true

nx g @nx/angular:library --directory=packages/themes --name=themes --publishable=true --importPath=@robotui/themes --inlineStyle=true --inlineTemplate=true --simpleName=true --skipTests=true

nx g @nx/angular:library --directory=packages/datatable --name=datatable --publishable=true --importPath=@robotui/datatable --inlineStyle=true --inlineTemplate=true --simpleName=true --skipTests=true

nx g @nx/angular:library --directory=packages/components --name=components --publishable=true --importPath=@robotui/components --inlineStyle=true --inlineTemplate=true --simpleName=true --skipTests=true

After creating the coarse structure, we add some dummy imports within the code to create dependencies. These dependencies are automatically tracked by NX, and the graph updates automatically. To visualize the graph just enter

npx nx graph

CleanShot 2025-02-08 at 15.04.41@2x.png

What are our deployment options? We could take the manual route: building each library, updating version numbers, and running "npm publish" in the dist folder. Or we can use "nx release," which automates this entire process out of the box.

nx release

CleanShot 2025-02-08 at 15.13.03@2x.png

When we run that command, Nx matches 5 projects that are ready for publishing—exactly what we want. After we accept the major version, Nx attempts to update all package.json files and create a version, but encounters this error:

NX Unable to determine the previous git tag. If this is the first release of your workspace, use the --first-release option or set the "release.changelog.automaticFromRef" config property in nx.json to generate a changelog from the first commit. Otherwise, be sure to configure the "release.releaseTagPattern" property in nx.json to match the structure of your repository's git tags.

Since this is our first release, we need to add the "--first-release" flag to the command.

CleanShot 2025-02-08 at 15.19.46@2x.png

Awesome! NX automatically created our packages, bumped the version, created a commit with a tag, and generated the CHANGELOG.md file.

Usually its a bad practice to directly push something out of our dev machine (thats more something for an process and should be done with CI/CD pipeline).

For local deployment, we can use Verdaccio as our local npm repository. One approach is to install Verdaccio globally:

npm i -g verdaccio

We can spawn and use it directly, or we can use the @nx/js package which provides better integration:

npx nx g @nx/js:setup-verdaccio
npx nx local-registry

After installation, we simply need to start the local-registry task that was created during setup. When we run nx release, it will publish to our local registry. In the default configuration, a local temporary folder is created where we can easily verify the generated artifacts.

We are now publishing all artifacts with the same version, which could be a valid strategy. However, this approach might not fit our needs if we want to deploy packages independently.

Nx has this covered. By default, the property projectsRelationship is set to "fixed," meaning all packages will be deployed with a version bump regardless of changes. When set to "independent" instead, packages can be released at their own pace.

  "release": {
    "projectsRelationship": "independent"
  }

Now we can scope the release command with the desired project

 nx release -p core

Changelogs

As mentioned above, Nx can generate a changelog based on our git commits. To fully utilize this feature, we can instruct Nx to use conventional commits. If that patterns fit to your company we can configure nx how to bump the sem version for us.

Here is an example where commits labeled as "docs" should not increase our semantic version, and "chore" commits should be hidden from the changelog generation.

  "release": {
    "projectsRelationship": "independent",
     "changelog": {
      "projectChangelogs": true,
      "workspaceChangelogs": true
    },
    "conventionalCommits": {
      "types": {
        "docs": {
          "semverBump": "none"
        },
        "chore": {
          "changelog": false
        }
      }
    }
  }

Let's add a change to the core project and create a commit message:

git commit -am 'feat(core): awesome new feature'

CleanShot 2025-02-08 at 16.01.36@2x.png

When we run nx release, it generates a change log for our core package containing the commit message.

NX offers much more than what we've covered here, including advanced features like custom tag schemas, build script customization, and comprehensive release management capabilities. These tools empower teams to create sophisticated deployment strategies tailored to their specific needs.

By automating the complex process of managing shared libraries in a monorepo, NX not only saves valuable development time but also ensures consistency and reliability in your deployment pipeline.

For those interested in exploring these concepts further and sharing different perspectives, we regularly host workshops diving deep into these architectural patterns.

The post NX Release – The NPM Butler appeared first on ANGULARarchitects.


Viewing all articles
Browse latest Browse all 32

Trending Articles