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,pnpm
Create 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"
--standalone
Create Angular Library
Demo
Create Angular App
Create Angular App
npx nx generate @nx/angular:app apps/playground
Create 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-point
Entry Points
Demo
Custom Plugins
Custom Plugins
npx ng add <name-of-library>
Custom Plugins
npm i -D @nx/plugin
Custom Plugins
npx nx generate @nx/plugin:plugin libs/plugin
Custom Plugins
npx nx generate @nx/plugin:generator
Custom 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-application
https://angular.dev/tools/libraries/creating-libraries/
Angular CLI
ng new my-workspace --no-create-application
Angular CLI
ng new my-workspace --no-create-application
cd my-workspace
Angular CLI
ng new my-workspace --no-create-application
cd my-workspace
ng generate library my-library
Angular CLI
ng build my-library
Angular 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 test
CLI
Nx
Monorepo
nx build
nx serve
nx test
CLI
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 later
Nx
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
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/angular
Nx
npx nx generate @nx/angular:library my-library
Nx
npx nx generate @nx/angular:library my-library --help
Nx
npx nx generate @nx/angular:library my-library
--publishable
--import-path=my-library
Nx
npx nx generate @nx/angular:library my-library
--publishable
--import-path=@my-library/core
Nx
npx nx generate @nx/angular:library my-library
--publishable
--import-path=my-library
Nx
npx nx generate @nx/angular:library my-library
--publishable
--import-path=my-library
--unit-test-runner=jest
Nx
npx nx generate @nx/angular:library my-library
--publishable
--import-path=my-library
--unit-test-runner=jest
--directory=libs/my-library
Nx
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-library
Nx
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-library
Nx
Secondary Entry Points
npx nx generate @nx/angular:entry-point first-entry-point
--library=my-library
Nx
Secondary Entry Points
npx nx build my-library
Nx
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 graph
Nx
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-library
Nx
Secondary Entry Points
npx nx generate @nx/angular:entry-point first-entry-point
--library=my-library
the plugin name
Nx
Secondary Entry Points
npx nx generate @nx/angular:entry-point first-entry-point
--library=my-library
the generator
Nx
Secondary Entry Points
npx nx generate my-workspace-plugin:entry-point first-entry-point
--library=my-library
What if?
Nx
Secondary Entry Points
npm i --save-dev @nx/plugin
Nx
Secondary Entry Points
npx nx generate plugin my-workspace-plugin
--directory=libs/my-workspace-plugin
Nx
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-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 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-project
Nx
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-point
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
Nx
Secondary Entry Points
npx nx graph --affected
Nx
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 starlight
Nx
Applications
An application for your documentation
Nx
Applications
An application for your documentation
Nx
Applications
An application for your documentation
npx nx dev docs
Nx
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-plugin
Nx
Schematics
npx nx generate plugin my-plugin --directory=libs/my-plugin
npx nx generate generator init
--project=my-plugin
--directory=libs/my-plugin/src/generators/init
Nx
Schematics
npx nx generate plugin my-plugin --directory=libs/my-plugin
npx nx generate generator init
--project=my-plugin
--directory=libs/my-plugin/src/generators/init
Nx
Schematics
touch libs/my-plugin/src/generators/init/compat.ts
Nx
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-point
Nx
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-releast
Nx
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 ngxtension
nx g @nx/plugin:plugin local-plugin
nx g @nx/plugin:plugin plugin
Structure
nx g @nx/angular:lib ngxtension
nx g @nx/plugin:plugin local-plugin
nx g @nx/plugin:plugin plugin
nx g @nx/plugin:plugin local-plugin
Structure
nx g @nx/angular:lib ngxtension
nx g @nx/plugin:plugin local-plugin
nx g @nx/plugin:plugin plugin
nx g @nx/plugin:plugin local-plugin
npm create astro --template=starlight
Structure
Structure
nx g @nx/angular:entry-point
Structure
nx g @nx/angular:entry-point
Thank you
nx angular library
By Chau Tran
nx angular library
- 260