today, we're going to talk about library and Nx (...and much more)
What is Nx?
What is Nx?
A task runner
What is Nx?
A task runner
that can orchestrates and executes tasks efficiently
What is Nx?
A task runner
that can orchestrates and executes tasks efficiently
What is Nx?
A task runner
that can orchestrates and executes tasks efficiently
because it knows about your projects
What is Nx?
It is also a collection of tools
What is Nx?
It is also a collection of tools

Disclaimers
...or pre-talk FAQ
Disclaimers
...or pre-talk FAQ
1. The demo is in Nx 19. What about Nx 20?
Disclaimers
...or pre-talk FAQ
1. The demo is in Nx 19. What about Nx 20?
2. The demo uses Angular. Why?

Libraries with Nx




Angular Libraries w/ Nx

Chau Tran
twitter.com/@nartc1410
github.com/nartc
Agenda
- Create an Nx Workspace
- Create an Angular library
- Create a playground application
- Entry Points
- Custom Plugin
- Release
- Optimize the library workspace
- Documentations
Create Nx Workspace
Create Nx Workspace
npx create-nx-workspace <name_of_workspace>Create Nx Workspace
npx create-nx-workspace <name_of_workspace>
--package-manager=npm,yarn,pnpmCreate Nx Workspace
npx create-nx-workspace <name_of_workspace>
Create Nx Workspace

Create Nx Workspace
npm i -D @nx/angular
Create Angular Library
Create Angular Library
npx nx generate @nx/angular:library libs/core
--publishable
--import-path="@js-day-demo/core"
--standaloneCreate Angular Library
Demo
Create Angular App
Create Angular App
npx nx generate @nx/angular:app apps/playgroundCreate Angular App
Demo
Entry Points
Entry Points
@angular/core
Entry Points
@angular/core
@angular/core/testing
Entry Points
@angular/core
@angular/core/testing
https://unpkg.com/browse/msw@2.5.1/package.json
Entry Points
npx nx generate @nx/angular:entry-pointEntry Points
Demo
Custom Plugins
Custom Plugins
npx ng add <name-of-library>Custom Plugins
npm i -D @nx/pluginCustom Plugins
npx nx generate @nx/plugin:plugin libs/pluginCustom Plugins
npx nx generate @nx/plugin:generatorCustom Plugins
Demo
Release
Release
A smart release tool because it has information about the Project Graph
Release
Demo
Optimize the Workspace
Demo
Conclusion
Agenda
- Angular library
- Angular CLI
- Nx
- Example
Angular Library
Angular Library
Angular Library
Angular Package Format
Angular Library
https://angular.dev/tools/libraries/angular-package-format

Angular Library
Ensure seamless integration with other tools
Angular Library
Ensure seamless integration with other tools
Secondary Entry Points
Angular Library
Ensure seamless integration with other tools
Secondary Entry Points
@angular/core -- @angular/core/testing
@angular/material -- @angular/material/button
Angular Library
Ensure seamless integration with other tools
Secondary Entry Points
Optimization w/ Partial Compilation
Angular Library
Ensure seamless integration with other tools
Secondary Entry Points
Optimization w/ Partial Compilation

Angular Library
Ensure seamless integration with other tools
Secondary Entry Points
Optimization w/ Partial Compilation
Angular Library
Ensure seamless integration with other tools
Secondary Entry Points
Optimization w/ Partial Compilation
Angular Library

Angular CLI
Angular CLI

Angular CLI
ng new my-workspace --no-create-applicationhttps://angular.dev/tools/libraries/creating-libraries/
Angular CLI
ng new my-workspace --no-create-application
Angular CLI
ng new my-workspace --no-create-applicationcd my-workspaceAngular CLI
ng new my-workspace --no-create-applicationcd my-workspaceng generate library my-library
Angular CLI
ng build my-libraryAngular CLI
ng build my-library
Angular CLI

Angular CLI
Secondary Entry Points
Angular CLI
karma
Angular CLI
karma

Angular CLI
Scalability
Angular CLI
Scalability

Angular CLI
Other details like docs, storybook, e2e ...
Angular CLI
Schematics
Angular CLI

Angular CLI

Nx
Nx
Nx

Monorepo
Nx

Monorepo
nx build
nx serve
nx testCLI
Nx

Monorepo
nx build
nx serve
nx testCLI


Performance
Nx
Nx
npx create-nx-workspace@latest my-nx-workspace
Nx
npx create-nx-workspace@latest my-nx-workspace
--preset=apps # we'll set up Angular laterNx
npx create-nx-workspace@latest my-nx-workspace
--preset=apps # we'll set up Angular later
--workspace-type=integrated # we'll use apps/libs conventionNx
npx create-nx-workspace@latest my-nx-workspace
--preset=apps # we'll set up Angular later
--workspace-type=integrated # we'll use apps/libs convention
Nx
npm install --save-dev @nx/angularNx
npx nx generate @nx/angular:library my-libraryNx
npx nx generate @nx/angular:library my-library --helpNx
npx nx generate @nx/angular:library my-library
--publishable
--import-path=my-libraryNx
npx nx generate @nx/angular:library my-library
--publishable
--import-path=@my-library/coreNx
npx nx generate @nx/angular:library my-library
--publishable
--import-path=my-libraryNx
npx nx generate @nx/angular:library my-library
--publishable
--import-path=my-library
--unit-test-runner=jestNx
npx nx generate @nx/angular:library my-library
--publishable
--import-path=my-library
--unit-test-runner=jest
--directory=libs/my-libraryNx
npx nx generate @nx/angular:library my-library
--publishable
--import-path=my-library
--unit-test-runner=jest
--directory=libs/my-library
Nx
npx nx test my-libraryNx
npx nx test my-library
Nx
npx nx test my-library

Nx
Secondary Entry Points
Nx
Secondary Entry Points
npx nx generate @nx/angular:entry-point first-entry-point
--library=my-libraryNx
Secondary Entry Points
npx nx generate @nx/angular:entry-point first-entry-point
--library=my-library
Nx
Secondary Entry Points
npx nx build my-libraryNx
Secondary Entry Points
npx nx build my-library
Nx
Secondary Entry Points
npx nx build my-library
Nx
Secondary Entry Points

Nx
Secondary Entry Points

Nx
Secondary Entry Points


Nx
Secondary Entry Points
npx nx graphNx
Secondary Entry Points
npx nx graph
Nx
Secondary Entry Points

Nx
Secondary Entry Points
Each entry point should be a Nx "project"
Nx
Secondary Entry Points
Each entry point should be a Nx "project"
with their own lint and test targets
Nx
Secondary Entry Points
Nx
Secondary Entry Points
Nx
Secondary Entry Points

Nx
Secondary Entry Points

Nx
Secondary Entry Points
npx nx generate @nx/angular:entry-point first-entry-point
--library=my-libraryNx
Secondary Entry Points
npx nx generate @nx/angular:entry-point first-entry-point
--library=my-librarythe plugin name
Nx
Secondary Entry Points
npx nx generate @nx/angular:entry-point first-entry-point
--library=my-librarythe generator
Nx
Secondary Entry Points
npx nx generate my-workspace-plugin:entry-point first-entry-point
--library=my-libraryWhat if?
Nx
Secondary Entry Points
npm i --save-dev @nx/pluginNx
Secondary Entry Points
npx nx generate plugin my-workspace-plugin
--directory=libs/my-workspace-pluginNx
Secondary Entry Points
npx nx generate plugin my-workspace-plugin
--directory=libs/my-workspace-plugin
Nx
Secondary Entry Points
npx nx generate generator entry-point
--project=my-workspace-plugin
--directory=libs/my-workspace-plugin/src/generators/entry-pointNx
Secondary Entry Points
npx nx generate generator entry-point
--project=my-workspace-plugin
--directory=libs/my-workspace-plugin/src/generators/entry-point
Nx
Secondary Entry Points
npx nx generate generator entry-point
--project=my-workspace-plugin
--directory=libs/my-workspace-plugin/src/generators/entry-point
Nx
Secondary Entry Points
npx nx generate generator convert-to-project
--project=my-workspace-plugin
--directory=libs/my-workspace-plugin/src/generators/convert-to-projectNx
Secondary Entry Points
Project == project.json exists
Nx
Secondary Entry Points
export async function convertToProjectGenerator(
tree: Tree,
options: ConvertToProjectGeneratorSchema
) {
await formatFiles(tree);
}
export default convertToProjectGenerator;
Nx
Secondary Entry Points
export async function convertToProjectGenerator(
tree: Tree,
options: ConvertToProjectGeneratorSchema
) {
const projectRoot = `libs/my-library/${options.name}`;
if (!tree.exists(projectRoot)) {
return logger.error(`Entry point ${options.name} does not exist`);
}
const isProjectJsonExist = tree.exists(`${projectRoot}/project.json`);
if (isProjectJsonExist) {
return logger.info(`Entry point ${options.name} is already a Project`);
}
await formatFiles(tree);
}
export default convertToProjectGenerator;
Nx
Secondary Entry Points
export async function convertToProjectGenerator(
tree: Tree,
options: ConvertToProjectGeneratorSchema
) {
const projectRoot = `libs/my-library/${options.name}`;
if (!tree.exists(projectRoot)) {
return logger.error(`Entry point ${options.name} does not exist`);
}
const isProjectJsonExist = tree.exists(`${projectRoot}/project.json`);
if (isProjectJsonExist) {
return logger.info(`Entry point ${options.name} is already a Project`);
}
const projectConfiguration = readProjectConfiguration(tree, 'my-library');
addProjectConfiguration(tree, `my-library/${options.name}`, {
root: projectRoot,
projectType: 'library',
sourceRoot: `${projectRoot}/src`,
targets: {
test: {
executor: '@nx/jest:jest',
outputs: [`{workspaceRoot}/coverage/{projectRoot}/${options.name}`],
options: {
jestConfig: `${projectConfiguration.root}/jest.config.ts`,
testPathPattern: [options.name],
passWithNoTests: true,
},
},
lint: {
executor: '@nx/eslint:lint',
outputs: ['{options.outputFile}'],
},
},
});
await formatFiles(tree);
}
export default convertToProjectGenerator;
Nx
Secondary Entry Points
import {librarySecondaryEntryPointGenerator} from '@nx/angular/generators';
import {formatFiles, Tree,} from '@nx/devkit';
import convertToProjectGenerator from "../convert-to-project/generator";
import {EntryPointGeneratorSchema} from './schema';
export async function entryPointGenerator(
tree: Tree,
options: EntryPointGeneratorSchema
) {
await librarySecondaryEntryPointGenerator(tree, {
name: options.name,
library: 'my-library'
});
await convertToProjectGenerator(tree, {
name: options.name
})
await formatFiles(tree);
}
export default entryPointGenerator;
Nx
Secondary Entry Points

Nx
Secondary Entry Points

Nx
Secondary Entry Points

Nx
Secondary Entry Points
npx nx generate convert-to-project first-entry-point
npx nx generate convert-to-project second-entry-pointNx
Secondary Entry Points

Nx
Secondary Entry Points

Nx
Secondary Entry Points

Nx
Secondary Entry Points


Nx
Secondary Entry Points



Nx
Secondary Entry Points


Nx
Secondary Entry Points



Nx
Secondary Entry Points

Nx
Secondary Entry Points

Nx
Secondary Entry Points
npx nx graph --affectedNx
Secondary Entry Points
npx nx graph --affected
Nx
Secondary Entry Points

Nx
Secondary Entry Points


Nx
Secondary Entry Points

Nx
Secondary Entry Points
Nx
Applications
Nx
Applications
Nx
Applications
Application to test your UI components
Nx
Applications
Application to test your UI components
An e2e application to test your test application
Nx
Applications
Application to test your UI components
An e2e application to test your test application

Nx
Applications
Application to test your UI components
An e2e application to test your test application
An application for your documentation
Nx
Applications
Application to test your UI components
An e2e application to test your test application
Nx
Applications
Application to test your UI components
An e2e application to test your test application
npx nx generate app test-app
--directory=apps/test-app
--bundler=esbuild
--e2e-test-runner=playwright
--style=css # you can pick whatever
# --...other options...Nx
Applications
Application to test your UI components
An e2e application to test your test application

Nx
Applications
Application to test your UI components
An e2e application to test your test application

Nx
Applications
Application to test your UI components
An e2e application to test your test application


Nx
Applications
An application for your documentation
Nx
Applications
An application for your documentation

https://starlight.astro.build/
Nx
Applications
An application for your documentation
npm create astro@latest -- --template starlightNx
Applications
An application for your documentation

Nx
Applications
An application for your documentation

Nx
Applications
An application for your documentation
npx nx dev docsNx
Applications
An application for your documentation
npx nx dev docs
Nx
Applications
An application for your documentation
npx nx dev docs

Nx
Schematics
Nx
Schematics
ng add, ng update
Nx
Schematics
Nx
Schematics
npx nx generate plugin my-plugin --directory=libs/my-pluginNx
Schematics
npx nx generate plugin my-plugin --directory=libs/my-pluginnpx nx generate generator init
--project=my-plugin
--directory=libs/my-plugin/src/generators/initNx
Schematics
npx nx generate plugin my-plugin --directory=libs/my-pluginnpx nx generate generator init
--project=my-plugin
--directory=libs/my-plugin/src/generators/initNx
Schematics
touch libs/my-plugin/src/generators/init/compat.tsNx
Schematics
touch libs/my-plugin/src/generators/init/compat.ts
Nx
Schematics
{
"generators": {
"init": {
"factory": "./src/generators/init/generator",
"schema": "./src/generators/init/schema.json",
"description": "init generator"
}
}
}
Nx
Schematics
{
"generators": {
"init": {
"factory": "./src/generators/init/generator",
"schema": "./src/generators/init/schema.json",
"description": "init generator"
}
},
"schematics": {
"ng-add": {
"factory": "./src/generators/init/compat",
"schema": "./src/generators/init/schema.json",
"description": "Init generator"
}
}
}
Nx
Schematics
npx nx generate migration rename-first-entry-point
--project=my-plugin
--directory=libs/my-plugin/src/migrations/rename-first-entry-pointNx
Schematics
npx nx generate migration rename-first-entry-point
--project=my-plugin
--directory=libs/my-plugin/src/migrations/rename-first-entry-point
Nx
Schematics
{
"name": "my-plugin",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/my-plugin/src",
"projectType": "library",
"tags": [],
"targets": {
"build": {
"executor": "@nx/js:tsc",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/libs/my-library",
...
}
},
"test": {
...
}
}
}
Nx
Schematics
{
"name": "my-plugin",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/my-plugin/src",
"projectType": "library",
"tags": [],
"targets": {
"build": {
"executor": "@nx/js:tsc",
"outputs": ["{options.outputPath}"],
"options": {
"outputPath": "dist/libs/my-library/plugin",
...
}
},
"test": {
...
}
}
}
Nx
Schematics
{
"name": "my-library",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^17.3.0",
"@angular/core": "^17.3.0"
},
"sideEffects": false
}
Nx
Schematics
{
"name": "my-library",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^17.3.0",
"@angular/core": "^17.3.0"
},
"sideEffects": false,
"generators": "./plugin/generators.json",
"schematics": "./plugin/generators.json",
"nx-migrations": {
"migrations": "./plugin/migrations.json"
},
"ng-update": {
"migrations": "./plugin/migrations.json"
}
}
Nx
Schematics
{
"name": "my-library",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/my-library/src",
"prefix": "lib",
"projectType": "library",
"tags": [],
"targets": {
"build": {
...
},
"test": {
...
},
"lint": {
...
}
}
}
Nx
Schematics
{
"name": "my-library",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/my-library/src",
"prefix": "lib",
"projectType": "library",
"tags": [],
"targets": {
"package": {
"executor": "nx:run-commands",
"options": {
"commands": [
"nx build my-library",
"nx build my-plugin"
],
"parallel": false
}
},
"build": {
...
},
"test": {
...
},
"lint": {
...
}
}
}
Nx
Schematics

Nx
Release
Nx
Release
{
...,
"release": {
"projects": [
"my-library"
],
"version": {
"preVersionCommand": "nx package my-library"
},
"releaseTagPattern": "{version}",
"conventionalCommits": {}
}
}Nx
Release
{
...,
"release": {
"version": {
"generatorOptions": {
"packageRoot": "dist/{projectRoot}",
"currentVersionResolver": "git-tag"
}
}
},
"targets": {...}
}Nx
Release
npx nx release --first-releastNx
Release
npx nx release --first-releast
Nx
Release
npx nx release --first-releast
Nx
Release
npx nx release --first-releast

https://monorepo.tools/conf

https://monorepo.tools/conf

https://github.com/ngxtension/ngxtension-platform

Structure

Structure
nx g @nx/angular:lib ngxtension
Structure
nx g @nx/angular:lib ngxtensionnx g @nx/plugin:plugin local-pluginnx g @nx/plugin:plugin plugin
Structure
nx g @nx/angular:lib ngxtensionnx g @nx/plugin:plugin local-pluginnx g @nx/plugin:plugin pluginnx g @nx/plugin:plugin local-plugin
Structure
nx g @nx/angular:lib ngxtensionnx g @nx/plugin:plugin local-pluginnx g @nx/plugin:plugin pluginnx g @nx/plugin:plugin local-pluginnpm create astro --template=starlightStructure

Structure

nx g @nx/angular:entry-pointStructure

nx g @nx/angular:entry-pointThank you
nx angular library
By Chau Tran
nx angular library
- 467