Nx 16.8 Release!!!

Zack DeRose - Sep 6 '23 - - Dev Community

As always, the Nx Team has been hard at work, and we're here to launch our latest release: Nx 16.8! And it's absolutely bursting with new features. We'll go into all these in depth below, but be sure to check out our latest release video on YouTube!

If you have more questions - be sure to stop by our latest Nx Live to ask them there! You can sign up for a notification from the link below!

Nx Community News!

Before we jump into the features, be sure to get plugged in to get the most out of Nx in our NEW discord server!

Be sure to checkout our livestream with Jay Bell (Nx Champion, former Nx Community Slack admin, and current Nx Discord Admin) all about the news:

Nx is also coming up on 20k Github stars please help us get there!

Closing in on 20k stars!

NEW PROJECT GENERATOR BEHAVIOR: Project Creation Paths and Names in Nx Generators

Alright, getting into the newest updates from Nx, the biggest change is coming in the form of Nx project generators.

Originally, all Nx workspaces had a directory structure where applications were always held in an apps/ directory, while libraries were held in the libs/ directory.

Over the years, we found this to be much too rigid, so we made these locations more configurable. We added a workspaceLayout category to the nx.json file, where you could set appDir and libDir options to customize the names of these directories.

We also simplified the definition of Nx projects to be any directory that had a project.json file in it, allowing for the ability to nest projects in your filesytem and also forego app or lib directories altogether!

With Nx 16.8, we're introducing an all-new option in this workspaceLayout category: projectNameAndRootFormat where you can chose either the option to apply project names as-provided or derived.

projectNameAndRootFormat options

If you don't set this option in your nx.json file, our generators will now prompt you as to how we should set:

  • the name of your project (as in the project's project.json file)
  • where to put the project in your filesystem

as provided vs. derived

You can avoid the extra prompt above by setting the projectNameAndRootFormat in the workspaceLayout category of your nx.json file, or by providing it in in your generate command:

> nx g app my-app --projectNameAndRootFormat=as-provided
Enter fullscreen mode Exit fullscreen mode

This will change some of the default behaviors of our generators and for new Nx workspaces. By default, new workspaces will be set to as-provided, so longtime Nx users might notice that if they create a new workspace and start generating apps or libs, that they will now get generated at the root of the workspace instead of inside the apps/ or libs/ directory like they used to.

To get the legacy behavior, be sure to change the projectNameAndRootFormat to derived and/or use the name option to set the name of the project, and the directory option to set the full path of the target directory for your new projects:

> nx g app --name=my-app --directory=apps/my-app
Enter fullscreen mode Exit fullscreen mode

Packaging TypeScript Libraries - Secondary Entrypoints, ESM, CJS

Nx has always had first-class TypeScript support from the very beginning. You never really had to worry about Type Definition files being properly included or setting up TS support in the first place. But there are some aspects that can be tricky, like defining and properly exporting secondary entry points or packaging in multiple formats (ESM and CJS). That's why we did some research to help make it easier.

The package.json format supports an export field which is a modern alternative to the main property, allowing to have multiple such entry points.

{
  "exports": {
    "./package.json": "./package.json",
    ".": "./src/index.js",
    "./foo": "./src/foo.js",
    "./bar": "./src/bar.js"
  }
}
Enter fullscreen mode Exit fullscreen mode

To make it easier to maintain these, we've added two new options to the @nx/js package: additionalEntryPoints and generateExportsField. Here's an example:

// packages/my-awesome-lib/project.json
{
  "name": "my-awesome-lib",
  "targets": {
    "build": {
      "executor": "@nx/js:tsc",
      ...
      "options": {
        "main": "packages/my-awesome-lib/src/index.ts",
        ...
        "additionalEntryPoints": ["packages/my-awesome-lib/src/foo.ts"],
        "generateExportsField": true
      },
    },
    ...
  }
}
Enter fullscreen mode Exit fullscreen mode

When building the library, the @nx/js:tsc executor automatically adds the correct exports definition to the resulting package.json.

This makes it easy to maintain the exports field, something that becomes even more relevant if we want to add add multiple formats. By switching to the @nx/rollup:rollup executor, we can also add the format option and define esm and cjs as the target formats we want to have. Note we still keep the additionalEntryPoints and generateExportsField.

// packages/my-awesome-lib/project.json
{
  "name": "my-awesome-lib",
  "targets": {
    "build": {
      "executor": "@nx/rollup:rollup",
      ...
      "options": {
        "main": "packages/my-awesome-lib/src/index.ts",
        ...
        "format": ["esm", "cjs"],
        "additionalEntryPoints": ["packages/my-awesome-lib/src/foo.ts"],
        "generateExportsField": true
      },
    },
    ...
  }
}
Enter fullscreen mode Exit fullscreen mode

After compiling our package using nx build my-awesome-lib we'll get the following output in our dist folder.

my-awesome-lib
└─ .
   ├─ README.md
   ├─ foo.cjs.d.ts
   ├─ foo.cjs.js
   ├─ foo.esm.js
   ├─ index.cjs.d.ts
   ├─ index.cjs.js
   ├─ index.esm.js
   ├─ package.json
   └─ src
      ├─ foo.d.ts
      ├─ index.d.ts
      └─ lib
         └─ my-awesome-lib.d.ts
Enter fullscreen mode Exit fullscreen mode

And our package.json will look as follows:

{
  "name": "my-awesome-lib",
  "version": "0.0.1",
  ...
  "type": "commonjs",
  "main": "./index.cjs.js",
  "typings": "./src/index.d.ts",
  "exports": {
    "./package.json": "./package.json",
    ".": {
      "import": "./index.esm.js",
      "default": "./index.cjs.js"
    },
    "./foo": {
      "import": "./foo.esm.js",
      "default": "./foo.cjs.js"
    }
  },
  "module": "./index.esm.js"
}

Enter fullscreen mode Exit fullscreen mode

High Performance TypeScript Compilation: Introducing Batch Mode & Rust-based Dependency Resolution

Speed is in our DNA! And TypeScript compilation can be slow which is mostly due to tsc being a costly operation. You feel this in particular in a monorepo where you have multiple projects that are being compiled independently, thus launching dozens of processes of the tsc compiler.

To help with this, the TypeScript team introduced Project References which performs incremental compilation by caching intermediate results. However this comes with some caveats you need to be aware of and it can be intense to maintain by hand on a large codebase.

We wanted to make it transparent though and not something the user needs to worry about. That's why we introduced "Batch Mode". Batch mode is still experimental, and you can enable it for any project using the @nx/js:tsc executor by adding the environment variable NX_BATCH_MODE=true:

> NX_BATCH_MODE=true nx run-many --target=build
Enter fullscreen mode Exit fullscreen mode

When enabling batch mode, Nx leverages the underlying project graph to generate TypeScript project references behind the scenes for you, to fully leverage TS incremental building. The results are amazing. According to our benchmarks, batch mode has the potential to speed up Typescript compilation by up to 5x for large monorepos.

Typescript Batchmode Support

In addition to batch mode, the processing of Typescript dependencies is now using a faster and more accurate Rust implementation. This should be transparent to most users - aside from your monorepo becoming even faster!

NEW Nx PLUGIN: Playwright

A new Nx plugin has appeared!!

New Nx Plugin: Playwright

Nx now supports Playwright as an e2e option alongside our long-standing support for Cypress!

First off, this means we've added Playwright as an option when generating new frontend applications:

e2e options

If you want to add playwright to an existing project in your workspace you can also do that now by installing the plugin (here using npm):

npm add -D @nx/playwright
Enter fullscreen mode Exit fullscreen mode

Then running our new generator to add playwright to your project (here I'm adding it to my application called my-app):

nx g @nx/playwright:configuration --project=my-app
Enter fullscreen mode Exit fullscreen mode

This will setup playwright for you, and add an e2e target to your project using playwright!

NEW INTEGRATION: Netlify's Improved Monorepo Experience

On Netlify's enterprise tier, approximately 46% of builds are monorepos, with the majority leveraging Nx and Lerna. Recognizing this trend, Netlify has focused on enhancing the setup and deployment experiences for monorepo projects. In particular they worked on an "automatic monorepo detection" feature. When you connect your project to GitHub, Netlify automatically detects if it's part of a monorepo, reads the relevant settings, and pre-configures your project. This eliminates the need for manual setup. This feature also extends to local development via the Netlify CLI.

Juri Strumpflohner from the Nx team sits down with Lukas Holzer from Netlify to discuss what monorepos are, when you might need them, their challenges and benefits, and the tooling support Nx provides. But it's not just talk; they also walk you through setting up a new Nx monorepo, adding Netlify Edge functions, and deploying it all to Netlify—both via the website and locally through the newly improved Netlify CLI.

If you prefer the blog post, check out "Elevating enterprise deployment: Introducing an enhanced monorepo experience on Netlify" on the Netlify blog.

NEW Nx CONSOLE FEATURE: Interactive Graph Functionality

If you're not familiar - Nx Console is our IDE enhancement for VsCode (1.4 million installations!!) and JetBrains Products (Intellij/WebStorm/etc - 52 thousand downloads!).

Nx Console provides a Graphical User Interface for running tasks and generating code for your Nx Monorepos, and it also provides the ability to view your project graph

Nx Project Graph

and task graph

Nx Task Graph

within your IDE!

As of our latest release, Nx Console has added the new feature of adding buttons inside the project graph to take you directly to the selected project in the project graph:

Button on Project Graph

And gives you a "play button" to run any task within your task graph:

Button on Task Graph

ENHANCEMENT: Storybook Support for Interaction Testing

Storybook 7 introduces new Interaction Testing to their platform!

Storybook Interaction Testing

The Nx Storybook plugin has now been enhanced with a new interactionTests option on the storybook-configuration generator, that will automate setting up these interaction tests for you when you use Nx to generate stories for your components!

You can checkout everything about Storybook Interaction tests and our Nx support for it in this video:

Nx has always provided similar functionality via our Storybook + Cypress integrations, where you can setup cypress tests to test your storybook showcases, and while you can use interaction testing to replace this integration, we will continue to support our Storybook + Cypress integrations going forward!

NEW GENERATOR: convert-to-monorepo

Towards the start of the year, we added support for Nx standalone applications. These were designed as a way of using Nx features in a way where you didn't need to opt into a monorepo setup.

Ever since we introduced these, we've had requests from the community to add a generator to convert your standalone workspace to a monorepo setup - to support repos that grew to emcompass more than just the 1 application.

This is where our new convert-to-monorepo generator comes into play!

> nx g convert-to-monorepo
Enter fullscreen mode Exit fullscreen mode

This will identify all library projects in currently in your repo and place them in the libs/ directory that you might expect of a typical Nx monorepo. It will also hoist your application project from the root of your workspace into the apps/ directory.

When all is said and done, you should be able to now add additional applications to your repo now!

DOCS ENHANCEMENT: Third-Party Plugin Quality Indicators

One of the great things about Nx is the extensibility, and the wide range of plugins that are available for supporting languages, frameworks, and tools that the core Nx team does not directly support.

Our docs site has hosted a registry of these plugins for awhile now, but we've recently added npm downloads, github stars, release dates, and compatible Nx versions to this registry:

Nx Plugin Registry Example

We expect that these will be valuable signals to users as to the quality of the plugin.

We've also added the ability to sort the registry by these metrics as a way of surfacing the higher quality plugins to the top!

Nx Registry Sorting Options

Go check it out now live on our docs site!

DOCS ENHANCEMENT: Redesigned Intro & Examples

Our mission to improve Nx docs continues: this edition with some major updates to our Docs intro page.

We improved the messaging around Nx and more prominently emphasizing the core features that distinguish Nx from other tools out there. We also linked a new "What is Nx" video. You should check it out 🐐

The core part of the intro page now has a dedicated section for "Learning Nx", surfacing some of our Nx, Nx Cloud and Monorepo videos as well as our in-depth tutorial about monorepos and single-project Nx workspaces. And we already have more in the works, so stay tuned.

Learn Nx Examples

We're also proud of all the new examples we've added in the last months. We have a brand new Nx Recipe repo with a variety of example projects that showcase Nx in combination with different technologies, even outside the JS ecosystem (e.g. with Rust, Go and .Net).

Go pick the ones you're most interested in!

Pick your stack

You can find all of the examples and more on our "Showcase" section: https://nx.dev/showcase.

NEW GENERATOR: ESLint Flat Config

ESLint has announced a new config system - nicknamed "flat config" - whose intent is to be be familiar and much simpler than the current config system. You can read more about this in their blog post.

As part of our continued support for ESLint, we've introduced a new generator to convert your Nx monorepo to this new system:

> nx g convert-to-flat-config
Enter fullscreen mode Exit fullscreen mode

Flat config is still experimental, so you can use this as a way of easily previewing the new config system now. Just be sure not to mix the original configuration with this new configuration system!

New Nx Cloud Overview Video

We've been working hard on our premium product: Nx Cloud, and part of that has been this awesome video from our own Rares Matei on what exactly Nx Cloud is!

Be sure to checkout the Nx Cloud landing site for more details on all the additional features you unlock with the power of the cloud!

Nx Conf Coming Up

Last but definitely not least, Nx Conf 2023 is fast approaching! We'll be coming to you live from New York City on September 26!

Be sure to register to attend online FOR FREE and be sure to checkout our lineup of talks and speakers!

Wrap Up

That's all for now folks! We're just starting up a new iteration of development on Nx, so be sure to subscribe to our YouTube channel to get updates when new features land! Until next time, KEEP WORKING HARD!

Learn more

More Nx Release Notes:

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .