Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fcfd75e46a |
@@ -4,176 +4,176 @@ version: 2.1
|
||||
# ORBS
|
||||
# -------------------------
|
||||
orbs:
|
||||
nx: nrwl/nx@1.6.2
|
||||
rust: circleci/rust@1.6.0
|
||||
browser-tools: circleci/browser-tools@1.4.8
|
||||
nx: nrwl/nx@1.6.2
|
||||
rust: circleci/rust@1.6.0
|
||||
browser-tools: circleci/browser-tools@1.4.8
|
||||
|
||||
# -------------------------
|
||||
# EXECUTORS
|
||||
# -------------------------
|
||||
|
||||
defaults: &defaults
|
||||
working_directory: ~/repo
|
||||
working_directory: ~/repo
|
||||
|
||||
executors:
|
||||
linux:
|
||||
<<: *defaults
|
||||
docker:
|
||||
- image: cimg/rust:1.73.0-browsers
|
||||
resource_class: medium+
|
||||
linux:
|
||||
<<: *defaults
|
||||
docker:
|
||||
- image: cimg/rust:1.73.0-browsers
|
||||
resource_class: medium+
|
||||
|
||||
macos:
|
||||
<<: *defaults
|
||||
resource_class: macos.m1.medium.gen1
|
||||
macos:
|
||||
xcode: '14.2.0'
|
||||
macos:
|
||||
<<: *defaults
|
||||
resource_class: macos.m1.medium.gen1
|
||||
macos:
|
||||
xcode: '14.2.0'
|
||||
|
||||
# -------------------------
|
||||
# COMMANDS
|
||||
# -------------------------
|
||||
commands:
|
||||
run-pnpm-install:
|
||||
parameters:
|
||||
os:
|
||||
type: string
|
||||
steps:
|
||||
- restore_cache:
|
||||
name: Restore pnpm Package Cache
|
||||
keys:
|
||||
- node-deps-{{ arch }}-v3-{{ checksum "pnpm-lock.yaml" }}
|
||||
- when:
|
||||
condition:
|
||||
equal: [<< parameters.os >>, linux]
|
||||
steps:
|
||||
- run:
|
||||
name: Install pnpm package manager (linux)
|
||||
command: |
|
||||
npm install --prefix=$HOME/.local -g @pnpm/exe@9.8.0
|
||||
- when:
|
||||
condition:
|
||||
equal: [<< parameters.os >>, macos]
|
||||
steps:
|
||||
- run:
|
||||
name: Install pnpm package manager (macos)
|
||||
command: |
|
||||
npm install -g @pnpm/exe@9.8.0
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm playwright install --with-deps
|
||||
- save_cache:
|
||||
name: Save pnpm Package Cache
|
||||
key: node-deps-{{ arch }}-v3-{{ checksum "pnpm-lock.yaml" }}
|
||||
paths:
|
||||
- ~/.pnpm-store
|
||||
- ~/.cache/Cypress
|
||||
- node_modules
|
||||
run-pnpm-install:
|
||||
parameters:
|
||||
os:
|
||||
type: string
|
||||
steps:
|
||||
- restore_cache:
|
||||
name: Restore pnpm Package Cache
|
||||
keys:
|
||||
- node-deps-{{ arch }}-v3-{{ checksum "pnpm-lock.yaml" }}
|
||||
- when:
|
||||
condition:
|
||||
equal: [<< parameters.os >>, linux]
|
||||
steps:
|
||||
- run:
|
||||
name: Install pnpm package manager (linux)
|
||||
command: |
|
||||
npm install --prefix=$HOME/.local -g @pnpm/exe@8
|
||||
- when:
|
||||
condition:
|
||||
equal: [<< parameters.os >>, macos]
|
||||
steps:
|
||||
- run:
|
||||
name: Install pnpm package manager (macos)
|
||||
command: |
|
||||
npm install -g @pnpm/exe@8
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: |
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm playwright install --with-deps
|
||||
- save_cache:
|
||||
name: Save pnpm Package Cache
|
||||
key: node-deps-{{ arch }}-v3-{{ checksum "pnpm-lock.yaml" }}
|
||||
paths:
|
||||
- ~/.pnpm-store
|
||||
- ~/.cache/Cypress
|
||||
- node_modules
|
||||
# -------------------------
|
||||
# JOBS
|
||||
# -------------------------
|
||||
jobs:
|
||||
# -------------------------
|
||||
# JOBS: Main Linux
|
||||
# -------------------------
|
||||
main-linux:
|
||||
executor: linux
|
||||
environment:
|
||||
NX_E2E_CI_CACHE_KEY: e2e-circleci-linux
|
||||
NX_DAEMON: 'true'
|
||||
NX_PERF_LOGGING: 'false'
|
||||
NX_NATIVE_LOGGING: 'false'
|
||||
NX_E2E_RUN_E2E: 'true'
|
||||
NX_CI_EXECUTION_ENV: 'linux'
|
||||
NX_CLOUD_DTE_V2: 'true'
|
||||
NX_CLOUD_DTE_SUMMARY: 'true'
|
||||
steps:
|
||||
- checkout
|
||||
- nx/set-shas:
|
||||
main-branch-name: 'master'
|
||||
- run: npx nx-cloud@next start-ci-run --distribute-on="auto linux-medium" --stop-agents-after="e2e"
|
||||
- run:
|
||||
command: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ca-certificates lsof libvips-dev libglib2.0-dev libgirepository1.0-dev
|
||||
- browser-tools/install-chrome
|
||||
- run-pnpm-install:
|
||||
os: linux
|
||||
- run:
|
||||
name: Check Documentation
|
||||
command: pnpm nx documentation --no-dte
|
||||
no_output_timeout: 20m
|
||||
- run:
|
||||
name: Run Checks/Lint/Test/Build
|
||||
no_output_timeout: 60m
|
||||
command: |
|
||||
pids=()
|
||||
# -------------------------
|
||||
# JOBS: Main Linux
|
||||
# -------------------------
|
||||
main-linux:
|
||||
executor: linux
|
||||
environment:
|
||||
NX_E2E_CI_CACHE_KEY: e2e-circleci-linux
|
||||
NX_DAEMON: 'true'
|
||||
NX_PERF_LOGGING: 'false'
|
||||
NX_NATIVE_LOGGING: 'false'
|
||||
NX_E2E_RUN_E2E: 'true'
|
||||
NX_CI_EXECUTION_ENV: 'linux'
|
||||
NX_CLOUD_DTE_V2: 'true'
|
||||
NX_CLOUD_DTE_SUMMARY: 'true'
|
||||
steps:
|
||||
- checkout
|
||||
- nx/set-shas:
|
||||
main-branch-name: 'master'
|
||||
- run: npx nx-cloud@next start-ci-run --distribute-on=".nx/workflows/dynamic-changesets.yaml" --stop-agents-after="e2e"
|
||||
- run:
|
||||
command: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ca-certificates lsof libvips-dev libglib2.0-dev libgirepository1.0-dev
|
||||
- browser-tools/install-chrome
|
||||
- run-pnpm-install:
|
||||
os: linux
|
||||
- run:
|
||||
name: Check Documentation
|
||||
command: pnpm nx documentation --no-dte
|
||||
no_output_timeout: 20m
|
||||
- run:
|
||||
name: Run Checks/Lint/Test/Build
|
||||
no_output_timeout: 60m
|
||||
command: |
|
||||
pids=()
|
||||
|
||||
pnpm nx-cloud record -- nx format:check --base=$NX_BASE --head=$NX_HEAD &
|
||||
pids+=($!)
|
||||
pnpm nx-cloud record -- nx format:check --base=$NX_BASE --head=$NX_HEAD &
|
||||
pids+=($!)
|
||||
|
||||
pnpm nx run-many -t check-imports check-commit check-lock-files check-codeowners documentation --parallel=1 --no-dte &
|
||||
pids+=($!)
|
||||
pnpm nx run-many -t check-imports check-commit check-lock-files check-codeowners documentation --parallel=1 --no-dte &
|
||||
pids+=($!)
|
||||
|
||||
pnpm nx affected --targets=lint,test,build,e2e,e2e-ci --base=$NX_BASE --head=$NX_HEAD --parallel=3 &
|
||||
pids+=($!)
|
||||
pnpm nx affected --targets=lint,test,build,e2e,e2e-ci --base=$NX_BASE --head=$NX_HEAD --parallel=3 &
|
||||
pids+=($!)
|
||||
|
||||
for pid in "${pids[@]}"; do
|
||||
wait "$pid"
|
||||
done
|
||||
# -------------------------
|
||||
# JOBS: Main-MacOS
|
||||
# -------------------------
|
||||
mainmacos:
|
||||
executor: macos
|
||||
environment:
|
||||
NX_E2E_CI_CACHE_KEY: e2e-circleci-macos
|
||||
NX_PERF_LOGGING: 'false'
|
||||
NX_CI_EXECUTION_ENV: 'macos'
|
||||
SELECTED_PM: 'npm' # explicitly define npm for macOS tests
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
name: Restore Homebrew packages
|
||||
keys:
|
||||
- nrwl-nx-homebrew-packages
|
||||
- run:
|
||||
name: Configure Detox Environment, Install applesimutils
|
||||
command: |
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install applesimutils >/dev/null
|
||||
xcrun simctl shutdown all && xcrun simctl erase all
|
||||
no_output_timeout: 20m
|
||||
- save_cache:
|
||||
name: Save Homebrew Cache
|
||||
key: nrwl-nx-homebrew-packages
|
||||
paths:
|
||||
- /usr/local/Homebrew
|
||||
- ~/Library/Caches/Homebrew
|
||||
- run-pnpm-install:
|
||||
os: macos
|
||||
- rust/install
|
||||
- nx/set-shas:
|
||||
main-branch-name: 'master'
|
||||
- run:
|
||||
name: Run E2E Tests for macOS
|
||||
command: |
|
||||
HAS_CHANGED=$(node ./scripts/check-react-native-changes.js $NX_BASE $NX_HEAD);
|
||||
if $HAS_CHANGED; then
|
||||
pnpm nx affected -t e2e-macos-local --parallel=1 --base=$NX_BASE --head=$NX_HEAD
|
||||
else
|
||||
echo "Skip E2E tests for macOS as there are no changes in React Native projects."
|
||||
fi
|
||||
no_output_timeout: 45m
|
||||
for pid in "${pids[@]}"; do
|
||||
wait "$pid"
|
||||
done
|
||||
# -------------------------
|
||||
# JOBS: Main-MacOS
|
||||
# -------------------------
|
||||
mainmacos:
|
||||
executor: macos
|
||||
environment:
|
||||
NX_E2E_CI_CACHE_KEY: e2e-circleci-macos
|
||||
NX_PERF_LOGGING: 'false'
|
||||
NX_CI_EXECUTION_ENV: 'macos'
|
||||
SELECTED_PM: 'npm' # explicitly define npm for macOS tests
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
name: Restore Homebrew packages
|
||||
keys:
|
||||
- nrwl-nx-homebrew-packages
|
||||
- run:
|
||||
name: Configure Detox Environment, Install applesimutils
|
||||
command: |
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew >/dev/null
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 brew install applesimutils >/dev/null
|
||||
xcrun simctl shutdown all && xcrun simctl erase all
|
||||
no_output_timeout: 20m
|
||||
- save_cache:
|
||||
name: Save Homebrew Cache
|
||||
key: nrwl-nx-homebrew-packages
|
||||
paths:
|
||||
- /usr/local/Homebrew
|
||||
- ~/Library/Caches/Homebrew
|
||||
- run-pnpm-install:
|
||||
os: macos
|
||||
- rust/install
|
||||
- nx/set-shas:
|
||||
main-branch-name: 'master'
|
||||
- run:
|
||||
name: Run E2E Tests for macOS
|
||||
command: |
|
||||
HAS_CHANGED=$(node ./scripts/check-react-native-changes.js $NX_BASE $NX_HEAD);
|
||||
if $HAS_CHANGED; then
|
||||
pnpm nx affected -t e2e-macos-ci --parallel=1 --base=$NX_BASE --head=$NX_HEAD
|
||||
else
|
||||
echo "Skip E2E tests for macOS as there are no changes in React Native projects."
|
||||
fi
|
||||
no_output_timeout: 45m
|
||||
|
||||
# -------------------------
|
||||
# WORKFLOWS(JOBS)
|
||||
# -------------------------
|
||||
workflows:
|
||||
version: 2
|
||||
version: 2
|
||||
|
||||
build:
|
||||
jobs:
|
||||
- main-linux
|
||||
- mainmacos:
|
||||
name: main-macos-e2e
|
||||
build:
|
||||
jobs:
|
||||
- main-linux
|
||||
- mainmacos:
|
||||
name: main-macos-e2e
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
FROM mcr.microsoft.com/devcontainers/typescript-node:20-bullseye
|
||||
|
||||
# Update the underlying (Debian) OS, to make sure we have the latest security patches and libraries like 'GLIBC'
|
||||
RUN sudo apt-get update && sudo apt-get -y upgrade
|
||||
|
||||
# Update pnpm
|
||||
RUN npm install -g pnpm@8.15.7
|
||||
@@ -1,48 +1,33 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
|
||||
{
|
||||
"name": "NxDevContainer",
|
||||
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||
|
||||
// Starting from a base image that already contains GLIBC v2.33 or higher (required by Nx)
|
||||
// Try a more recent distribution, if your are having build issues related to GLIBC version
|
||||
// Here we use 'bookworm', which is based on `Debian-12`, which comes with `GLIBC v2.36`
|
||||
// (Nx tools currenlty requires `GLIBC v2.33` or higher)
|
||||
"image": "mcr.microsoft.com/devcontainers/typescript-node:20-bookworm",
|
||||
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/rust:1": {}
|
||||
},
|
||||
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// 4211 = nx graph port
|
||||
// 4873 = verdaccio (local npm registry) port
|
||||
"forwardPorts": [4211, 4873],
|
||||
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
"postCreateCommand": "./.devcontainer/postCreateCommand.sh",
|
||||
|
||||
// Configure tool-specific properties.
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"nrwl.angular-console",
|
||||
"firsttris.vscode-jest-runner",
|
||||
"eamodio.gitlens",
|
||||
"mhutchie.git-graph",
|
||||
"mutantdino.resourcemonitor" // to monitor cpu, memory usage from the dev container
|
||||
],
|
||||
"settings": {
|
||||
"debug.javascript.autoAttachFilter": "disabled" // workaround for that issue: https://github.com/microsoft/vscode-js-debug/issues/374#issuecomment-622239998
|
||||
"name": "NxDevContainer",
|
||||
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
||||
"build": {
|
||||
// Path is relative to the devcontainer.json file.
|
||||
"dockerfile": "Dockerfile"
|
||||
},
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/rust:1": {}
|
||||
},
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
// 4211 = nx graph port
|
||||
"forwardPorts": [4211],
|
||||
// Use 'postCreateCommand' to run commands after the container is created.
|
||||
"postCreateCommand": "./.devcontainer/postCreateCommand.sh",
|
||||
// Configure tool-specific properties.
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"nrwl.angular-console",
|
||||
"firsttris.vscode-jest-runner",
|
||||
"eamodio.gitlens"
|
||||
],
|
||||
"settings": {
|
||||
"debug.javascript.autoAttachFilter": "onlyWithFlag" // workaround for that issue: https://github.com/microsoft/vscode-js-debug/issues/374#issuecomment-622239998
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// To improve disk performances when installing node modules
|
||||
// See https://code.visualstudio.com/remote/advancedcontainers/improve-performance
|
||||
"mounts": [
|
||||
"source=${localWorkspaceFolderBasename}-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume"
|
||||
],
|
||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||
"remoteUser": "root"
|
||||
}
|
||||
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
|
||||
// "remoteUser": "root"
|
||||
}
|
||||
|
||||
@@ -1,23 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Update the underlying (Debian) OS, to make sure we have the latest security patches and libraries like 'GLIBC'
|
||||
echo "⚙️ Updating the underlying OS..."
|
||||
sudo apt-get update && sudo apt-get -y upgrade
|
||||
|
||||
# Uninstall globally installed PNPM (required version will be reinstalled through corepack)
|
||||
echo "❌ Uninstalling globally installed PNPM..."
|
||||
npm uninstall -g pnpm
|
||||
|
||||
# Prevent corepack from prompting user before downloading PNPM
|
||||
export COREPACK_ENABLE_DOWNLOAD_PROMPT=0
|
||||
|
||||
# Enable corepack
|
||||
corepack enable
|
||||
|
||||
# Install the PNPM version defined in the root package.json
|
||||
echo "⚙️ Installing required PNPM version..."
|
||||
corepack prepare --activate
|
||||
|
||||
# Install NPM dependencies
|
||||
echo "⚙️ Installing NPM dependencies..."
|
||||
# Install dependencies
|
||||
pnpm install --frozen-lockfile
|
||||
|
||||
|
||||
@@ -1,69 +1,71 @@
|
||||
{
|
||||
"root": true,
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"ignorePatterns": ["**/*.ts"],
|
||||
"plugins": ["@typescript-eslint", "@nx"],
|
||||
"extends": ["plugin:storybook/recommended"],
|
||||
"rules": {
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||
"no-restricted-imports": ["error", "create-nx-workspace"],
|
||||
"@typescript-eslint/no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"patterns": [
|
||||
{
|
||||
"group": ["nx/src/plugins/js*"],
|
||||
"message": "Imports from 'nx/src/plugins/js' are not allowed. Use '@nx/js' instead"
|
||||
},
|
||||
{
|
||||
"group": ["**/native-bindings", "**/native-bindings.js", ""],
|
||||
"message": "Direct imports from native-bindings.js are not allowed. Import from index.js instead."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"storybook/no-uninstalled-addons": [
|
||||
"error",
|
||||
{
|
||||
"ignore": ["@nx/react/plugins/storybook"],
|
||||
"packageJsonLocation": "../../package.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.json"],
|
||||
"parser": "jsonc-eslint-parser",
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["**/executors/**/schema.json", "**/generators/**/schema.json"],
|
||||
"rules": {
|
||||
"@nx/workspace/valid-schema-description": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {
|
||||
"@nx/enforce-module-boundaries": [
|
||||
"error",
|
||||
{
|
||||
"enforceBuildableLibDependency": true,
|
||||
"checkDynamicDependenciesExceptions": [".*"],
|
||||
"allow": [],
|
||||
"depConstraints": [
|
||||
{
|
||||
"sourceTag": "*",
|
||||
"onlyDependOnLibsWithTags": ["*"]
|
||||
}
|
||||
"root": true,
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"ignorePatterns": ["**/*.ts"],
|
||||
"plugins": ["@typescript-eslint", "@nx"],
|
||||
"extends": ["plugin:storybook/recommended"],
|
||||
"rules": {
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||
"no-restricted-imports": ["error", "create-nx-workspace"],
|
||||
"@typescript-eslint/no-restricted-imports": [
|
||||
"error",
|
||||
{
|
||||
"patterns": [
|
||||
{
|
||||
"group": ["nx/src/plugins/js*"],
|
||||
"message": "Imports from 'nx/src/plugins/js' are not allowed. Use '@nx/js' instead"
|
||||
},
|
||||
{
|
||||
"group": ["**/native-bindings", "**/native-bindings.js", ""],
|
||||
"message": "Direct imports from native-bindings.js are not allowed. Import from index.js instead."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"@nx/workspace/valid-command-object": "error"
|
||||
}
|
||||
],
|
||||
"storybook/no-uninstalled-addons": [
|
||||
"error",
|
||||
{
|
||||
"ignore": ["@nx/react/plugins/storybook"],
|
||||
"packageJsonLocation": "../../package.json"
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.json"],
|
||||
"parser": "jsonc-eslint-parser",
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"**/executors/**/schema.json",
|
||||
"**/generators/**/schema.json"
|
||||
],
|
||||
"rules": {
|
||||
"@nx/workspace/valid-schema-description": "error"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {
|
||||
"@nx/enforce-module-boundaries": [
|
||||
"error",
|
||||
{
|
||||
"enforceBuildableLibDependency": true,
|
||||
"checkDynamicDependenciesExceptions": [".*"],
|
||||
"allow": [],
|
||||
"depConstraints": [
|
||||
{
|
||||
"sourceTag": "*",
|
||||
"onlyDependOnLibsWithTags": ["*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ env:
|
||||
NX_RUN_GROUP: ${{ github.run_id }}-${{ github.run_attempt }}
|
||||
CYPRESS_INSTALL_BINARY: 0
|
||||
NODE_VERSION: 18
|
||||
PNPM_VERSION: 9.8.0 # Aligned with root package.json (pnpm/action-setup will helpfully error if out of sync)
|
||||
PNPM_VERSION: 8.15.7 # Aligned with root package.json (pnpm/action-setup will helpfully error if out of sync)
|
||||
|
||||
jobs:
|
||||
# We first need to determine the version we are releasing, and if we need a custom repo or ref to use for the git checkout in subsequent steps.
|
||||
@@ -115,7 +115,7 @@ jobs:
|
||||
fi
|
||||
|
||||
build:
|
||||
needs: [ resolve-required-data ]
|
||||
needs: [resolve-required-data]
|
||||
if: ${{ github.repository_owner == 'nrwl' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -138,7 +138,7 @@ jobs:
|
||||
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian
|
||||
build: |-
|
||||
set -e &&
|
||||
npm i -g pnpm@9.8.0 --force &&
|
||||
npm i -g pnpm@8.15.7 --force &&
|
||||
pnpm --version &&
|
||||
pnpm install --frozen-lockfile &&
|
||||
pnpm nx run-many --verbose --target=build-native -- --target=x86_64-unknown-linux-gnu
|
||||
@@ -147,7 +147,7 @@ jobs:
|
||||
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
|
||||
build: |-
|
||||
set -e &&
|
||||
npm i -g pnpm@9.8.0 --force &&
|
||||
npm i -g pnpm@8.15.7 --force &&
|
||||
pnpm --version &&
|
||||
pnpm install --frozen-lockfile &&
|
||||
pnpm nx run-many --verbose --target=build-native -- --target=x86_64-unknown-linux-musl
|
||||
@@ -165,7 +165,7 @@ jobs:
|
||||
docker: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64
|
||||
build: |-
|
||||
set -e &&
|
||||
npm i -g pnpm@9.8.0 --force &&
|
||||
npm i -g pnpm@8.15.7 --force &&
|
||||
pnpm --version &&
|
||||
pnpm install --frozen-lockfile &&
|
||||
pnpm nx run-many --verbose --target=build-native -- --target=aarch64-unknown-linux-gnu
|
||||
@@ -191,7 +191,7 @@ jobs:
|
||||
build: |-
|
||||
set -e &&
|
||||
rustup target add aarch64-unknown-linux-musl &&
|
||||
npm i -g pnpm@9.8.0 --force &&
|
||||
npm i -g pnpm@8.15.7 --force &&
|
||||
pnpm --version &&
|
||||
pnpm install --frozen-lockfile &&
|
||||
pnpm nx run-many --verbose --target=build-native -- --target=aarch64-unknown-linux-musl
|
||||
@@ -287,7 +287,7 @@ jobs:
|
||||
if-no-files-found: error
|
||||
|
||||
build-freebsd:
|
||||
needs: [ resolve-required-data ]
|
||||
needs: [resolve-required-data]
|
||||
if: ${{ github.repository_owner == 'nrwl' }}
|
||||
runs-on: ubuntu-latest
|
||||
name: Build FreeBSD
|
||||
@@ -318,7 +318,7 @@ jobs:
|
||||
env
|
||||
whoami
|
||||
sudo pkg install -y -f node libnghttp2 www/npm git
|
||||
sudo npm install --location=global --ignore-scripts pnpm@9.8.0
|
||||
sudo npm install --location=global --ignore-scripts pnpm@8.15.7
|
||||
curl https://sh.rustup.rs -sSf --output rustup.sh
|
||||
sh rustup.sh -y --profile minimal --default-toolchain stable
|
||||
source "$HOME/.cargo/env"
|
||||
@@ -397,10 +397,7 @@ jobs:
|
||||
run: ls -R artifacts
|
||||
shell: bash
|
||||
- name: Build Wasm
|
||||
run: |
|
||||
wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-23/wasi-sdk-23.0-x86_64-linux.tar.gz
|
||||
tar -xvf wasi-sdk-23.0-x86_64-linux.tar.gz
|
||||
pnpm build:wasm
|
||||
run: pnpm build:wasm
|
||||
- name: Publish
|
||||
env:
|
||||
VERSION: ${{ needs.resolve-required-data.outputs.version }}
|
||||
@@ -440,7 +437,7 @@ jobs:
|
||||
pr_failure_comment:
|
||||
# Run this job if it is a PR release, running on the nrwl origin, and any of the required jobs failed
|
||||
if: ${{ github.repository_owner == 'nrwl' && github.event.inputs.pr && always() && contains(needs.*.result, 'failure') }}
|
||||
needs: [ resolve-required-data, build, build-freebsd, publish ]
|
||||
needs: [resolve-required-data, build, build-freebsd, publish]
|
||||
name: (PR Release Failure Only) Create comment for failed PR release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
@@ -22,7 +22,6 @@ jest.debug.config.js
|
||||
/graph/client/src/assets/generated-source-maps
|
||||
/nx-dev/nx-dev/public/documentation
|
||||
/nx-dev/nx-dev/public/images/open-graph
|
||||
**/tests/temp-db
|
||||
|
||||
# Issues scraper creates these files, stored by github's cache
|
||||
/scripts/issues-scraper/cached
|
||||
@@ -59,4 +58,3 @@ out
|
||||
.rustup/
|
||||
target
|
||||
*.wasm
|
||||
/wasi-sdk*
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
NX_DB_CACHE=true
|
||||
@@ -1,57 +1,57 @@
|
||||
launch-templates:
|
||||
linux-medium:
|
||||
resource-class: 'docker_linux_amd64/medium+'
|
||||
image: 'ubuntu22.04-node20.11-v10'
|
||||
env:
|
||||
GIT_AUTHOR_EMAIL: test@test.com
|
||||
GIT_AUTHOR_NAME: Test
|
||||
GIT_COMMITTER_EMAIL: test@test.com
|
||||
GIT_COMMITTER_NAME: Test
|
||||
SELECTED_PM: 'pnpm'
|
||||
NPM_CONFIG_PREFIX: '/home/workflows/.npm-global'
|
||||
init-steps:
|
||||
- name: Checkout
|
||||
uses: 'nrwl/nx-cloud-workflows/v4/workflow-steps/checkout/main.yaml'
|
||||
- name: Cache restore
|
||||
uses: 'nrwl/nx-cloud-workflows/v4/workflow-steps/cache/main.yaml'
|
||||
inputs:
|
||||
key: 'pnpm-lock.yaml'
|
||||
paths: |
|
||||
node_modules
|
||||
~/.cache/Cypress
|
||||
~/.cache/ms-playwright
|
||||
~/.pnpm-store
|
||||
base_branch: 'master'
|
||||
- name: Install e2e deps
|
||||
script: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ca-certificates lsof libvips-dev libglib2.0-dev libgirepository1.0-dev
|
||||
- name: Install Pnpm
|
||||
script: |
|
||||
npm install -g pnpm@9.8.0
|
||||
linux-medium:
|
||||
resource-class: 'docker_linux_amd64/medium+'
|
||||
image: 'ubuntu22.04-node20.11-v3'
|
||||
env:
|
||||
GIT_AUTHOR_EMAIL: test@test.com
|
||||
GIT_AUTHOR_NAME: Test
|
||||
GIT_COMMITTER_EMAIL: test@test.com
|
||||
GIT_COMMITTER_NAME: Test
|
||||
SELECTED_PM: 'pnpm'
|
||||
NPM_CONFIG_PREFIX: '/home/workflows/.npm-global'
|
||||
init-steps:
|
||||
- name: Checkout
|
||||
uses: 'nrwl/nx-cloud-workflows/v3.6/workflow-steps/checkout/main.yaml'
|
||||
- name: Cache restore
|
||||
uses: 'nrwl/nx-cloud-workflows/v3.6/workflow-steps/cache/main.yaml'
|
||||
env:
|
||||
KEY: 'pnpm-lock.yaml'
|
||||
PATHS: |
|
||||
node_modules
|
||||
~/.cache/Cypress
|
||||
~/.cache/ms-playwright
|
||||
~/.pnpm-store
|
||||
BASE_BRANCH: 'master'
|
||||
- name: Install e2e deps
|
||||
script: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y ca-certificates lsof libvips-dev libglib2.0-dev libgirepository1.0-dev
|
||||
- name: Install Pnpm
|
||||
script: |
|
||||
npm install -g pnpm@8
|
||||
|
||||
- name: Pnpm Install
|
||||
script: |
|
||||
pnpm install --frozen-lockfile
|
||||
- name: Pnpm Install
|
||||
script: |
|
||||
pnpm install --frozen-lockfile
|
||||
|
||||
- name: Install Browsers
|
||||
script: |
|
||||
pnpm exec cypress install
|
||||
pnpm exec playwright install
|
||||
- name: Install Browsers
|
||||
script: |
|
||||
pnpm exec cypress install
|
||||
pnpm exec playwright install
|
||||
|
||||
- name: Install Rust
|
||||
script: |
|
||||
curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
source "$HOME/.cargo/env"
|
||||
rustup toolchain install 1.70.0
|
||||
- name: Install Rust
|
||||
script: |
|
||||
curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
source "$HOME/.cargo/env"
|
||||
rustup toolchain install 1.70.0
|
||||
|
||||
- name: Configure git metadata (needed for lerna smoke tests)
|
||||
script: |
|
||||
git config --global user.email test@test.com
|
||||
git config --global user.name "Test Test"
|
||||
- name: Configure git metadata (needed for lerna smoke tests)
|
||||
script: |
|
||||
git config --global user.email test@test.com
|
||||
git config --global user.name "Test Test"
|
||||
|
||||
- name: Load Cargo Env
|
||||
script: echo "PATH=$HOME/.cargo/bin:$PATH" >> $NX_CLOUD_ENV
|
||||
- name: Load Cargo Env
|
||||
script: echo "PATH=$HOME/.cargo/bin:$PATH" >> $NX_CLOUD_ENV
|
||||
|
||||
- name: Install zip and unzip
|
||||
script: sudo apt-get -yqq install zip unzip
|
||||
- name: Install zip and unzip
|
||||
script: sudo apt-get -yqq install zip unzip
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
distribute-on:
|
||||
small-changeset: 8 linux-medium
|
||||
medium-changeset: 10 linux-medium
|
||||
large-changeset: 12 linux-medium
|
||||
small-changeset: 8 linux-medium
|
||||
medium-changeset: 10 linux-medium
|
||||
large-changeset: 12 linux-medium
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"endOfLine": "lf",
|
||||
"plugins": ["prettier-plugin-tailwindcss"]
|
||||
"singleQuote": true,
|
||||
"endOfLine": "lf",
|
||||
"plugins": ["prettier-plugin-tailwindcss"],
|
||||
"tabWidth": 3
|
||||
}
|
||||
|
||||
@@ -2,47 +2,47 @@
|
||||
storage: ../build/local-registry/storage
|
||||
|
||||
auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd
|
||||
htpasswd:
|
||||
file: ./htpasswd
|
||||
|
||||
# a list of other known repositories we can talk to
|
||||
uplinks:
|
||||
npmjs:
|
||||
url: https://registry.npmjs.org/
|
||||
maxage: 60m
|
||||
max_fails: 20
|
||||
fail_timeout: 2m
|
||||
yarn:
|
||||
url: https://registry.yarnpkg.com
|
||||
maxage: 60m
|
||||
max_fails: 20
|
||||
fail_timeout: 2m
|
||||
npmjs:
|
||||
url: https://registry.npmjs.org/
|
||||
maxage: 60m
|
||||
max_fails: 20
|
||||
fail_timeout: 2m
|
||||
yarn:
|
||||
url: https://registry.yarnpkg.com
|
||||
maxage: 60m
|
||||
max_fails: 20
|
||||
fail_timeout: 2m
|
||||
|
||||
packages:
|
||||
'@*/*':
|
||||
# scoped packages
|
||||
access: $all
|
||||
publish: $all
|
||||
unpublish: $all
|
||||
proxy: npmjs
|
||||
'@*/*':
|
||||
# scoped packages
|
||||
access: $all
|
||||
publish: $all
|
||||
unpublish: $all
|
||||
proxy: npmjs
|
||||
|
||||
'**':
|
||||
# allow all users (including non-authenticated users) to read and
|
||||
# publish all packages
|
||||
access: $all
|
||||
'**':
|
||||
# allow all users (including non-authenticated users) to read and
|
||||
# publish all packages
|
||||
access: $all
|
||||
|
||||
# allow all users (including non-authenticated users) to publish/publish packages
|
||||
publish: $all
|
||||
unpublish: $all
|
||||
# allow all users (including non-authenticated users) to publish/publish packages
|
||||
publish: $all
|
||||
unpublish: $all
|
||||
|
||||
# if package is not available locally, proxy requests to 'yarn' registry
|
||||
proxy: npmjs
|
||||
# if package is not available locally, proxy requests to 'yarn' registry
|
||||
proxy: npmjs
|
||||
|
||||
# log settings
|
||||
logs:
|
||||
type: stdout
|
||||
format: pretty
|
||||
level: warn
|
||||
type: stdout
|
||||
format: pretty
|
||||
level: warn
|
||||
|
||||
publish:
|
||||
allow_offline: true # set offline to true to allow publish offline
|
||||
allow_offline: true # set offline to true to allow publish offline
|
||||
|
||||
@@ -172,7 +172,6 @@ rust-toolchain @nrwl/nx-native-reviewers
|
||||
/CONTRIBUTING.md @FrozenPandaz @isaacplmann
|
||||
/CODE_OF_CONDUCT.md @FrozenPandaz @isaacplmann
|
||||
/CODEOWNERS @FrozenPandaz @AgentEnder
|
||||
/packages/nx/src/nx-cloud/utilities/url-shorten.ts @MaxKless
|
||||
|
||||
# Scripts
|
||||
/scripts/documentation @nrwl/nx-docs-reviewers
|
||||
|
||||
@@ -27,13 +27,13 @@ can [submit a Pull Request](https://github.com/nrwl/nx/blob/master/CONTRIBUTING.
|
||||
|
||||
Source code and documentation are included in the top-level folders listed below.
|
||||
|
||||
- `docs` - Markdown and configuration files for documentation including tutorials, guides for each supported platform,
|
||||
and API docs.
|
||||
- `e2e` - E2E tests.
|
||||
- `packages` - Source code for Nx packages such as Angular, React, Web, NestJS, Next and others including generators and
|
||||
executors (or builders).
|
||||
- `scripts` - Miscellaneous scripts for project tasks such as building documentation, testing, and code formatting.
|
||||
- `tmp` - Folder used by e2e tests. If you are a WebStorm user, make sure to mark this folder as excluded.
|
||||
- `docs` - Markdown and configuration files for documentation including tutorials, guides for each supported platform,
|
||||
and API docs.
|
||||
- `e2e` - E2E tests.
|
||||
- `packages` - Source code for Nx packages such as Angular, React, Web, NestJS, Next and others including generators and
|
||||
executors (or builders).
|
||||
- `scripts` - Miscellaneous scripts for project tasks such as building documentation, testing, and code formatting.
|
||||
- `tmp` - Folder used by e2e tests. If you are a WebStorm user, make sure to mark this folder as excluded.
|
||||
|
||||
## Development Workstation Setup
|
||||
|
||||
@@ -41,41 +41,23 @@ If you are using `VSCode`, and provided you have [Docker](https://docker.com) in
|
||||
|
||||
To do so, simply:
|
||||
|
||||
- Checkout the repo
|
||||
- Open it with VSCode
|
||||
- Open the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) and select "Dev Containers: Open Folder in Container..."
|
||||
- Checkout the repo
|
||||
- Open it with VSCode
|
||||
- Open the [Command Palette](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) and select "Dev Containers: Open Folder in Container..."
|
||||
|
||||
The repo comes with a preconfigured `devcontainer.json` file (located in `.devcontainer/` folder at root), that `VSCode` will automatically use to install the aforementioned tools, inside a Docker image. It will even run `pnpm install` for you, so you can start contributing to Nx right after.
|
||||
|
||||
If you open the repo in [Github Codespace](https://github.com/features/codespaces), it will also leverage this config file, to setup the codespace, with the same required tools.
|
||||
|
||||
> 💡 **Troubleshooting**
|
||||
>
|
||||
> If you are having issues when running Nx commands like `build`, `test`... related to the version of `GLIBC`,
|
||||
> it probably means the version that is installed on the devcontainer, **is outdated** compare to the minimum version required by Nx tools.
|
||||
>
|
||||
> You can check currently installed version by running the following command, in a terminal within the container:
|
||||
>
|
||||
> `ldd --version`
|
||||
>
|
||||
> Then, try updating the base image used in [devcontainer.json](.devcontainer/devcontainer.json) and rebuild it, to see if it solved the issue.
|
||||
>
|
||||
> Current base image is `"mcr.microsoft.com/devcontainers/typescript-node:20-bookworm"` which is based on `Debian-12 (bookworm)`,
|
||||
> which comes with `GLIBC v2.36` pre-installed (Nx tools currenlty requires `GLIBC v2.33` or higher).
|
||||
|
||||
## Building the Project
|
||||
|
||||
> 💡 Nx uses `Rust` to build native bindings for Node. Please make sure that you have Rust installed via [rustup.rs](https://rustup.rs)
|
||||
> If you have `VSCode` + `Docker`, this can be automated for you, see [section](#development-workstation-setup) above
|
||||
> Nx uses Rust to build native bindings for Node. Please make sure that you have Rust installed via [rustup.rs](https://rustup.rs)
|
||||
> If you have VSCode + Docker, this can be automated for you, see [section](#development-workstation-setup) above
|
||||
|
||||
After cloning the project to your machine, to install the dependencies, run:
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
|
||||
// or prefer...
|
||||
|
||||
pnpm install --frozen-lockfile // if you haven't changed any dependency
|
||||
pnpm i
|
||||
```
|
||||
|
||||
To build all the packages, run:
|
||||
@@ -91,12 +73,12 @@ it can be useful to publish to a local registry.
|
||||
|
||||
Check out [this video for a live walkthrough](https://youtu.be/Tx257WpNsxc) or follow the instructions below:
|
||||
|
||||
- Run `pnpm local-registry` in Terminal 1 (keep it running)
|
||||
- Run `npm adduser --registry http://localhost:4873` in Terminal 2 (real credentials are not required, you just need to
|
||||
be logged in. You can use test/test/test@test.io.)
|
||||
- Run `pnpm nx-release 20.0.0 --local` in Terminal 2 - you can choose any nonexistent version number here, but it's recommended to use the next major
|
||||
- Run `cd ./tmp` in Terminal 2
|
||||
- Run `npx create-nx-workspace@20.0.0` in Terminal 2
|
||||
- Run `pnpm local-registry` in Terminal 1 (keep it running)
|
||||
- Run `npm adduser --registry http://localhost:4873` in Terminal 2 (real credentials are not required, you just need to
|
||||
be logged in. You can use test/test/test@test.io.)
|
||||
- Run `pnpm nx-release 20.0.0 --local` in Terminal 2 - you can choose any nonexistent version number here, but it's recommended to use the next major
|
||||
- Run `cd ./tmp` in Terminal 2
|
||||
- Run `npx create-nx-workspace@20.0.0` in Terminal 2
|
||||
|
||||
If you have problems publishing, make sure you use Node 18 and NPM 8.
|
||||
|
||||
@@ -106,33 +88,33 @@ If you have problems publishing, make sure you use Node 18 and NPM 8.
|
||||
|
||||
Yarn Berry operates slightly differently than Yarn Classic. In order to publish packages for Berry follow next steps:
|
||||
|
||||
- Run `yarn set version berry` to switch to latest Yarn version.
|
||||
- Create `.yarnrc.yml` in root with following contents:
|
||||
- Run `yarn set version berry` to switch to latest Yarn version.
|
||||
- Create `.yarnrc.yml` in root with following contents:
|
||||
|
||||
```yml
|
||||
nodeLinker: node-modules
|
||||
npmRegistryServer: 'http://localhost:4873'
|
||||
unsafeHttpWhitelist:
|
||||
- localhost
|
||||
```
|
||||
```yml
|
||||
nodeLinker: node-modules
|
||||
npmRegistryServer: 'http://localhost:4873'
|
||||
unsafeHttpWhitelist:
|
||||
- localhost
|
||||
```
|
||||
|
||||
- Run `pnpm local-registry` in Terminal 1 (keep it running)
|
||||
- If you are creating nx workspace outside of your nx repo, make sure to add npm registry info to your root yarnrc (
|
||||
usually in ~/.yarnrc.yml). The file should look something like this:
|
||||
- Run `pnpm local-registry` in Terminal 1 (keep it running)
|
||||
- If you are creating nx workspace outside of your nx repo, make sure to add npm registry info to your root yarnrc (
|
||||
usually in ~/.yarnrc.yml). The file should look something like this:
|
||||
|
||||
```yml
|
||||
npmRegistries:
|
||||
'https://registry.yarnpkg.com':
|
||||
npmAuthToken: npm_******************
|
||||
yarnPath: .yarn/releases/yarn-3.2.2.cjs
|
||||
npmRegistryServer: 'http://localhost:4873'
|
||||
unsafeHttpWhitelist:
|
||||
- localhost
|
||||
```
|
||||
```yml
|
||||
npmRegistries:
|
||||
'https://registry.yarnpkg.com':
|
||||
npmAuthToken: npm_******************
|
||||
yarnPath: .yarn/releases/yarn-3.2.2.cjs
|
||||
npmRegistryServer: 'http://localhost:4873'
|
||||
unsafeHttpWhitelist:
|
||||
- localhost
|
||||
```
|
||||
|
||||
- Run `pnpm nx-release minor --local` in Terminal 2 to publish next minor version. The output will report the version of published packages.
|
||||
- Go to your target folder (e.g. `cd ./tmp`) in Terminal 2
|
||||
- Run `yarn dlx create-nx-workspace@123.4.5` in Terminal 2 (replace `123.4.5` with the version that got published).
|
||||
- Run `pnpm nx-release minor --local` in Terminal 2 to publish next minor version. The output will report the version of published packages.
|
||||
- Go to your target folder (e.g. `cd ./tmp`) in Terminal 2
|
||||
- Run `yarn dlx create-nx-workspace@123.4.5` in Terminal 2 (replace `123.4.5` with the version that got published).
|
||||
|
||||
### Running Unit Tests
|
||||
|
||||
@@ -176,9 +158,9 @@ The above command sets verbose logging (this exposes stack traces and underlying
|
||||
|
||||
To build Nx on Windows, you need to use WSL.
|
||||
|
||||
- Run `pnpm install` in WSL. Yarn will compile several dependencies. If you don't run `install` in WSL, they will be
|
||||
compiled for Windows.
|
||||
- Run `nx affected --target=test` and other commands in WSL.
|
||||
- Run `pnpm install` in WSL. Yarn will compile several dependencies. If you don't run `install` in WSL, they will be
|
||||
compiled for Windows.
|
||||
- Run `nx affected --target=test` and other commands in WSL.
|
||||
|
||||
## Documentation Contributions
|
||||
|
||||
@@ -265,9 +247,9 @@ We want to fix all the issues as soon as possible, but before fixing a bug we ne
|
||||
reproducible scenario gives us wealth of important information without going back and forth with you requiring
|
||||
additional information, such as:
|
||||
|
||||
- the output of `nx report`
|
||||
- `yarn.lock` or `package-lock.json` or `pnpm-lock.yaml`
|
||||
- and most importantly - a use-case that fails
|
||||
- the output of `nx report`
|
||||
- `yarn.lock` or `package-lock.json` or `pnpm-lock.yaml`
|
||||
- and most importantly - a use-case that fails
|
||||
|
||||
A minimal reproduction allows us to quickly confirm a bug (or point out a coding problem) as well as confirm that we are
|
||||
fixing the right problem.
|
||||
@@ -283,18 +265,18 @@ You can file new issues by filling out our [issue form](https://github.com/nrwl/
|
||||
|
||||
Please follow the following guidelines:
|
||||
|
||||
- Make sure unit tests pass (`nx affected --target=test`)
|
||||
- Target a specific project with: `nx run proj:test` (i.e. `nx run angular:test` to target `packages/angular`)
|
||||
- Target a specific unit test file (i.e. `packages/angular/src/utils/ast-command-line-utils.spec.ts`)
|
||||
with `npx jest angular/src/utils/ast-utils` or `npx jest packages/angular/src/utils/ast-utils`
|
||||
- For more options on running tests - check `npx jest --help` or visit [jestjs.io](https://jestjs.io/)
|
||||
- Debug with `node --inspect-brk ./node_modules/jest/bin/jest.js build/packages/angular/src/utils/ast-utils.spec.js`
|
||||
- Make sure e2e tests pass (this can take a while, so you can always let CI check those) (`nx affected --target=e2e`)
|
||||
- Target a specific e2e test with `nx e2e e2e-cypress`
|
||||
- Make sure you run `nx format`
|
||||
- Update documentation with `pnpm documentation`. For documentation, check for spelling and grammatical errors.
|
||||
- Update your commit message to follow the guidelines below (use `pnpm commit` to automate compliance)
|
||||
- `pnpm check-commit` will check to make sure your commit messages are formatted correctly
|
||||
- Make sure unit tests pass (`nx affected --target=test`)
|
||||
- Target a specific project with: `nx run proj:test` (i.e. `nx run angular:test` to target `packages/angular`)
|
||||
- Target a specific unit test file (i.e. `packages/angular/src/utils/ast-command-line-utils.spec.ts`)
|
||||
with `npx jest angular/src/utils/ast-utils` or `npx jest packages/angular/src/utils/ast-utils`
|
||||
- For more options on running tests - check `npx jest --help` or visit [jestjs.io](https://jestjs.io/)
|
||||
- Debug with `node --inspect-brk ./node_modules/jest/bin/jest.js build/packages/angular/src/utils/ast-utils.spec.js`
|
||||
- Make sure e2e tests pass (this can take a while, so you can always let CI check those) (`nx affected --target=e2e`)
|
||||
- Target a specific e2e test with `nx e2e e2e-cypress`
|
||||
- Make sure you run `nx format`
|
||||
- Update documentation with `pnpm documentation`. For documentation, check for spelling and grammatical errors.
|
||||
- Update your commit message to follow the guidelines below (use `pnpm commit` to automate compliance)
|
||||
- `pnpm check-commit` will check to make sure your commit messages are formatted correctly
|
||||
|
||||
#### Commit Message Guidelines
|
||||
|
||||
@@ -310,46 +292,46 @@ body
|
||||
|
||||
The type must be one of the following:
|
||||
|
||||
- feat - New or improved behavior being introduced (e.g. Updating to new versions of React or Jest which bring in new
|
||||
features)
|
||||
- fix - Fixes the current unexpected behavior to match expected behavior (e.g. Fixing the library generator to create
|
||||
the proper named project)
|
||||
- cleanup - Code Style changes that have little to no effect on the user (e.g. Refactoring some functions into a
|
||||
different file)
|
||||
- docs - Changes to the documentation (e.g. Adding more details into the getting started guide)
|
||||
- chore - Changes that have absolutely no effect on users (e.g. Updating the version of Nx used to build the repo)
|
||||
- feat - New or improved behavior being introduced (e.g. Updating to new versions of React or Jest which bring in new
|
||||
features)
|
||||
- fix - Fixes the current unexpected behavior to match expected behavior (e.g. Fixing the library generator to create
|
||||
the proper named project)
|
||||
- cleanup - Code Style changes that have little to no effect on the user (e.g. Refactoring some functions into a
|
||||
different file)
|
||||
- docs - Changes to the documentation (e.g. Adding more details into the getting started guide)
|
||||
- chore - Changes that have absolutely no effect on users (e.g. Updating the version of Nx used to build the repo)
|
||||
|
||||
##### Scope
|
||||
|
||||
The scope must be one of the following:
|
||||
|
||||
- angular - anything Angular specific
|
||||
- bundling - anything bundling specific (e.g. rollup, webpack, etc.)
|
||||
- core - anything Nx core specific
|
||||
- detox - anything Detox specific
|
||||
- devkit - devkit-related changes
|
||||
- graph - anything graph app specific
|
||||
- expo - anything Expo specific
|
||||
- express - anything Express specific
|
||||
- js - anything related to @nx/js package or general js/ts support
|
||||
- linter - anything Linter specific
|
||||
- nest - anything Nest specific
|
||||
- nextjs - anything Next specific
|
||||
- node - anything Node specific
|
||||
- nx-cloud - anything Nx Cloud specific
|
||||
- nx-plugin - anything Nx Plugin specific
|
||||
- nx-dev - anything related to docs infrastructure
|
||||
- react - anything React specific
|
||||
- react-native - anything React Native specific
|
||||
- release - anything related to nx release
|
||||
- repo - anything related to managing the Nx repo itself
|
||||
- storybook - anything Storybook specific
|
||||
- testing - anything testing specific (e.g., Jest or Cypress)
|
||||
- vite - anything Vite specific
|
||||
- vue - anything Vue specific
|
||||
- web - anything Web specific
|
||||
- webpack - anything Webpack specific
|
||||
- misc - misc stuff
|
||||
- angular - anything Angular specific
|
||||
- bundling - anything bundling specific (e.g. rollup, webpack, etc.)
|
||||
- core - anything Nx core specific
|
||||
- detox - anything Detox specific
|
||||
- devkit - devkit-related changes
|
||||
- graph - anything graph app specific
|
||||
- expo - anything Expo specific
|
||||
- express - anything Express specific
|
||||
- js - anything related to @nx/js package or general js/ts support
|
||||
- linter - anything Linter specific
|
||||
- nest - anything Nest specific
|
||||
- nextjs - anything Next specific
|
||||
- node - anything Node specific
|
||||
- nx-cloud - anything Nx Cloud specific
|
||||
- nx-plugin - anything Nx Plugin specific
|
||||
- nx-dev - anything related to docs infrastructure
|
||||
- react - anything React specific
|
||||
- react-native - anything React Native specific
|
||||
- release - anything related to nx release
|
||||
- repo - anything related to managing the Nx repo itself
|
||||
- storybook - anything Storybook specific
|
||||
- testing - anything testing specific (e.g., Jest or Cypress)
|
||||
- vite - anything Vite specific
|
||||
- vue - anything Vue specific
|
||||
- web - anything Web specific
|
||||
- webpack - anything Webpack specific
|
||||
- misc - misc stuff
|
||||
|
||||
##### Subject and Body
|
||||
|
||||
|
||||
@@ -65,21 +65,6 @@ version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
|
||||
|
||||
[[package]]
|
||||
name = "android-tzdata"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.6"
|
||||
@@ -141,9 +126,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.81"
|
||||
version = "0.1.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
|
||||
checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -186,29 +171,6 @@ dependencies = [
|
||||
"scoped-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.69.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.53",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
@@ -217,9 +179,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
@@ -253,12 +215,6 @@ dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
|
||||
|
||||
[[package]]
|
||||
name = "bytecheck"
|
||||
version = "0.6.12"
|
||||
@@ -289,21 +245,9 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.16"
|
||||
version = "1.0.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9d013ecb737093c0e86b151a7b837993cf9ec6c502946cfb44bedc392421e0b"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@@ -311,31 +255,6 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "2.1.0"
|
||||
@@ -367,12 +286,6 @@ dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.12"
|
||||
@@ -413,7 +326,7 @@ version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.5.0",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio",
|
||||
@@ -517,18 +430,6 @@ version = "2.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
|
||||
|
||||
[[package]]
|
||||
name = "fallible-streaming-iterator"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
|
||||
|
||||
[[package]]
|
||||
name = "faster-hex"
|
||||
version = "0.9.0"
|
||||
@@ -754,7 +655,7 @@ version = "0.14.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbd06203b1a9b33a78c88252a625031b094d9e1b647260070c25b09910c0a804"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.5.0",
|
||||
"bstr",
|
||||
"gix-path",
|
||||
"libc",
|
||||
@@ -802,7 +703,7 @@ version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5db19298c5eeea2961e5b3bf190767a2d1f09b8802aeb5f258e42276350aff19"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.5.0",
|
||||
"bstr",
|
||||
"gix-features",
|
||||
"gix-path",
|
||||
@@ -850,9 +751,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gix-path"
|
||||
version = "0.10.9"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d23d5bbda31344d8abc8de7c075b3cf26e5873feba7c4a15d916bce67382bd9"
|
||||
checksum = "23623cf0f475691a6d943f898c4d0b89f5c1a2a64d0f92bce0e0322ee6528783"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"gix-trace",
|
||||
@@ -888,7 +789,7 @@ version = "0.10.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fddc27984a643b20dd03e97790555804f98cf07404e0e552c0ad8133266a79a1"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.5.0",
|
||||
"gix-path",
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
@@ -933,12 +834,6 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
|
||||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.4.14"
|
||||
@@ -958,7 +853,7 @@ version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.5.0",
|
||||
"ignore",
|
||||
"walkdir",
|
||||
]
|
||||
@@ -984,15 +879,6 @@ dependencies = [
|
||||
"rkyv",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashlink"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
|
||||
dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
@@ -1008,29 +894,6 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.5.0"
|
||||
@@ -1150,15 +1013,6 @@ version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue"
|
||||
version = "1.0.8"
|
||||
@@ -1185,17 +1039,11 @@ version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.155"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
@@ -1207,17 +1055,6 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.30.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.13"
|
||||
@@ -1240,18 +1077,6 @@ version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "machine-uid"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a842fb2a43d7a19fe4a6eab96456c417aea97a166f2de0e82410df5bfd7e0cbc"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"cc",
|
||||
"libc",
|
||||
"winreg 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
@@ -1342,7 +1167,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54a63d0570e4c3e0daf7a8d380563610e159f538e20448d6c911337246f40e84"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.5.0",
|
||||
"ctor",
|
||||
"napi-derive",
|
||||
"napi-sys",
|
||||
@@ -1352,9 +1177,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "napi-build"
|
||||
version = "2.1.3"
|
||||
version = "2.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1c0f5d67ee408a4685b61f5ab7e58605c8ae3f2b4189f0127d804ff13d5560a"
|
||||
checksum = "2f9130fccc5f763cf2069b34a089a18f0d0883c66aceb81f2fad541a3d823c43"
|
||||
|
||||
[[package]]
|
||||
name = "napi-derive"
|
||||
@@ -1429,7 +1254,7 @@ version = "0.27.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.5.0",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
]
|
||||
@@ -1456,7 +1281,7 @@ version = "6.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.5.0",
|
||||
"crossbeam-channel",
|
||||
"filetime",
|
||||
"fsevent-sys",
|
||||
@@ -1540,7 +1365,6 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"assert_fs",
|
||||
"chrono",
|
||||
"colored",
|
||||
"crossbeam-channel",
|
||||
"crossterm",
|
||||
@@ -1552,7 +1376,6 @@ dependencies = [
|
||||
"ignore",
|
||||
"ignore-files 2.1.0",
|
||||
"itertools",
|
||||
"machine-uid",
|
||||
"mio",
|
||||
"napi",
|
||||
"napi-build",
|
||||
@@ -1564,7 +1387,6 @@ dependencies = [
|
||||
"rayon",
|
||||
"regex",
|
||||
"rkyv",
|
||||
"rusqlite",
|
||||
"swc_common",
|
||||
"swc_ecma_ast",
|
||||
"swc_ecma_dep_graph",
|
||||
@@ -1663,12 +1485,6 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||
|
||||
[[package]]
|
||||
name = "portable-pty"
|
||||
version = "0.8.1"
|
||||
@@ -1686,7 +1502,7 @@ dependencies = [
|
||||
"shared_library",
|
||||
"shell-words",
|
||||
"winapi",
|
||||
"winreg 0.10.1",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1734,16 +1550,6 @@ dependencies = [
|
||||
"termtree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.53",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.79"
|
||||
@@ -1965,20 +1771,6 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusqlite"
|
||||
version = "0.32.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"fallible-iterator",
|
||||
"fallible-streaming-iterator",
|
||||
"hashlink",
|
||||
"libsqlite3-sys",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
@@ -1997,7 +1789,7 @@ version = "0.38.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.5.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
@@ -2130,12 +1922,6 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.17"
|
||||
@@ -2313,7 +2099,7 @@ version = "0.107.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6528f3dd33e11eae9d7fe9fee4a79d5bbd211c74426ab2eec64dc82bd2eb74d"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bitflags 2.5.0",
|
||||
"is-macro",
|
||||
"num-bigint",
|
||||
"scoped-tls",
|
||||
@@ -2501,9 +2287,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.36"
|
||||
version = "0.3.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
|
||||
checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
@@ -2524,9 +2310,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.18"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
|
||||
checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
@@ -2732,12 +2518,6 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
@@ -2760,61 +2540,6 @@ version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484"
|
||||
|
||||
[[package]]
|
||||
name = "watchexec"
|
||||
version = "3.0.1"
|
||||
@@ -2894,18 +2619,6 @@ dependencies = [
|
||||
"watchexec-signals",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
|
||||
dependencies = [
|
||||
"either",
|
||||
"home",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
@@ -2937,15 +2650,6 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
@@ -3103,16 +2807,6 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winreg"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.5.1"
|
||||
|
||||
@@ -21,45 +21,26 @@
|
||||
|
||||
# Smart Monorepos · Fast CI
|
||||
|
||||
Nx is a build system, optimized for monorepos, with plugins for popular frameworks and tools and advanced CI capabilities including caching and distribution.
|
||||
Nx is a build system with built-in tooling and advanced CI capabilities. It helps you maintain and scale monorepos, both locally and on CI.
|
||||
|
||||
Create a new Nx workspace with
|
||||
A few links to help you get started:
|
||||
|
||||
```shell
|
||||
npx create-nx-workspace
|
||||
```
|
||||
- [Nx.Dev: Documentation, Guides, Interactive Tutorials](https://nx.dev)
|
||||
- [Nx.Dev: Core Tutorials](https://nx.dev/getting-started/intro)
|
||||
- [Recipe: Adding Nx to an Existing Monorepo](https://nx.dev/recipes/adopting-nx/adding-to-monorepo)
|
||||
- [Official Nx YouTube Channel](https://www.youtube.com/@NxDevtools)
|
||||
- [Blog Posts About Nx](https://nx.dev/blog)
|
||||
|
||||
...or run
|
||||
|
||||
```
|
||||
npx nx init
|
||||
```
|
||||
|
||||
to add Nx to your existing workspace to get faster task scheduling, caching and more. More [in the docs](https://nx.dev/getting-started/intro#try-nx-yourself).
|
||||
|
||||
## Learn about CI with Nx Cloud
|
||||
|
||||
[Nx Cloud](https://nx.dev/nx-cloud) connects directly to your existing CI setup, helping you scale your monorepos on CI by leveraging [remote caching](https://nx.dev/ci/features/remote-cache?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo), [task distribution across multiple machines](https://nx.dev/ci/features/distribute-task-execution?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo), [automated e2e test splitting](https://nx.dev/ci/features/split-e2e-tasks?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo) and [automated task flakiness detection](https://nx.dev/ci/features/flaky-tasks?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo)
|
||||
|
||||
Connect your existing Nx workspace with
|
||||
|
||||
```
|
||||
npx nx connect
|
||||
```
|
||||
|
||||
Learn more in the [Nx CI docs »](https://nx.dev/ci/intro?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo)
|
||||
|
||||
## Useful links
|
||||
|
||||
- [Our docs](https://nx.dev/docs)
|
||||
- [Our blog](https://nx.dev/blog)
|
||||
- [Our community discord, live stream,...](https://nx.dev/community)
|
||||
- [Our YouTube channel](https://www.youtube.com/@NxDevtools)
|
||||
- [Our Twitter/X](https://x.com/nxdevtools)
|
||||
|
||||
<p style="text-align: center;"><a href="https://www.youtube.com/@nxdevtools/videos" target="_blank" rel="noreferrer"><img src="./images/nx-courses-and-videos.svg"
|
||||
<p style="text-align: center;"><a href="https://nx.dev/#learning-materials" target="_blank" rel="noreferrer"><img src="./images/nx-courses-and-videos.svg"
|
||||
width="100%" alt="Nx - Smart Monorepos · Fast CI"></a></p>
|
||||
|
||||
# Engage with the Core Team and the Community
|
||||
|
||||
- [Nx.Dev Community Page: Community Discord Channel, Newsletter, etc.](https://nx.dev/community)
|
||||
- [The Nx Show Playlist on YouTube](https://www.youtube.com/playlist?list=PLakNactNC1dE8KLQ5zd3fQwu_yQHjTmR5). It's a
|
||||
regular YouTube stream where we talk all things Nx. Join the stream, ask questions, etc.
|
||||
- [Follow Nx on Twitter](https://twitter.com/NxDevTools)
|
||||
|
||||
## Want to help?
|
||||
|
||||
If you want to file a bug or submit a PR, read up on
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"babelrcRoots": ["*"]
|
||||
"babelrcRoots": ["*"]
|
||||
}
|
||||
|
||||
@@ -1,502 +1,492 @@
|
||||
[
|
||||
{
|
||||
"name": "@ahryman40k/nx-vitepress",
|
||||
"description": "Nx plugin add vitepress project to your workspace",
|
||||
"url": "https://github.com/Ahryman40k/nx-vitepress/tree/main/packages/nx-vitepress"
|
||||
},
|
||||
{
|
||||
"name": "@nightwatch/nx",
|
||||
"description": "The NightwatchJS plugin allows your workspace to use the power of NightwatchJS for E2E and Component Testing on Desktop and Mobile",
|
||||
"url": "https://github.com/nightwatchjs/nightwatch-plugin-nx/"
|
||||
},
|
||||
{
|
||||
"name": "@nxkit/playwright",
|
||||
"description": "The Playwright plugin allows your workspace to use the power of Playwright end-to-end testing",
|
||||
"url": "https://github.com/nxkit/nxkit"
|
||||
},
|
||||
{
|
||||
"name": "qwik-nx",
|
||||
"description": "Get first class support for Qwik inside of Nx monorepos with Qwik optimized custom executors, generators and a vite plugin",
|
||||
"url": "https://github.com/qwikifiers/qwik-nx"
|
||||
},
|
||||
{
|
||||
"name": "@nxkit/style-dictionary",
|
||||
"description": "Nx plugin to generate and build Style Dictionary projects inside your Nx workspace",
|
||||
"url": "https://github.com/nxkit/nxkit"
|
||||
},
|
||||
{
|
||||
"name": "nx-plugin-vite",
|
||||
"description": "Nx plugin integrations with Vite.",
|
||||
"url": "https://nx-plugins.netlify.app/"
|
||||
},
|
||||
{
|
||||
"name": "nx-serverless-cdk",
|
||||
"description": "Create CDK applications and construct libraries. Test and debug infrastructure code and AWS Lambda functions locally.",
|
||||
"url": "https://github.com/castleadmin/nx-plugins/tree/main/nx-serverless-cdk/plugin"
|
||||
},
|
||||
{
|
||||
"name": "@ago-dev/nx-aws-cdk-v2",
|
||||
"description": "An nx plugin for the aws-cdk v2.",
|
||||
"url": "https://github.com/adrian-goe/nx-aws-cdk-v2"
|
||||
},
|
||||
{
|
||||
"name": "@berenddeboer/nx-aws-cdk",
|
||||
"description": "Nx plugin to generate a CDK stack with support for the vitest runner. Supports all CDK commands.",
|
||||
"url": "https://github.com/berenddeboer/nx-plugins/tree/main/packages/nx-aws-cdk"
|
||||
},
|
||||
{
|
||||
"name": "@nx-iac/aws-cdk",
|
||||
"description": "Empowers your Nx workspace with AWS CDK capabilities ⚡",
|
||||
"url": "https://github.com/joelklint/nx-aws-cdk"
|
||||
},
|
||||
{
|
||||
"name": "@routineless/nx-aws-cdk",
|
||||
"description": "Nx plugin to generate and manage aws cdk app and lambdas.",
|
||||
"url": "https://github.com/KozelAnatoliy/routineless/tree/main/packages/nx-aws-cdk"
|
||||
},
|
||||
{
|
||||
"name": "@berenddeboer/nx-sst",
|
||||
"description": "Nx plugin to generate an SST stack and execute all SST commands.",
|
||||
"url": "https://github.com/berenddeboer/nx-plugins/tree/main/packages/nx-sst"
|
||||
},
|
||||
{
|
||||
"name": "@rxap/plugin-localazy",
|
||||
"description": "An Nx plugin for localazy.com upload and download tasks.",
|
||||
"url": "https://gitlab.com/rxap/plugins/-/tree/master/libs/localazy"
|
||||
},
|
||||
{
|
||||
"name": "nx-electron",
|
||||
"description": "An Nx plugin for developing Electron applications",
|
||||
"url": "https://github.com/bennymeg/nx-electron"
|
||||
},
|
||||
{
|
||||
"name": "nx-stylelint",
|
||||
"description": "Nx plugin to use stylelint in a nx workspace",
|
||||
"url": "https://github.com/Phillip9587/nx-stylelint"
|
||||
},
|
||||
{
|
||||
"name": "@nxext/ionic-react",
|
||||
"description": "An Nx plugin for developing Ionic React applications and libraries",
|
||||
"url": "https://github.com/nxext/nx-extensions-ionic/tree/main/packages/ionic-react"
|
||||
},
|
||||
{
|
||||
"name": "@nxext/ionic-angular",
|
||||
"description": "An Nx plugin for developing Ionic Angular applications and libraries",
|
||||
"url": "https://github.com/nxext/nx-extensions-ionic/tree/main/packages/ionic-angular"
|
||||
},
|
||||
{
|
||||
"name": "@nxext/capacitor",
|
||||
"description": "An Nx plugin for developing cross-platform applications using Capacitor",
|
||||
"url": "https://github.com/nxext/nx-extensions/tree/main/packages/capacitor"
|
||||
},
|
||||
{
|
||||
"name": "@angular-architects/ddd",
|
||||
"description": "Nx plugin for structuring a monorepo with domains and layers",
|
||||
"url": "https://github.com/angular-architects/nx-ddd-plugin"
|
||||
},
|
||||
{
|
||||
"name": "@flowaccount/nx-serverless",
|
||||
"description": "Nx plugin for node/angular-universal schematics and deployment builders in an Nx workspace",
|
||||
"url": "https://github.com/flowaccount/nx-plugins"
|
||||
},
|
||||
{
|
||||
"name": "@ns3/nx-serverless",
|
||||
"description": "Nx plugin for node serverless applications in an Nx workspace",
|
||||
"url": "https://github.com/Bielik20/nx-plugins/tree/master/packages/nx-serverless"
|
||||
},
|
||||
{
|
||||
"name": "@ns3/nx-jest-playwright",
|
||||
"description": "Nx plugin to run jest-playwright e2e tests in an Nx workspace",
|
||||
"url": "https://github.com/Bielik20/nx-plugins/tree/master/packages/nx-jest-playwright"
|
||||
},
|
||||
{
|
||||
"name": "@ns3/nx-playwright",
|
||||
"description": "Nx plugin to run playwright e2e tests in an Nx workspace",
|
||||
"url": "https://github.com/Bielik20/nx-plugins/tree/master/packages/nx-playwright"
|
||||
},
|
||||
{
|
||||
"name": "@nx-plus/nuxt",
|
||||
"description": "Nx plugin adding first class support for Nuxt in your Nx workspace.",
|
||||
"url": "https://github.com/ZachJW34/nx-plus/tree/master/libs/nuxt"
|
||||
},
|
||||
{
|
||||
"name": "@nx-plus/vue",
|
||||
"description": "Nx plugin adding first class support for Vue in your Nx workspace.",
|
||||
"url": "https://github.com/ZachJW34/nx-plus/tree/master/libs/vue"
|
||||
},
|
||||
{
|
||||
"name": "@nx-plus/docusaurus",
|
||||
"description": "Nx plugin adding first class support for Docusaurus in your Nx workspace.",
|
||||
"url": "https://github.com/ZachJW34/nx-plus/tree/master/libs/docusaurus"
|
||||
},
|
||||
{
|
||||
"name": "@twittwer/compodoc",
|
||||
"description": "Nx Plugin to integrate the generation of documentation with Compodoc in the Nx workflow",
|
||||
"url": "https://github.com/twittwer/nx-tools/tree/master/libs/compodoc#readme"
|
||||
},
|
||||
{
|
||||
"name": "@enio.ai/nx-install",
|
||||
"description": "nx-install is a plugin for Nx workspaces to quickly setup custom install commands via npm.",
|
||||
"url": "https://github.com/enio-ireland/enio/tree/develop/packages/nx-install#readme"
|
||||
},
|
||||
{
|
||||
"name": "@enio.ai/typedoc",
|
||||
"description": "typedoc is a plugin for Nx workspaces to quickly setup documentation automation on your projects using typedoc.",
|
||||
"url": "https://github.com/enio-ireland/enio/tree/develop/packages/typedoc#readme"
|
||||
},
|
||||
{
|
||||
"name": "@nxext/svelte",
|
||||
"description": "Nx plugin to use Svelte within nx workspaces",
|
||||
"url": "https://github.com/nxext/nx-extensions/tree/master/packages/svelte"
|
||||
},
|
||||
{
|
||||
"name": "@nxext/stencil",
|
||||
"description": "Nx plugin to use StencilJs within nx workspaces",
|
||||
"url": "https://github.com/nxext/nx-extensions/tree/master/packages/stencil"
|
||||
},
|
||||
{
|
||||
"name": "@nxext/vue",
|
||||
"description": "Nx plugin to use VueJS 3 within nx workspaces",
|
||||
"url": "https://github.com/nxext/nx-extensions/tree/master/packages/vue"
|
||||
},
|
||||
{
|
||||
"name": "@nxext/solid",
|
||||
"description": "Nx plugin to use SolidJS within nx workspaces",
|
||||
"url": "https://github.com/nxext/nx-extensions/tree/master/packages/solid"
|
||||
},
|
||||
{
|
||||
"name": "@nx-go/nx-go",
|
||||
"description": "Nx plugin to use Go in a Nx workspace",
|
||||
"url": "https://github.com/nx-go/nx-go"
|
||||
},
|
||||
{
|
||||
"name": "@nx-golang/gin",
|
||||
"description": "Nx plugin to use Go-Gin in a Nx workspace",
|
||||
"url": "https://github.com/nx-golang/nx-golang"
|
||||
},
|
||||
{
|
||||
"name": "@angular-architects/module-federation",
|
||||
"description": "Nx plugin to use webpack module federation",
|
||||
"url": "https://github.com/angular-architects/module-federation-plugin"
|
||||
},
|
||||
{
|
||||
"name": "@nxrocks/nx-spring-boot",
|
||||
"description": "Nx plugin to generate, run, package, build (and more) Spring Boot projects inside your Nx workspace",
|
||||
"url": "https://github.com/tinesoft/nxrocks/tree/master/packages/nx-spring-boot"
|
||||
},
|
||||
{
|
||||
"name": "@trumbitta/nx-plugin-openapi",
|
||||
"description": "OpenAPI Plugin for Nx. Keep your API spec files in libs, and auto-generate sources.",
|
||||
"url": "https://github.com/trumbitta/nx-trumbitta/tree/main/packages/nx-plugin-openapi"
|
||||
},
|
||||
{
|
||||
"name": "@trumbitta/nx-plugin-unused-deps",
|
||||
"description": "Check the dependency graph of your monorepo, looking for unused NPM packages.",
|
||||
"url": "https://github.com/trumbitta/nx-trumbitta/tree/main/packages/nx-plugin-unused-deps"
|
||||
},
|
||||
{
|
||||
"name": "@nxrocks/nx-flutter",
|
||||
"description": "Nx Plugin adding first class support for Flutter in your Nx workspace",
|
||||
"url": "https://github.com/tinesoft/nxrocks/tree/master/packages/nx-flutter"
|
||||
},
|
||||
{
|
||||
"name": "@srleecode/domain",
|
||||
"description": "Nx Plugin for allowing operations to occur at the domain level instead of the default library level",
|
||||
"url": "https://github.com/srlee309/domain"
|
||||
},
|
||||
{
|
||||
"name": "@jscutlery/semver",
|
||||
"description": "Nx plugin to automate semantic versioning and CHANGELOG generation.",
|
||||
"url": "https://github.com/jscutlery/semver"
|
||||
},
|
||||
{
|
||||
"name": "ngx-deploy-npm",
|
||||
"description": "Publish your libraries to NPM with just one command.",
|
||||
"url": "https://github.com/bikecoders/ngx-deploy-npm"
|
||||
},
|
||||
{
|
||||
"name": "@nx-dotnet/core",
|
||||
"description": "Nx plugin for developing and housing .NET projects within an Nx workspace.",
|
||||
"url": "https://github.com/nx-dotnet/nx-dotnet"
|
||||
},
|
||||
{
|
||||
"name": "@nxrocks/nx-quarkus",
|
||||
"description": "Nx plugin to generate, run, package, build (and more) Quarkus projects inside your Nx workspace",
|
||||
"url": "https://github.com/tinesoft/nxrocks/tree/master/packages/nx-quarkus"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/gcp-secrets",
|
||||
"description": "Nx plugin to generate and securely deploy your Google Cloud Secrets",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/gcp-secrets"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/gcp-storage",
|
||||
"description": "Nx plugin to upload to Google Cloud Storage",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/gcp-storage"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/gcp-functions",
|
||||
"description": "Nx plugin to generate, run, build and deploy your Google Cloud Functions",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/gcp-functions"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/gcp-deployment-manager",
|
||||
"description": "Nx plugin to deploy your Google Cloud Deployments",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/gcp-deployment-manager"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/gcp-cloud-run",
|
||||
"description": "Nx plugin to build and deploy your docker container to Google Cloud Run",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/gcp-cloud-run"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/translations",
|
||||
"description": "Nx plugin to extract, pull, push and translate your apps translations",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/translations"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/firebase-hosting",
|
||||
"description": "Nx plugin to deploy your apps to Firebase hosting",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/firebase-hosting"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/e2e-runner",
|
||||
"description": "Nx plugin that can start your API before running Cypress/Playwright",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/e2e-runner"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/vercel",
|
||||
"description": "Nx plugin to deploy your apps to Vercel",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/vercel"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/strapi",
|
||||
"description": "Nx plugin for developing Strapi applications",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/strapi"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/playwright",
|
||||
"description": "Nx plugin to run playwright e2e tests in an Nx workspace",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/playwright"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/terraform",
|
||||
"description": "Nx plugin for deploying your resources with Terraform",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/terraform"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/pulumi",
|
||||
"description": "Nx plugin for deploying your resources with Pulumi",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/pulumi"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/react-email",
|
||||
"description": "Nx plugin for developing email templates with react.email",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/react-email"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/shadcn-ui",
|
||||
"description": "Nx plugin for working with shadcn/ui",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/shadcn-ui"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/docusaurus",
|
||||
"description": "Nx plugin adding first class support for Docusaurus in your Nx workspace.",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/docusaurus"
|
||||
},
|
||||
{
|
||||
"name": "@nativescript/nx",
|
||||
"description": "Nx Plugin adding first class support for NativeScript in your Nx workspace",
|
||||
"url": "https://github.com/nativescript/nx"
|
||||
},
|
||||
{
|
||||
"name": "@nxtensions/astro",
|
||||
"description": "Nx plugin adding first class support for Astro (https://astro.build).",
|
||||
"url": "https://github.com/nxtensions/nxtensions/tree/main/packages/astro"
|
||||
},
|
||||
{
|
||||
"name": "@nxrs/cargo",
|
||||
"description": "Nx plugin adding first-class support for Rust applications and libraries.",
|
||||
"url": "https://github.com/nxrs/cargo/tree/main/packages/cargo"
|
||||
},
|
||||
{
|
||||
"name": "nx-uvu",
|
||||
"description": "An nx executor for the uvu test library",
|
||||
"url": "https://github.com/jmcdo29/nx-uvu"
|
||||
},
|
||||
{
|
||||
"name": "@ndrsg/nx-http",
|
||||
"description": "Plugin with executors, which can perform http-stuff (e.g. requests, webhooks, file up/downloads, ...)",
|
||||
"url": "https://github.com/ndrsg/nx-ext/tree/main/packages/nx-http"
|
||||
},
|
||||
{
|
||||
"name": "@diogovcs/graphql-mesh",
|
||||
"description": "Nx plugin to add GraphQL Mesh integration to Nx Workspace.",
|
||||
"url": "https://github.com/DiogoVCS/nx-workspace-plugins"
|
||||
},
|
||||
{
|
||||
"name": "@computas/nx-yarn",
|
||||
"description": "A plugin to help make nx with yarn a pleasant experience.",
|
||||
"url": "https://github.com/computas/nx-yarn"
|
||||
},
|
||||
{
|
||||
"name": "@theunderscorer/nx-semantic-release",
|
||||
"description": "Nx plugin for automated releases using semantic-release.",
|
||||
"url": "https://github.com/TheUnderScorer/nx-semantic-release"
|
||||
},
|
||||
{
|
||||
"name": "nx-pwm",
|
||||
"description": "Nx plugin and CLI to help maintain packages, inspired by NX repo tooling",
|
||||
"url": "https://github.com/gioragutt/nx-pwm"
|
||||
},
|
||||
{
|
||||
"name": "@nxrocks/nx-micronaut",
|
||||
"description": "Nx plugin to generate, run, package, build (and more) Micronaut projects inside your Nx workspace",
|
||||
"url": "https://github.com/tinesoft/nxrocks/tree/master/packages/nx-micronaut"
|
||||
},
|
||||
{
|
||||
"name": "@koliveira15/nx-sonarqube",
|
||||
"description": "Nx plugin that scans projects using SonarQube / SonarCloud.",
|
||||
"url": "https://github.com/koliveira15/nx-sonarqube"
|
||||
},
|
||||
{
|
||||
"name": "@mands/nx-playwright",
|
||||
"description": "The Playwright plugin allows your workspace to use the power of Playwright end-to-end testing using a native runner.",
|
||||
"url": "https://github.com/marksandspencer/nx-plugins/tree/main/packages/nx-playwright"
|
||||
},
|
||||
{
|
||||
"name": "@diogovcs/stryker-mutator",
|
||||
"description": "Nx plugin to add Stryker Mutator mutation tests to the Nx Workspace.",
|
||||
"url": "https://github.com/DiogoVCS/nx-workspace-plugins"
|
||||
},
|
||||
{
|
||||
"name": "@spaceribs/nx-web-ext",
|
||||
"description": "Nx plugin that allows you to build, test and deploy web extensions.",
|
||||
"url": "https://github.com/spaceribs/spaceribs/tree/main/packages/nx-web-ext"
|
||||
},
|
||||
{
|
||||
"name": "@spaceribs/nx-betterer",
|
||||
"description": "Nx plugin that applies betterer standards on a per-project basis.",
|
||||
"url": "https://github.com/spaceribs/spaceribs/tree/main/packages/nx-betterer"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extensions/helm",
|
||||
"description": "Nx plugin providing comprehensive support for Helm charts, including generation, packaging, and publishing capabilities.",
|
||||
"url": "https://github.com/marcolongol/nx-extensions/tree/main/packages/helm"
|
||||
},
|
||||
{
|
||||
"name": "@nx-tools/nx-container",
|
||||
"description": "Nx plugin to build OCI containers with Docker, Podman or Kaniko.",
|
||||
"url": "https://github.com/gperdomor/nx-tools/tree/main/packages/nx-container"
|
||||
},
|
||||
{
|
||||
"name": "@nxrocks/nx-melos",
|
||||
"description": "Nx plugin adding first class support for Melos in your Nx workspace",
|
||||
"url": "https://github.com/tinesoft/nxrocks/tree/master/packages/nx-melos"
|
||||
},
|
||||
{
|
||||
"name": "@monodon/rust",
|
||||
"description": "Adds Cargo and Rust support",
|
||||
"url": "https://github.com/cammisuli/monodon/tree/main/packages/rust"
|
||||
},
|
||||
{
|
||||
"name": "nx-mesh",
|
||||
"description": "GraphQL Mesh support for Nx",
|
||||
"url": "https://github.com/domjtalbot/nx-mesh"
|
||||
},
|
||||
{
|
||||
"name": "@nxazure/func",
|
||||
"description": "Nx plugin to add Azure Functions support to Nx Workspace.",
|
||||
"url": "https://github.com/AlexPshul/nxazure/tree/master/packages/func"
|
||||
},
|
||||
{
|
||||
"name": "@rbnx/webdriverio",
|
||||
"description": "A Nx plugin that adds the WebdriverIO testing framework to a NX workspace.",
|
||||
"url": "https://github.com/Roozenboom/rbnx/tree/main/packages/webdriverio"
|
||||
},
|
||||
{
|
||||
"name": "nx-ngrok",
|
||||
"description": "Ngrok support for Nx",
|
||||
"url": "https://github.com/domjtalbot/nx-ngrok"
|
||||
},
|
||||
{
|
||||
"name": "@nxrocks/nx-ktor",
|
||||
"description": "Nx plugin to generate, run, package, build (and more) Ktor projects inside your Nx workspace",
|
||||
"url": "https://github.com/tinesoft/nxrocks/tree/master/packages/nx-ktor"
|
||||
},
|
||||
{
|
||||
"name": "nx-size-limit",
|
||||
"description": "Adds size-limit support for Nx (performance budget tool for JavaScript)",
|
||||
"url": "https://github.com/LironHazan/nx-size-limit"
|
||||
},
|
||||
{
|
||||
"name": "@loft-orbital/terraform",
|
||||
"description": "Terraform executors and generators",
|
||||
"url": "https://github.com/loft-orbital/nx-plugins/tree/main/packages/terraform"
|
||||
},
|
||||
{
|
||||
"name": "@nxlv/python",
|
||||
"description": "Nx plugin designed to extend the Nx features to work with Python projects based on Poetry.",
|
||||
"url": "https://github.com/lucasvieirasilva/nx-plugins/tree/main/packages/nx-python"
|
||||
},
|
||||
{
|
||||
"name": "nx-gcp-cache",
|
||||
"description": "Nx plugin to use Google Cloud Storage as distributed remote cache",
|
||||
"url": "https://github.com/davidgarciab/nx-gcp-cache"
|
||||
},
|
||||
{
|
||||
"name": "@jnxplus/nx-gradle",
|
||||
"description": "Nx plugin to add Gradle multi-project builds support to Nx workspace",
|
||||
"url": "https://github.com/khalilou88/jnxplus/tree/main/packages/nx-gradle"
|
||||
},
|
||||
{
|
||||
"name": "@jnxplus/nx-maven",
|
||||
"description": "Nx plugin to add Maven multi-module project support to Nx workspace",
|
||||
"url": "https://github.com/khalilou88/jnxplus/tree/main/packages/nx-maven"
|
||||
},
|
||||
{
|
||||
"name": "@naxodev/nx-cloudflare",
|
||||
"description": "Nx plugin for Cloudflare, in particular Cloudflare workers. It allows to generate build and run Cloudflare workers in your Nx workspace.",
|
||||
"url": "https://github.com/naxodev/oss/tree/main/packages/nx-cloudflare"
|
||||
},
|
||||
{
|
||||
"name": "@ziacik/azure-func",
|
||||
"description": "Generating, serving and publishing Azure Functions 4 apps.",
|
||||
"url": "https://github.com/ziacik/nx-tools/tree/master/packages/azure-func"
|
||||
},
|
||||
{
|
||||
"name": "@simondotm/nx-firebase",
|
||||
"description": "Nx plugin to support Firebase Apps and Cloud Functions in Nx workspaces",
|
||||
"url": "https://github.com/simondotm/nx-firebase"
|
||||
},
|
||||
{
|
||||
"name": "@dman926/nx-python-pdm",
|
||||
"description": "Use Python in NX workspaces with PDM",
|
||||
"url": "https://github.com/dman926/nx-python-pdm"
|
||||
},
|
||||
{
|
||||
"name": "@gnuechtel/nx-cucumber",
|
||||
"description": "Plugin to use Cucumber within Nx workspaces",
|
||||
"url": "https://gitlab.com/gnuechtel/open-source/-/tree/main/libs/nx-cucumber"
|
||||
},
|
||||
{
|
||||
"name": "@analogjs/platform",
|
||||
"description": "Official plugin to add Analog to your Nx monorepo.",
|
||||
"url": "https://analogjs.org/docs/integrations/nx"
|
||||
},
|
||||
{
|
||||
"name": "@getlarge/nx-heroku",
|
||||
"description": "Plugin to deploy and promote Nx apps on Heroku",
|
||||
"url": "https://github.com/getlarge/nx-heroku"
|
||||
},
|
||||
{
|
||||
"name": "@huge-nx/conventions",
|
||||
"description": "Plugin to generate and manage Nx workspaces by adhering to established workspace conventions.",
|
||||
"url": "https://github.com/jogelin/huge-nx"
|
||||
},
|
||||
{
|
||||
"name": "nx-github-pages",
|
||||
"description": "A small Nx plugin to make deploying static projects to GitHub Pages easy.",
|
||||
"url": "https://github.com/agentender/nx-github-pages"
|
||||
}
|
||||
{
|
||||
"name": "@ahryman40k/nx-vitepress",
|
||||
"description": "Nx plugin add vitepress project to your workspace",
|
||||
"url": "https://github.com/Ahryman40k/nx-vitepress/tree/main/packages/nx-vitepress"
|
||||
},
|
||||
{
|
||||
"name": "@nightwatch/nx",
|
||||
"description": "The NightwatchJS plugin allows your workspace to use the power of NightwatchJS for E2E and Component Testing on Desktop and Mobile",
|
||||
"url": "https://github.com/nightwatchjs/nightwatch-plugin-nx/"
|
||||
},
|
||||
{
|
||||
"name": "@nxkit/playwright",
|
||||
"description": "The Playwright plugin allows your workspace to use the power of Playwright end-to-end testing",
|
||||
"url": "https://github.com/nxkit/nxkit"
|
||||
},
|
||||
{
|
||||
"name": "qwik-nx",
|
||||
"description": "Get first class support for Qwik inside of Nx monorepos with Qwik optimized custom executors, generators and a vite plugin",
|
||||
"url": "https://github.com/qwikifiers/qwik-nx"
|
||||
},
|
||||
{
|
||||
"name": "@nxkit/style-dictionary",
|
||||
"description": "Nx plugin to generate and build Style Dictionary projects inside your Nx workspace",
|
||||
"url": "https://github.com/nxkit/nxkit"
|
||||
},
|
||||
{
|
||||
"name": "nx-plugin-vite",
|
||||
"description": "Nx plugin integrations with Vite.",
|
||||
"url": "https://nx-plugins.netlify.app/"
|
||||
},
|
||||
{
|
||||
"name": "nx-serverless-cdk",
|
||||
"description": "Create CDK applications and construct libraries. Test and debug infrastructure code and AWS Lambda functions locally.",
|
||||
"url": "https://github.com/castleadmin/nx-plugins/tree/main/nx-serverless-cdk/plugin"
|
||||
},
|
||||
{
|
||||
"name": "@ago-dev/nx-aws-cdk-v2",
|
||||
"description": "An nx plugin for the aws-cdk v2.",
|
||||
"url": "https://github.com/adrian-goe/nx-aws-cdk-v2"
|
||||
},
|
||||
{
|
||||
"name": "@berenddeboer/nx-aws-cdk",
|
||||
"description": "Nx plugin to generate a CDK stack with support for the vitest runner. Supports all CDK commands.",
|
||||
"url": "https://github.com/berenddeboer/nx-plugins/tree/main/packages/nx-aws-cdk"
|
||||
},
|
||||
{
|
||||
"name": "@nx-iac/aws-cdk",
|
||||
"description": "Empowers your Nx workspace with AWS CDK capabilities ⚡",
|
||||
"url": "https://github.com/joelklint/nx-aws-cdk"
|
||||
},
|
||||
{
|
||||
"name": "@routineless/nx-aws-cdk",
|
||||
"description": "Nx plugin to generate and manage aws cdk app and lambdas.",
|
||||
"url": "https://github.com/KozelAnatoliy/routineless/tree/main/packages/nx-aws-cdk"
|
||||
},
|
||||
{
|
||||
"name": "@berenddeboer/nx-sst",
|
||||
"description": "Nx plugin to generate an SST stack and execute all SST commands.",
|
||||
"url": "https://github.com/berenddeboer/nx-plugins/tree/main/packages/nx-sst"
|
||||
},
|
||||
{
|
||||
"name": "@rxap/plugin-localazy",
|
||||
"description": "An Nx plugin for localazy.com upload and download tasks.",
|
||||
"url": "https://gitlab.com/rxap/plugins/-/tree/master/libs/localazy"
|
||||
},
|
||||
{
|
||||
"name": "nx-electron",
|
||||
"description": "An Nx plugin for developing Electron applications",
|
||||
"url": "https://github.com/bennymeg/nx-electron"
|
||||
},
|
||||
{
|
||||
"name": "nx-stylelint",
|
||||
"description": "Nx plugin to use stylelint in a nx workspace",
|
||||
"url": "https://github.com/Phillip9587/nx-stylelint"
|
||||
},
|
||||
{
|
||||
"name": "@nxext/ionic-react",
|
||||
"description": "An Nx plugin for developing Ionic React applications and libraries",
|
||||
"url": "https://github.com/nxext/nx-extensions-ionic/tree/main/packages/ionic-react"
|
||||
},
|
||||
{
|
||||
"name": "@nxext/ionic-angular",
|
||||
"description": "An Nx plugin for developing Ionic Angular applications and libraries",
|
||||
"url": "https://github.com/nxext/nx-extensions-ionic/tree/main/packages/ionic-angular"
|
||||
},
|
||||
{
|
||||
"name": "@nxext/capacitor",
|
||||
"description": "An Nx plugin for developing cross-platform applications using Capacitor",
|
||||
"url": "https://github.com/nxext/nx-extensions/tree/main/packages/capacitor"
|
||||
},
|
||||
{
|
||||
"name": "@angular-architects/ddd",
|
||||
"description": "Nx plugin for structuring a monorepo with domains and layers",
|
||||
"url": "https://github.com/angular-architects/nx-ddd-plugin"
|
||||
},
|
||||
{
|
||||
"name": "@flowaccount/nx-serverless",
|
||||
"description": "Nx plugin for node/angular-universal schematics and deployment builders in an Nx workspace",
|
||||
"url": "https://github.com/flowaccount/nx-plugins"
|
||||
},
|
||||
{
|
||||
"name": "@ns3/nx-serverless",
|
||||
"description": "Nx plugin for node serverless applications in an Nx workspace",
|
||||
"url": "https://github.com/Bielik20/nx-plugins/tree/master/packages/nx-serverless"
|
||||
},
|
||||
{
|
||||
"name": "@ns3/nx-jest-playwright",
|
||||
"description": "Nx plugin to run jest-playwright e2e tests in an Nx workspace",
|
||||
"url": "https://github.com/Bielik20/nx-plugins/tree/master/packages/nx-jest-playwright"
|
||||
},
|
||||
{
|
||||
"name": "@ns3/nx-playwright",
|
||||
"description": "Nx plugin to run playwright e2e tests in an Nx workspace",
|
||||
"url": "https://github.com/Bielik20/nx-plugins/tree/master/packages/nx-playwright"
|
||||
},
|
||||
{
|
||||
"name": "@nx-plus/nuxt",
|
||||
"description": "Nx plugin adding first class support for Nuxt in your Nx workspace.",
|
||||
"url": "https://github.com/ZachJW34/nx-plus/tree/master/libs/nuxt"
|
||||
},
|
||||
{
|
||||
"name": "@nx-plus/vue",
|
||||
"description": "Nx plugin adding first class support for Vue in your Nx workspace.",
|
||||
"url": "https://github.com/ZachJW34/nx-plus/tree/master/libs/vue"
|
||||
},
|
||||
{
|
||||
"name": "@nx-plus/docusaurus",
|
||||
"description": "Nx plugin adding first class support for Docusaurus in your Nx workspace.",
|
||||
"url": "https://github.com/ZachJW34/nx-plus/tree/master/libs/docusaurus"
|
||||
},
|
||||
{
|
||||
"name": "@twittwer/compodoc",
|
||||
"description": "Nx Plugin to integrate the generation of documentation with Compodoc in the Nx workflow",
|
||||
"url": "https://github.com/twittwer/nx-tools/tree/master/libs/compodoc#readme"
|
||||
},
|
||||
{
|
||||
"name": "@enio.ai/nx-install",
|
||||
"description": "nx-install is a plugin for Nx workspaces to quickly setup custom install commands via npm.",
|
||||
"url": "https://github.com/enio-ireland/enio/tree/develop/packages/nx-install#readme"
|
||||
},
|
||||
{
|
||||
"name": "@enio.ai/typedoc",
|
||||
"description": "typedoc is a plugin for Nx workspaces to quickly setup documentation automation on your projects using typedoc.",
|
||||
"url": "https://github.com/enio-ireland/enio/tree/develop/packages/typedoc#readme"
|
||||
},
|
||||
{
|
||||
"name": "@nxext/svelte",
|
||||
"description": "Nx plugin to use Svelte within nx workspaces",
|
||||
"url": "https://github.com/nxext/nx-extensions/tree/master/packages/svelte"
|
||||
},
|
||||
{
|
||||
"name": "@nxext/stencil",
|
||||
"description": "Nx plugin to use StencilJs within nx workspaces",
|
||||
"url": "https://github.com/nxext/nx-extensions/tree/master/packages/stencil"
|
||||
},
|
||||
{
|
||||
"name": "@nxext/vue",
|
||||
"description": "Nx plugin to use VueJS 3 within nx workspaces",
|
||||
"url": "https://github.com/nxext/nx-extensions/tree/master/packages/vue"
|
||||
},
|
||||
{
|
||||
"name": "@nxext/solid",
|
||||
"description": "Nx plugin to use SolidJS within nx workspaces",
|
||||
"url": "https://github.com/nxext/nx-extensions/tree/master/packages/solid"
|
||||
},
|
||||
{
|
||||
"name": "@nx-go/nx-go",
|
||||
"description": "Nx plugin to use Go in a Nx workspace",
|
||||
"url": "https://github.com/nx-go/nx-go"
|
||||
},
|
||||
{
|
||||
"name": "@nx-golang/gin",
|
||||
"description": "Nx plugin to use Go-Gin in a Nx workspace",
|
||||
"url": "https://github.com/nx-golang/nx-golang"
|
||||
},
|
||||
{
|
||||
"name": "@angular-architects/module-federation",
|
||||
"description": "Nx plugin to use webpack module federation",
|
||||
"url": "https://github.com/angular-architects/module-federation-plugin"
|
||||
},
|
||||
{
|
||||
"name": "@nxrocks/nx-spring-boot",
|
||||
"description": "Nx plugin to generate, run, package, build (and more) Spring Boot projects inside your Nx workspace",
|
||||
"url": "https://github.com/tinesoft/nxrocks/tree/master/packages/nx-spring-boot"
|
||||
},
|
||||
{
|
||||
"name": "@trumbitta/nx-plugin-openapi",
|
||||
"description": "OpenAPI Plugin for Nx. Keep your API spec files in libs, and auto-generate sources.",
|
||||
"url": "https://github.com/trumbitta/nx-trumbitta/tree/main/packages/nx-plugin-openapi"
|
||||
},
|
||||
{
|
||||
"name": "@trumbitta/nx-plugin-unused-deps",
|
||||
"description": "Check the dependency graph of your monorepo, looking for unused NPM packages.",
|
||||
"url": "https://github.com/trumbitta/nx-trumbitta/tree/main/packages/nx-plugin-unused-deps"
|
||||
},
|
||||
{
|
||||
"name": "@nxrocks/nx-flutter",
|
||||
"description": "Nx Plugin adding first class support for Flutter in your Nx workspace",
|
||||
"url": "https://github.com/tinesoft/nxrocks/tree/master/packages/nx-flutter"
|
||||
},
|
||||
{
|
||||
"name": "@srleecode/domain",
|
||||
"description": "Nx Plugin for allowing operations to occur at the domain level instead of the default library level",
|
||||
"url": "https://github.com/srlee309/domain"
|
||||
},
|
||||
{
|
||||
"name": "@jscutlery/semver",
|
||||
"description": "Nx plugin to automate semantic versioning and CHANGELOG generation.",
|
||||
"url": "https://github.com/jscutlery/semver"
|
||||
},
|
||||
{
|
||||
"name": "ngx-deploy-npm",
|
||||
"description": "Publish your libraries to NPM with just one command.",
|
||||
"url": "https://github.com/bikecoders/ngx-deploy-npm"
|
||||
},
|
||||
{
|
||||
"name": "@nx-dotnet/core",
|
||||
"description": "Nx plugin for developing and housing .NET projects within an Nx workspace.",
|
||||
"url": "https://github.com/nx-dotnet/nx-dotnet"
|
||||
},
|
||||
{
|
||||
"name": "@nxrocks/nx-quarkus",
|
||||
"description": "Nx plugin to generate, run, package, build (and more) Quarkus projects inside your Nx workspace",
|
||||
"url": "https://github.com/tinesoft/nxrocks/tree/master/packages/nx-quarkus"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/gcp-secrets",
|
||||
"description": "Nx plugin to generate and securely deploy your Google Cloud Secrets",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/gcp-secrets"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/gcp-storage",
|
||||
"description": "Nx plugin to upload to Google Cloud Storage",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/gcp-storage"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/gcp-functions",
|
||||
"description": "Nx plugin to generate, run, build and deploy your Google Cloud Functions",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/gcp-functions"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/gcp-deployment-manager",
|
||||
"description": "Nx plugin to deploy your Google Cloud Deployments",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/gcp-deployment-manager"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/gcp-cloud-run",
|
||||
"description": "Nx plugin to build and deploy your docker container to Google Cloud Run",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/gcp-cloud-run"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/translations",
|
||||
"description": "Nx plugin to extract, pull, push and translate your apps translations",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/translations"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/firebase-hosting",
|
||||
"description": "Nx plugin to deploy your apps to Firebase hosting",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/firebase-hosting"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/e2e-runner",
|
||||
"description": "Nx plugin that can start your API before running Cypress/Playwright",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/e2e-runner"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/vercel",
|
||||
"description": "Nx plugin to deploy your apps to Vercel",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/vercel"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/strapi",
|
||||
"description": "Nx plugin for developing Strapi applications",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/strapi"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/playwright",
|
||||
"description": "Nx plugin to run playwright e2e tests in an Nx workspace",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/playwright"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/terraform",
|
||||
"description": "Nx plugin for deploying your resources with Terraform",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/terraform"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/pulumi",
|
||||
"description": "Nx plugin for deploying your resources with Pulumi",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/pulumi"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/react-email",
|
||||
"description": "Nx plugin for developing email templates with react.email",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/react-email"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/shadcn-ui",
|
||||
"description": "Nx plugin for working with shadcn/ui",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/shadcn-ui"
|
||||
},
|
||||
{
|
||||
"name": "@nx-extend/docusaurus",
|
||||
"description": "Nx plugin adding first class support for Docusaurus in your Nx workspace.",
|
||||
"url": "https://github.com/tripss/nx-extend/tree/master/packages/docusaurus"
|
||||
},
|
||||
{
|
||||
"name": "@nativescript/nx",
|
||||
"description": "Nx Plugin adding first class support for NativeScript in your Nx workspace",
|
||||
"url": "https://github.com/nativescript/nx"
|
||||
},
|
||||
{
|
||||
"name": "@nxtensions/astro",
|
||||
"description": "Nx plugin adding first class support for Astro (https://astro.build).",
|
||||
"url": "https://github.com/nxtensions/nxtensions/tree/main/packages/astro"
|
||||
},
|
||||
{
|
||||
"name": "@nxrs/cargo",
|
||||
"description": "Nx plugin adding first-class support for Rust applications and libraries.",
|
||||
"url": "https://github.com/nxrs/cargo/tree/main/packages/cargo"
|
||||
},
|
||||
{
|
||||
"name": "nx-uvu",
|
||||
"description": "An nx executor for the uvu test library",
|
||||
"url": "https://github.com/jmcdo29/nx-uvu"
|
||||
},
|
||||
{
|
||||
"name": "@ndrsg/nx-http",
|
||||
"description": "Plugin with executors, which can perform http-stuff (e.g. requests, webhooks, file up/downloads, ...)",
|
||||
"url": "https://github.com/ndrsg/nx-ext/tree/main/packages/nx-http"
|
||||
},
|
||||
{
|
||||
"name": "@diogovcs/graphql-mesh",
|
||||
"description": "Nx plugin to add GraphQL Mesh integration to Nx Workspace.",
|
||||
"url": "https://github.com/DiogoVCS/nx-workspace-plugins"
|
||||
},
|
||||
{
|
||||
"name": "@computas/nx-yarn",
|
||||
"description": "A plugin to help make nx with yarn a pleasant experience.",
|
||||
"url": "https://github.com/computas/nx-yarn"
|
||||
},
|
||||
{
|
||||
"name": "@theunderscorer/nx-semantic-release",
|
||||
"description": "Nx plugin for automated releases using semantic-release.",
|
||||
"url": "https://github.com/TheUnderScorer/nx-semantic-release"
|
||||
},
|
||||
{
|
||||
"name": "nx-pwm",
|
||||
"description": "Nx plugin and CLI to help maintain packages, inspired by NX repo tooling",
|
||||
"url": "https://github.com/gioragutt/nx-pwm"
|
||||
},
|
||||
{
|
||||
"name": "@nxrocks/nx-micronaut",
|
||||
"description": "Nx plugin to generate, run, package, build (and more) Micronaut projects inside your Nx workspace",
|
||||
"url": "https://github.com/tinesoft/nxrocks/tree/master/packages/nx-micronaut"
|
||||
},
|
||||
{
|
||||
"name": "@koliveira15/nx-sonarqube",
|
||||
"description": "Nx plugin that scans projects using SonarQube / SonarCloud.",
|
||||
"url": "https://github.com/koliveira15/nx-sonarqube"
|
||||
},
|
||||
{
|
||||
"name": "@mands/nx-playwright",
|
||||
"description": "The Playwright plugin allows your workspace to use the power of Playwright end-to-end testing using a native runner.",
|
||||
"url": "https://github.com/marksandspencer/nx-plugins/tree/main/packages/nx-playwright"
|
||||
},
|
||||
{
|
||||
"name": "@diogovcs/stryker-mutator",
|
||||
"description": "Nx plugin to add Stryker Mutator mutation tests to the Nx Workspace.",
|
||||
"url": "https://github.com/DiogoVCS/nx-workspace-plugins"
|
||||
},
|
||||
{
|
||||
"name": "@spaceribs/nx-web-ext",
|
||||
"description": "Nx plugin that allows you to build, test and deploy web extensions.",
|
||||
"url": "https://github.com/spaceribs/spaceribs/tree/main/packages/nx-web-ext"
|
||||
},
|
||||
{
|
||||
"name": "@spaceribs/nx-betterer",
|
||||
"description": "Nx plugin that applies betterer standards on a per-project basis.",
|
||||
"url": "https://github.com/spaceribs/spaceribs/tree/main/packages/nx-betterer"
|
||||
},
|
||||
{
|
||||
"name": "@nx-tools/nx-container",
|
||||
"description": "Nx plugin to build OCI containers with Docker, Podman or Kaniko.",
|
||||
"url": "https://github.com/gperdomor/nx-tools/tree/main/packages/nx-container"
|
||||
},
|
||||
{
|
||||
"name": "@nxrocks/nx-melos",
|
||||
"description": "Nx plugin adding first class support for Melos in your Nx workspace",
|
||||
"url": "https://github.com/tinesoft/nxrocks/tree/master/packages/nx-melos"
|
||||
},
|
||||
{
|
||||
"name": "@monodon/rust",
|
||||
"description": "Adds Cargo and Rust support",
|
||||
"url": "https://github.com/cammisuli/monodon/tree/main/packages/rust"
|
||||
},
|
||||
{
|
||||
"name": "nx-mesh",
|
||||
"description": "GraphQL Mesh support for Nx",
|
||||
"url": "https://github.com/domjtalbot/nx-mesh"
|
||||
},
|
||||
{
|
||||
"name": "@nxazure/func",
|
||||
"description": "Nx plugin to add Azure Functions support to Nx Workspace.",
|
||||
"url": "https://github.com/AlexPshul/nxazure/tree/master/packages/func"
|
||||
},
|
||||
{
|
||||
"name": "@rbnx/webdriverio",
|
||||
"description": "A Nx plugin that adds the WebdriverIO testing framework to a NX workspace.",
|
||||
"url": "https://github.com/Roozenboom/rbnx/tree/main/packages/webdriverio"
|
||||
},
|
||||
{
|
||||
"name": "nx-ngrok",
|
||||
"description": "Ngrok support for Nx",
|
||||
"url": "https://github.com/domjtalbot/nx-ngrok"
|
||||
},
|
||||
{
|
||||
"name": "@nxrocks/nx-ktor",
|
||||
"description": "Nx plugin to generate, run, package, build (and more) Ktor projects inside your Nx workspace",
|
||||
"url": "https://github.com/tinesoft/nxrocks/tree/master/packages/nx-ktor"
|
||||
},
|
||||
{
|
||||
"name": "nx-size-limit",
|
||||
"description": "Adds size-limit support for Nx (performance budget tool for JavaScript)",
|
||||
"url": "https://github.com/LironHazan/nx-size-limit"
|
||||
},
|
||||
{
|
||||
"name": "@loft-orbital/terraform",
|
||||
"description": "Terraform executors and generators",
|
||||
"url": "https://github.com/loft-orbital/nx-plugins/tree/main/packages/terraform"
|
||||
},
|
||||
{
|
||||
"name": "@nxlv/python",
|
||||
"description": "Nx plugin designed to extend the Nx features to work with Python projects based on Poetry.",
|
||||
"url": "https://github.com/lucasvieirasilva/nx-plugins/tree/main/packages/nx-python"
|
||||
},
|
||||
{
|
||||
"name": "nx-gcp-cache",
|
||||
"description": "Nx plugin to use Google Cloud Storage as distributed remote cache",
|
||||
"url": "https://github.com/davidgarciab/nx-gcp-cache"
|
||||
},
|
||||
{
|
||||
"name": "@jnxplus/nx-gradle",
|
||||
"description": "Nx plugin to add Gradle multi-project builds support to Nx workspace",
|
||||
"url": "https://github.com/khalilou88/jnxplus/tree/main/packages/nx-gradle"
|
||||
},
|
||||
{
|
||||
"name": "@jnxplus/nx-maven",
|
||||
"description": "Nx plugin to add Maven multi-module project support to Nx workspace",
|
||||
"url": "https://github.com/khalilou88/jnxplus/tree/main/packages/nx-maven"
|
||||
},
|
||||
{
|
||||
"name": "@naxodev/nx-cloudflare",
|
||||
"description": "Nx plugin for Cloudflare, in particular Cloudflare workers. It allows to generate build and run Cloudflare workers in your Nx workspace.",
|
||||
"url": "https://github.com/naxodev/oss/tree/main/packages/plugins/nx-cloudflare"
|
||||
},
|
||||
{
|
||||
"name": "@ziacik/azure-func",
|
||||
"description": "Generating, serving and publishing Azure Functions 4 apps.",
|
||||
"url": "https://github.com/ziacik/nx-tools/tree/master/packages/azure-func"
|
||||
},
|
||||
{
|
||||
"name": "@simondotm/nx-firebase",
|
||||
"description": "Nx plugin to support Firebase Apps and Cloud Functions in Nx workspaces",
|
||||
"url": "https://github.com/simondotm/nx-firebase"
|
||||
},
|
||||
{
|
||||
"name": "@dman926/nx-python-pdm",
|
||||
"description": "Use Python in NX workspaces with PDM",
|
||||
"url": "https://github.com/dman926/nx-python-pdm"
|
||||
},
|
||||
{
|
||||
"name": "@gnuechtel/nx-cucumber",
|
||||
"description": "Plugin to use Cucumber within Nx workspaces",
|
||||
"url": "https://gitlab.com/gnuechtel/open-source/-/tree/main/libs/nx-cucumber"
|
||||
},
|
||||
{
|
||||
"name": "@analogjs/platform",
|
||||
"description": "Official plugin to add Analog to your Nx monorepo.",
|
||||
"url": "https://analogjs.org/docs/integrations/nx"
|
||||
},
|
||||
{
|
||||
"name": "@getlarge/nx-heroku",
|
||||
"description": "Plugin to deploy and promote Nx apps on Heroku",
|
||||
"url": "https://github.com/getlarge/nx-heroku"
|
||||
},
|
||||
{
|
||||
"name": "@huge-nx/conventions",
|
||||
"description": "Plugin to generate and manage Nx workspaces by adhering to established workspace conventions.",
|
||||
"url": "https://github.com/jogelin/huge-nx"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -8,10 +8,10 @@ When writing documentation, it is important to know the audience you are writing
|
||||
|
||||
We are generally following the [Diataxis](https://diataxis.fr) model where documents are divided into tutorials, concept guides, recipes and reference.
|
||||
|
||||
- Tutorial - Focused on explaining a concept through step by step instructions.
|
||||
- Concept guide - Explains why something works the way it does or how to think about something.
|
||||
- Recipe - Focused directions to accomplish a specific task. Describes how to do something.
|
||||
- Reference - Lists what you can do with the tool (i.e. API docs).
|
||||
- Tutorial - Focused on explaining a concept through step by step instructions.
|
||||
- Concept guide - Explains why something works the way it does or how to think about something.
|
||||
- Recipe - Focused directions to accomplish a specific task. Describes how to do something.
|
||||
- Reference - Lists what you can do with the tool (i.e. API docs).
|
||||
|
||||
### Audiences
|
||||
|
||||
@@ -19,40 +19,40 @@ We also have different audiences in mind when writing docs:
|
||||
|
||||
👶 New user starting from scratch
|
||||
|
||||
- They know their framework of choice
|
||||
- They have probably heard the term monorepo but don't really know what it is
|
||||
- They're smart and eager to learn
|
||||
- They know their framework of choice
|
||||
- They have probably heard the term monorepo but don't really know what it is
|
||||
- They're smart and eager to learn
|
||||
|
||||
👶 New user migrating an existing repo
|
||||
|
||||
- They know their framework of choice
|
||||
- They know how npm workspaces work
|
||||
- They're smart and eager to learn
|
||||
- They know their framework of choice
|
||||
- They know how npm workspaces work
|
||||
- They're smart and eager to learn
|
||||
|
||||
👦 Intermediate User
|
||||
|
||||
- They know how to create an Nx repo or add Nx to an existing repo
|
||||
- They have heard the terms integrated and package-based
|
||||
- They know what a project is and how to make one
|
||||
- They understand how to run a task and the basics of caching
|
||||
- They can launch the graph
|
||||
- They know that it is possible to enforce project boundaries
|
||||
- They know how to create an Nx repo or add Nx to an existing repo
|
||||
- They have heard the terms integrated and package-based
|
||||
- They know what a project is and how to make one
|
||||
- They understand how to run a task and the basics of caching
|
||||
- They can launch the graph
|
||||
- They know that it is possible to enforce project boundaries
|
||||
|
||||
👨🦳 Advanced User
|
||||
|
||||
- They know everything about Nx except the specific piece of knowledge that is being taught by this document.
|
||||
- They know everything about Nx except the specific piece of knowledge that is being taught by this document.
|
||||
|
||||
### Outline
|
||||
|
||||
- Getting Started - These documents assume a new user and are generally concept guides with a lot of links to other parts of the site. There are some elements of recipes mixed in, but those should be kept to a minimum.
|
||||
- Tutorials - These are tutorials written for a new user. After completing one of these tutorials, the user should have enough knowledge to be an intermediate user.
|
||||
- Core Features - These are primarily recipes with a little concept mixed in. These documents should be short and provide the basic information that people will want 80% of the time and link to anything more complex. A new user should be able to click through these documents and skim them to get a good understanding of what Nx does without getting overwhelmed with details.
|
||||
- Concepts - These are concept guides written for a new user. Any recipe content should be split into a recipe document and linked.
|
||||
- More Concepts (or other categories under Concepts) - These are concept guides written for an intermediate user.
|
||||
- Recipes - These are recipes written for an advanced user.
|
||||
- Nx with Your Favorite Tech - These are tutorials written for an intermediate user.
|
||||
- Benchmarks - Reference documents linking to external resources.
|
||||
- Reference - Reference documents.
|
||||
- Getting Started - These documents assume a new user and are generally concept guides with a lot of links to other parts of the site. There are some elements of recipes mixed in, but those should be kept to a minimum.
|
||||
- Tutorials - These are tutorials written for a new user. After completing one of these tutorials, the user should have enough knowledge to be an intermediate user.
|
||||
- Core Features - These are primarily recipes with a little concept mixed in. These documents should be short and provide the basic information that people will want 80% of the time and link to anything more complex. A new user should be able to click through these documents and skim them to get a good understanding of what Nx does without getting overwhelmed with details.
|
||||
- Concepts - These are concept guides written for a new user. Any recipe content should be split into a recipe document and linked.
|
||||
- More Concepts (or other categories under Concepts) - These are concept guides written for an intermediate user.
|
||||
- Recipes - These are recipes written for an advanced user.
|
||||
- Nx with Your Favorite Tech - These are tutorials written for an intermediate user.
|
||||
- Benchmarks - Reference documents linking to external resources.
|
||||
- Reference - Reference documents.
|
||||
|
||||
## Markdown syntax available
|
||||
|
||||
@@ -64,8 +64,8 @@ Front matter is used to add metadata to your Markdown file (`title` & `descripti
|
||||
|
||||
If no Front matter is detected, the metadata will be populated with the following:
|
||||
|
||||
- `title`: first main title detected
|
||||
- `description`: first paragraph detected
|
||||
- `title`: first main title detected
|
||||
- `description`: first paragraph detected
|
||||
|
||||
```markdown
|
||||
---
|
||||
@@ -94,14 +94,14 @@ Your content goes here.
|
||||
{% /callout %}
|
||||
```
|
||||
|
||||
#### Deep Dives
|
||||
#### Disclosure
|
||||
|
||||
These are special callouts that are collapsed with the intention of containing more deep-dive information about the topic which isn't required to understand right away.
|
||||
A disclosure can be used for less important information that is initially collapsed.
|
||||
|
||||
```markdown
|
||||
{% callout type="deepdive" title="string" %}
|
||||
Your deep-dive content goes here.
|
||||
{% /callout %}
|
||||
{% disclosure title="string" %}
|
||||
Your content goes here.
|
||||
{% /disclosure %}
|
||||
```
|
||||
|
||||
#### Cards
|
||||
@@ -309,34 +309,34 @@ Embed a Project Details View that is identical what is shown in Nx Console or `n
|
||||
|
||||
```json
|
||||
{
|
||||
"project": {
|
||||
"name": "demo",
|
||||
"data": {
|
||||
"root": " packages/demo",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"dev": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"command": "vite dev"
|
||||
}
|
||||
},
|
||||
"build": {
|
||||
"executor": "nx:run-commands",
|
||||
"inputs": ["production", "^production"],
|
||||
"outputs": ["{projectRoot}/dist"],
|
||||
"options": {
|
||||
"command": "vite build"
|
||||
}
|
||||
}
|
||||
"project": {
|
||||
"name": "demo",
|
||||
"data": {
|
||||
"root": " packages/demo",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"dev": {
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"command": "vite dev"
|
||||
}
|
||||
},
|
||||
"build": {
|
||||
"executor": "nx:run-commands",
|
||||
"inputs": ["production", "^production"],
|
||||
"outputs": ["{projectRoot}/dist"],
|
||||
"options": {
|
||||
"command": "vite build"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sourceMap": {
|
||||
"targets": ["packages/demo/vite.config.ts", "@nx/vite"],
|
||||
"targets.dev": ["packages/demo/vite.config.ts", "@nx/vite"],
|
||||
"targets.build": ["packages/demo/vite.config.ts", "@nx/vite"]
|
||||
}
|
||||
},
|
||||
"sourceMap": {
|
||||
"targets": ["packages/demo/vite.config.ts", "@nx/vite"],
|
||||
"targets.dev": ["packages/demo/vite.config.ts", "@nx/vite"],
|
||||
"targets.build": ["packages/demo/vite.config.ts", "@nx/vite"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -352,65 +352,65 @@ Embed an Nx Graph visualization that can be panned by the user.
|
||||
|
||||
```json
|
||||
{
|
||||
"projects": [
|
||||
{
|
||||
"type": "app",
|
||||
"name": "app-changed",
|
||||
"data": {
|
||||
"tags": ["scope:cart"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "lib",
|
||||
"name": "lib",
|
||||
"data": {
|
||||
"tags": ["scope:cart"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "lib",
|
||||
"name": "lib2",
|
||||
"data": {
|
||||
"tags": ["scope:cart"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "lib",
|
||||
"name": "lib3",
|
||||
"data": {
|
||||
"tags": ["scope:cart"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"groupByFolder": false,
|
||||
"workspaceLayout": {
|
||||
"appsDir": "apps",
|
||||
"libsDir": "libs"
|
||||
},
|
||||
"dependencies": {
|
||||
"app-changed": [
|
||||
"projects": [
|
||||
{
|
||||
"target": "lib",
|
||||
"source": "app-changed",
|
||||
"type": "direct"
|
||||
}
|
||||
],
|
||||
"lib": [
|
||||
{
|
||||
"target": "lib2",
|
||||
"source": "lib",
|
||||
"type": "implicit"
|
||||
"type": "app",
|
||||
"name": "app-changed",
|
||||
"data": {
|
||||
"tags": ["scope:cart"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"target": "lib3",
|
||||
"source": "lib",
|
||||
"type": "direct"
|
||||
"type": "lib",
|
||||
"name": "lib",
|
||||
"data": {
|
||||
"tags": ["scope:cart"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "lib",
|
||||
"name": "lib2",
|
||||
"data": {
|
||||
"tags": ["scope:cart"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "lib",
|
||||
"name": "lib3",
|
||||
"data": {
|
||||
"tags": ["scope:cart"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"lib2": [],
|
||||
"lib3": []
|
||||
},
|
||||
"affectedProjectIds": []
|
||||
],
|
||||
"groupByFolder": false,
|
||||
"workspaceLayout": {
|
||||
"appsDir": "apps",
|
||||
"libsDir": "libs"
|
||||
},
|
||||
"dependencies": {
|
||||
"app-changed": [
|
||||
{
|
||||
"target": "lib",
|
||||
"source": "app-changed",
|
||||
"type": "direct"
|
||||
}
|
||||
],
|
||||
"lib": [
|
||||
{
|
||||
"target": "lib2",
|
||||
"source": "lib",
|
||||
"type": "implicit"
|
||||
},
|
||||
{
|
||||
"target": "lib3",
|
||||
"source": "lib",
|
||||
"type": "direct"
|
||||
}
|
||||
],
|
||||
"lib2": [],
|
||||
"lib3": []
|
||||
},
|
||||
"affectedProjectIds": []
|
||||
}
|
||||
```
|
||||
|
||||
@@ -421,9 +421,9 @@ Embed an Nx Graph visualization that can be panned by the user.
|
||||
|
||||
There are multiple versions of the `nx.dev` site.
|
||||
|
||||
- [canary.nx.dev](https://canary.nx.dev) contains the documentation on the `master` branch
|
||||
- [nx.dev](https://nx.dev) contains the documentation as of the latest release of Nx to npm. The main site will not include reference documentation for APIs that have been merged to the codebase, but not yet released to the public.
|
||||
- `[version].nx.dev` contains the documentation for that version of Nx. `[version]` in this case is the major version up to the current LTS version of Nx. So [18.nx.dev](https://18.nx.dev) will show the Nx documentation as of the last released version of Nx 18.
|
||||
- [canary.nx.dev](https://canary.nx.dev) contains the documentation on the `master` branch
|
||||
- [nx.dev](https://nx.dev) contains the documentation as of the latest release of Nx to npm. The main site will not include reference documentation for APIs that have been merged to the codebase, but not yet released to the public.
|
||||
- `[version].nx.dev` contains the documentation for that version of Nx. `[version]` in this case is the major version up to the current LTS version of Nx. So [18.nx.dev](https://18.nx.dev) will show the Nx documentation as of the last released version of Nx 18.
|
||||
|
||||
When a commit that contains documentation is merged into `master`, it will be immediately published to `canary.nx.dev`. Whenever a new release of Nx is published to npm, that documentation will then be available on the main site.
|
||||
|
||||
|
||||
@@ -12,14 +12,14 @@ In the last couple of months we have quadrupled the team and have done some amaz
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
- [New, Streamlined UI](#new-streamlined-ui)
|
||||
- [Prefetching and Faster Cache Uploading](#prefetching-and-faster-cache-uploading)
|
||||
- [DTE Just got Better](#dte-just-got-better)
|
||||
- [Direct Integration With GitHub, GitLab and Bitbucket](#direct-integration-with-github-gitlab-and-bitbucket)
|
||||
- [Enterprise Support](#enterprise-support)
|
||||
- [New, Simplified Plans and Pricing Model](#new-simplified-plans-and-pricing-model)
|
||||
- [Coming Next](#coming-next)
|
||||
- [Learn more](#learn-more)
|
||||
- [New, Streamlined UI](#new-streamlined-ui)
|
||||
- [Prefetching and Faster Cache Uploading](#prefetching-and-faster-cache-uploading)
|
||||
- [DTE Just got Better](#dte-just-got-better)
|
||||
- [Direct Integration With GitHub, GitLab and Bitbucket](#direct-integration-with-github-gitlab-and-bitbucket)
|
||||
- [Enterprise Support](#enterprise-support)
|
||||
- [New, Simplified Plans and Pricing Model](#new-simplified-plans-and-pricing-model)
|
||||
- [Coming Next](#coming-next)
|
||||
- [Learn more](#learn-more)
|
||||
|
||||
**Prefer a Video? We’ve got you Covered!**
|
||||
|
||||
@@ -80,9 +80,9 @@ We have extensive experience working with Fortune 500 companies, helping them sc
|
||||
|
||||
We’ve recently made a couple of improvements to our enterprise offering.
|
||||
|
||||
- **Helm Charts** — We added a **Helm chart** to simplify the process of deploying Nx Cloud to on-premises infrastructure, allowing organizations to quickly set up and manage their own instance of Nx Cloud within their secure environment.
|
||||
- **Stability improvements** — We significantly reworked our on-premises solution to be identical to our SaaS deployment. This revamp resulted in a more robust and reliable on-premises deployment of Nx Cloud, ensuring enterprise-grade performance and reliability.
|
||||
- **SSO** — We now support AWS Identity and Access Management (IAM) for seamless integration with existing AWS environments and the SAML protocol for a more flexible single sign-on integration across various providers. This enables organizations to leverage their existing identity management systems for authentication and authorization.
|
||||
- **Helm Charts** — We added a **Helm chart** to simplify the process of deploying Nx Cloud to on-premises infrastructure, allowing organizations to quickly set up and manage their own instance of Nx Cloud within their secure environment.
|
||||
- **Stability improvements** — We significantly reworked our on-premises solution to be identical to our SaaS deployment. This revamp resulted in a more robust and reliable on-premises deployment of Nx Cloud, ensuring enterprise-grade performance and reliability.
|
||||
- **SSO** — We now support AWS Identity and Access Management (IAM) for seamless integration with existing AWS environments and the SAML protocol for a more flexible single sign-on integration across various providers. This enables organizations to leverage their existing identity management systems for authentication and authorization.
|
||||
|
||||
Learn more at [enterprise](/enterprise).
|
||||
|
||||
@@ -90,7 +90,7 @@ Learn more at [enterprise](/enterprise).
|
||||
|
||||
Nx Cloud has evolved a lot since we first released it in 2020, and is changing even more in 2023. To better adapt to Nx Cloud being a critical CI tool, we changed our pricing model to be more consistent and predictable for CI workloads.
|
||||
|
||||
Nx Cloud’s previous pricing was based on time savings from Nx Cloud, which made sense when Nx Cloud was strictly a distributed caching service. The [new pricing model](/pricing) is based entirely on the number of CI pipeline executions per calendar month. We believe this is a simpler and more transparent model that should help you predict your costs far more easily.
|
||||
Nx Cloud’s previous pricing was based on time savings from Nx Cloud, which made sense when Nx Cloud was strictly a distributed caching service. The [new pricing model](https://nx.app/pricing) is based entirely on the number of CI pipeline executions per calendar month. We believe this is a simpler and more transparent model that should help you predict your costs far more easily.
|
||||
|
||||

|
||||
|
||||
@@ -100,7 +100,7 @@ Finally, the **Enterprise plan** is for companies that want full control over wh
|
||||
|
||||
All these changes should allow developers to choose the plan that best suits their needs and budget more easily, ensuring a seamless and transparent experience regarding pricing and subscription management.
|
||||
|
||||
Learn more at [https://nx.dev/pricing](/pricing).
|
||||
Learn more at [https://nx.app/pricing](https://nx.app/pricing).
|
||||
|
||||
## Coming Next
|
||||
|
||||
@@ -114,9 +114,9 @@ In addition, we are actively exploring ways to provide advanced analytics for yo
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -10,15 +10,15 @@ Over the last few weeks, we rebuilt one of Nx Console’s most liked features fr
|
||||
|
||||
You can use it today by installing the latest version of Nx Console for VSCode and JetBrains IDEs! 🎉🎉🎉
|
||||
|
||||
- [Nx Console on the VSCode Marketplace](https://marketplace.visualstudio.com/items?itemName=nrwl.angular-console)
|
||||
- [Nx Console on the JetBrains Marketplace](https://plugins.jetbrains.com/plugin/21060-nx-console)
|
||||
- [Nx Console on the VSCode Marketplace](https://marketplace.visualstudio.com/items?itemName=nrwl.angular-console)
|
||||
- [Nx Console on the JetBrains Marketplace](https://plugins.jetbrains.com/plugin/21060-nx-console)
|
||||
|
||||
If you’re curious to learn more about the rewrite and the motivations behind it, this is the blog post for you! We’ll touch on these topics and more:
|
||||
|
||||
- Why did we choose to rewrite?
|
||||
- What’s Lit and why did we use it over Angular?
|
||||
- How did the rewrite go and what Lit features were important for us?
|
||||
- What does the performance look like before and after?
|
||||
- Why did we choose to rewrite?
|
||||
- What’s Lit and why did we use it over Angular?
|
||||
- How did the rewrite go and what Lit features were important for us?
|
||||
- What does the performance look like before and after?
|
||||
|
||||
{% youtube src="https://www.youtube.com/embed/p455D4W7330?si=FRbiKJhGxT8dYzf9" /%}
|
||||
|
||||
@@ -54,17 +54,17 @@ Before I dive deeper into specifics, let’s have a look at the general architec
|
||||
|
||||
Nx Console is composed of 3 core parts:
|
||||
|
||||
- The **nxls** is a language server based on the [Language Server Protocol (LSP)](https://microsoft.github.io/language-server-protocol/) and acts as the “brain” of Nx Console. It analyzes your Nx workspace and provides information on it, including code completion and more.
|
||||
- The **Generate UI** is the form-based view for running Nx generators.
|
||||
- The **platform-specific wrappers**. These are written in Typescript and Kotlin and connect the rest of Nx Console to IDE-specific APIs. Having the other parts separate greatly reduces the amount of duplicated code we have to write in order to support multiple IDEs
|
||||
- The **nxls** is a language server based on the [Language Server Protocol (LSP)](https://microsoft.github.io/language-server-protocol/) and acts as the “brain” of Nx Console. It analyzes your Nx workspace and provides information on it, including code completion and more.
|
||||
- The **Generate UI** is the form-based view for running Nx generators.
|
||||
- The **platform-specific wrappers**. These are written in Typescript and Kotlin and connect the rest of Nx Console to IDE-specific APIs. Having the other parts separate greatly reduces the amount of duplicated code we have to write in order to support multiple IDEs
|
||||
|
||||
This architecture’s modularity meant we could quickly switch out the Generate UI for a new version without significantly impacting the rest of the codebase — only the parts that actually render the UI and communicate with it had to be adjusted slightly. It also allowed us to ensure backward compatibility: the old generate UI is still available via a feature toggle in the settings.
|
||||
|
||||
If you want to dive deeper, there are many more resources on the architecture of Nx Console and how it’s built:
|
||||
|
||||
- [In-depth blog post about expanding to JetBrains IDEs](https://blog.nrwl.io/expanding-nx-console-to-jetbrains-ides-8a5b80fff2d7?source=friends_link&sk=967080ea30bdbf9f8132f098a2cdd188)
|
||||
- [Accompanying Youtube video by Zack DeRose](https://www.youtube.com/watch?v=xUTm6GDqwJM)
|
||||
- [The Power of Nx Console — talk by Jon Cammisuli](https://www.youtube.com/watch?v=3C_9g9kt2KM)
|
||||
- [In-depth blog post about expanding to JetBrains IDEs](https://blog.nrwl.io/expanding-nx-console-to-jetbrains-ides-8a5b80fff2d7?source=friends_link&sk=967080ea30bdbf9f8132f098a2cdd188)
|
||||
- [Accompanying Youtube video by Zack DeRose](https://www.youtube.com/watch?v=xUTm6GDqwJM)
|
||||
- [The Power of Nx Console — talk by Jon Cammisuli](https://www.youtube.com/watch?v=3C_9g9kt2KM)
|
||||
|
||||
## Migrating to Lit: Step by Step
|
||||
|
||||
@@ -76,9 +76,9 @@ This generates an entire project for us, with a `tsconfig.json`, `index.html`, `
|
||||
|
||||
I also installed a couple of dependencies:
|
||||
|
||||
- The `@nx/esbuild` plugin because I like fast build times 🏎️
|
||||
- TailwindCSS because I don’t like writing CSS 🤫
|
||||
- `@vscode/webview-ui-toolkit` because it does all of the VSCode work for me 🤖
|
||||
- The `@nx/esbuild` plugin because I like fast build times 🏎️
|
||||
- TailwindCSS because I don’t like writing CSS 🤫
|
||||
- `@vscode/webview-ui-toolkit` because it does all of the VSCode work for me 🤖
|
||||
|
||||
This is really where Nx shines, because it allows you to take these tools and quickly patch them together and build a pipeline that does exactly what you need. And it also allows you to think about your workspace visually. This is what this is what my task graph for building the Lit app ultimately looks like:
|
||||
|
||||
@@ -86,15 +86,15 @@ This is really where Nx shines, because it allows you to take these tools and qu
|
||||
|
||||
You can see three build steps:
|
||||
|
||||
- `generate-ui-v2:_build` uses esbuild to bundle my Lit components written in Typescript and spits out a `main.js` file
|
||||
- `generate-ui-v2:extract-dependencies` copies the third party assets we need into the dist folder. Right now it’s just codicons `.css` and `.ttf` files.
|
||||
- `generate-ui-v2:build` finally runs tailwind over the bundled code. This could also be done with `postCss` or a custom `esbuild` plugin but running tailwind directly is the easier, so why complicate things?
|
||||
- `generate-ui-v2:_build` uses esbuild to bundle my Lit components written in Typescript and spits out a `main.js` file
|
||||
- `generate-ui-v2:extract-dependencies` copies the third party assets we need into the dist folder. Right now it’s just codicons `.css` and `.ttf` files.
|
||||
- `generate-ui-v2:build` finally runs tailwind over the bundled code. This could also be done with `postCss` or a custom `esbuild` plugin but running tailwind directly is the easier, so why complicate things?
|
||||
|
||||
> 💡 There are different ways to generate this visualisation for your own workspaces:
|
||||
>
|
||||
> - In VSCode, use the Nx Project View or the `Nx: Focus task in Graph` action
|
||||
> - In JetBrains IDEs, use the Nx Toolwindow or context menus
|
||||
> - In the command line, run `nx build {{your project}} --graph`
|
||||
> - In VSCode, use the Nx Project View or the `Nx: Focus task in Graph` action
|
||||
> - In JetBrains IDEs, use the Nx Toolwindow or context menus
|
||||
> - In the command line, run `nx build {{your project}} --graph`
|
||||
|
||||
In the bigger context of Nx Console, here’s what happens when you build the VSCode extension:
|
||||
|
||||
@@ -109,19 +109,19 @@ Lit is a very small library that provides useful abstractions over browser-nativ
|
||||
```ts {% fileName="main.ts" %}
|
||||
@customElement('root-element')
|
||||
export class Root extends LitElement {
|
||||
render() {
|
||||
return html`<p>Hello World</p>`;
|
||||
}
|
||||
render() {
|
||||
return html`<p>Hello World</p>`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```html {% fileName="index.html" %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<body>
|
||||
<script type="module" src="main.js"></script>
|
||||
<root-element></root-element>
|
||||
</body>
|
||||
<body>
|
||||
<script type="module" src="main.js"></script>
|
||||
<root-element></root-element>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
@@ -136,29 +136,29 @@ To communicate with the host IDE, we were able to reuse almost all the logic fro
|
||||
```ts {% fileName="main.ts" %}
|
||||
@customElement('root-element')
|
||||
export class Root extends LitElement {
|
||||
icc: IdeCommunicationController;
|
||||
icc: IdeCommunicationController;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.icc = new IdeCommunicationController(this);
|
||||
}
|
||||
render() {
|
||||
return html`${JSON.stringify(this.icc.generatorSchema)}`;
|
||||
}
|
||||
constructor() {
|
||||
super();
|
||||
this.icc = new IdeCommunicationController(this);
|
||||
}
|
||||
render() {
|
||||
return html`${JSON.stringify(this.icc.generatorSchema)}`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts {% fileName="ide-communication-controller.ts" %}
|
||||
// ide-communication-controller.ts
|
||||
export class IdeCommunicationController implements ReactiveController {
|
||||
generatorSchema: GeneratorSchema | undefined;
|
||||
constructor(private host: ReactiveControllerHost) {}
|
||||
// ...
|
||||
private handleMessageFromIde(message: InputMessage) {
|
||||
// ...
|
||||
this.generatorSchema = message.payload;
|
||||
this.host.requestUpdate();
|
||||
}
|
||||
generatorSchema: GeneratorSchema | undefined;
|
||||
constructor(private host: ReactiveControllerHost) {}
|
||||
// ...
|
||||
private handleMessageFromIde(message: InputMessage) {
|
||||
// ...
|
||||
this.generatorSchema = message.payload;
|
||||
this.host.requestUpdate();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -170,42 +170,42 @@ The core part of the UI is the form. We built all kinds of inputs: text fields,
|
||||
|
||||
```ts {% fileName="field-mixin.ts" %}
|
||||
const Field = (superClass) =>
|
||||
class extends superClass {
|
||||
// we can define (reactive) properties that every field is going to need
|
||||
@property()
|
||||
option: Option;
|
||||
protected get fieldId(): string {
|
||||
return `${this.option.name}-field`;
|
||||
}
|
||||
class extends superClass {
|
||||
// we can define (reactive) properties that every field is going to need
|
||||
@property()
|
||||
option: Option;
|
||||
protected get fieldId(): string {
|
||||
return `${this.option.name}-field`;
|
||||
}
|
||||
|
||||
// we can define methods that should be available to all fields
|
||||
dispatchValue(value: string) {
|
||||
// ...
|
||||
}
|
||||
};
|
||||
// we can define methods that should be available to all fields
|
||||
dispatchValue(value: string) {
|
||||
// ...
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
```ts {% fileName="field-wrapper-mixin.ts" %}
|
||||
const FieldWrapper = (superClass) =>
|
||||
class extends superClass {
|
||||
// we can define a render() method so that fields are all rendered the same
|
||||
protected render() {
|
||||
return html` <label for="${this.fieldId}">${this.option.name}</label>
|
||||
<p>${this.option.description}</p>
|
||||
${this.renderField()}`;
|
||||
}
|
||||
};
|
||||
class extends superClass {
|
||||
// we can define a render() method so that fields are all rendered the same
|
||||
protected render() {
|
||||
return html` <label for="${this.fieldId}">${this.option.name}</label>
|
||||
<p>${this.option.description}</p>
|
||||
${this.renderField()}`;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
```ts {% fileName="input-field.ts" %}
|
||||
@customElement('input-field')
|
||||
export class InputField extends FieldWrapper(Field(LitElement)) {
|
||||
renderField() {
|
||||
return html` <input
|
||||
id="${this.fieldId}"
|
||||
@input="${(e) => this.dispatchValue(e.target.value)}"
|
||||
/>`;
|
||||
}
|
||||
renderField() {
|
||||
return html` <input
|
||||
id="${this.fieldId}"
|
||||
@input="${(e) => this.dispatchValue(e.target.value)}"
|
||||
/>`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -225,37 +225,37 @@ Have a look at the following example:
|
||||
|
||||
```ts {% fileName="editor-context.ts" %}
|
||||
export const editorContext = createContext<'vscode' | 'intellij'>(
|
||||
Symbol('editor')
|
||||
Symbol('editor')
|
||||
);
|
||||
|
||||
const EditorContext = (superClass) =>
|
||||
class extends superClass {
|
||||
@consume({ context: editorContext })
|
||||
@state()
|
||||
editor: 'vscode' | 'intellij';
|
||||
};
|
||||
class extends superClass {
|
||||
@consume({ context: editorContext })
|
||||
@state()
|
||||
editor: 'vscode' | 'intellij';
|
||||
};
|
||||
```
|
||||
|
||||
```ts {% fileName="ide-communication-controller.ts" %}
|
||||
export class IdeCommunicationController implements ReactiveController {
|
||||
// ...
|
||||
constructor(private host: ReactiveElement) {
|
||||
const editor = isVscode() ? 'vscode' : 'intellij';
|
||||
// provide the context to all DOM children of the host element
|
||||
new ContextProvider(host, {
|
||||
context: editorContext,
|
||||
initialValue: editor,
|
||||
});
|
||||
}
|
||||
// ...
|
||||
constructor(private host: ReactiveElement) {
|
||||
const editor = isVscode() ? 'vscode' : 'intellij';
|
||||
// provide the context to all DOM children of the host element
|
||||
new ContextProvider(host, {
|
||||
context: editorContext,
|
||||
initialValue: editor,
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts {% fileName="some-component.ts" %}
|
||||
@customElement('some-component')
|
||||
export class SomeComponent extends EditorContext(LitElement) {
|
||||
render() {
|
||||
return html`<p>I am rendered in ${this.editor}</p>`;
|
||||
}
|
||||
render() {
|
||||
return html`<p>I am rendered in ${this.editor}</p>`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -320,9 +320,9 @@ So keep your eyes peeled for announcements and let us know via GitHub or Twitter
|
||||
|
||||
Nx Console is a tool by developers for developers and there’s one thing we love — keyboard shortcuts. So of course we had to build some in. In addition to being keyboard-friendly and tabbable, you can do the following:
|
||||
|
||||
- `Cmd/Ctrl + Enter` to run the generator
|
||||
- `Cmd/Ctrl + Shift + Enter` to start a dry run
|
||||
- `Cmd/Ctrl + Shift + S` to focus the search bar and look for a specific option. Just `tab` to get back to the form
|
||||
- `Cmd/Ctrl + Enter` to run the generator
|
||||
- `Cmd/Ctrl + Shift + Enter` to start a dry run
|
||||
- `Cmd/Ctrl + Shift + S` to focus the search bar and look for a specific option. Just `tab` to get back to the form
|
||||
|
||||
If the prettier UI and better performance haven’t convinced you, this surely will! 😉
|
||||
|
||||
@@ -330,9 +330,9 @@ If the prettier UI and better performance haven’t convinced you, this surely w
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -19,19 +19,19 @@ In this blog post, we’ll explore how to combine the strengths of Nx and Qwik t
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
- [Creating the Workspace](#creating-the-workspace)
|
||||
- [Generate the App](#generate-the-app)
|
||||
- [Generate a new Route](#generate-a-new-route)
|
||||
- [Build a Basic UI](#build-a-basic-ui)
|
||||
- [Generate a Library](#generate-a-library)
|
||||
- [Add a Qwik Context](#add-a-qwik-context)
|
||||
- [Using the Context](#using-the-context)
|
||||
- [Adding a `routeLoader$` to load data on Navigation](#adding-a-routeloader-to-load-data-on-navigation)
|
||||
- [Handle the Form Action to add todos](#handle-the-form-action-to-add-todos)
|
||||
- [Improve the Architecture](#improve-the-architecture)
|
||||
- [Conclusion](#conclusion)
|
||||
- [Further Reading](#further-reading)
|
||||
- [Learn more](#learn-more)
|
||||
- [Creating the Workspace](#creating-the-workspace)
|
||||
- [Generate the App](#generate-the-app)
|
||||
- [Generate a new Route](#generate-a-new-route)
|
||||
- [Build a Basic UI](#build-a-basic-ui)
|
||||
- [Generate a Library](#generate-a-library)
|
||||
- [Add a Qwik Context](#add-a-qwik-context)
|
||||
- [Using the Context](#using-the-context)
|
||||
- [Adding a `routeLoader$` to load data on Navigation](#adding-a-routeloader-to-load-data-on-navigation)
|
||||
- [Handle the Form Action to add todos](#handle-the-form-action-to-add-todos)
|
||||
- [Improve the Architecture](#improve-the-architecture)
|
||||
- [Conclusion](#conclusion)
|
||||
- [Further Reading](#further-reading)
|
||||
- [Learn more](#learn-more)
|
||||
|
||||
You can learn more about this integration in the video below:
|
||||
|
||||
@@ -93,7 +93,7 @@ The newly created file should look like this:
|
||||
import { component$ } from '@builder.io/qwik';
|
||||
|
||||
export default component$(() => {
|
||||
return <div>This is the todo</div>;
|
||||
return <div>This is the todo</div>;
|
||||
});
|
||||
```
|
||||
|
||||
@@ -114,21 +114,21 @@ import { component$ } from '@builder.io/qwik';
|
||||
import { Form } from '@builder.io/qwik-city';
|
||||
|
||||
export default component$(() => {
|
||||
return (
|
||||
<div>
|
||||
<h1>Todos</h1>
|
||||
return (
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" /> {'My First Todo'}
|
||||
</label>
|
||||
<h1>Todos</h1>
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" /> {'My First Todo'}
|
||||
</label>
|
||||
</div>
|
||||
<Form>
|
||||
<input type="hidden" name="id" value={1} />
|
||||
<input type="text" name="message" />
|
||||
<button type="submit">Add</button>
|
||||
</Form>
|
||||
</div>
|
||||
<Form>
|
||||
<input type="hidden" name="id" value={1} />
|
||||
<input type="text" name="message" />
|
||||
<button type="submit">Add</button>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
@@ -180,8 +180,8 @@ Create `libs/data-access/src/lib/api.ts` and add the following:
|
||||
|
||||
```ts {% fileName="libs/data-access/src/lib/api.ts" %}
|
||||
export interface Todo {
|
||||
id: number;
|
||||
message: string;
|
||||
id: number;
|
||||
message: string;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -189,27 +189,27 @@ Next, let’s create a new file `libs/data-access/src/lib/todo.context.tsx` and
|
||||
|
||||
```tsx {% fileName="libs/data-access/src/lib/todo.context.tsx" %}
|
||||
import {
|
||||
component$,
|
||||
createContextId,
|
||||
Slot,
|
||||
useContextProvider,
|
||||
useStore,
|
||||
component$,
|
||||
createContextId,
|
||||
Slot,
|
||||
useContextProvider,
|
||||
useStore,
|
||||
} from '@builder.io/qwik';
|
||||
import { Todo } from './api';
|
||||
|
||||
interface TodoStore {
|
||||
todos: Todo[];
|
||||
lastId: number;
|
||||
todos: Todo[];
|
||||
lastId: number;
|
||||
}
|
||||
|
||||
export const TodoContext = createContextId<TodoStore>('todo.context');
|
||||
export const TodoContextProvider = component$(() => {
|
||||
const todoStore = useStore<TodoStore>({
|
||||
todos: [],
|
||||
lastId: 0,
|
||||
});
|
||||
useContextProvider(TodoContext, todoStore);
|
||||
return <Slot />;
|
||||
const todoStore = useStore<TodoStore>({
|
||||
todos: [],
|
||||
lastId: 0,
|
||||
});
|
||||
useContextProvider(TodoContext, todoStore);
|
||||
return <Slot />;
|
||||
});
|
||||
```
|
||||
|
||||
@@ -226,37 +226,37 @@ Let’s update the root page to add our Context Provider. Open `apps/todo/src/ro
|
||||
```tsx {% fileName="apps/todo/src/root.tsx" %}
|
||||
import { component$, useStyles$ } from '@builder.io/qwik';
|
||||
import {
|
||||
QwikCityProvider,
|
||||
RouterOutlet,
|
||||
ServiceWorkerRegister,
|
||||
QwikCityProvider,
|
||||
RouterOutlet,
|
||||
ServiceWorkerRegister,
|
||||
} from '@builder.io/qwik-city';
|
||||
import { RouterHead } from './components/router-head/router-head';
|
||||
import globalStyles from './global.css?inline';
|
||||
import { TodoContextProvider } from '@qwik-todo-app/data-access';
|
||||
|
||||
export default component$(() => {
|
||||
/**
|
||||
* The root of a QwikCity site always start with the <QwikCityProvider> component,
|
||||
* immediately followed by the document's <head> and <body>.
|
||||
*
|
||||
* Don't remove the `<head>` and `<body>` elements.
|
||||
*/
|
||||
useStyles$(globalStyles);
|
||||
return (
|
||||
<QwikCityProvider>
|
||||
<TodoContextProvider>
|
||||
<head>
|
||||
<meta charSet="utf-8" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<RouterHead />
|
||||
</head>
|
||||
<body lang="en">
|
||||
<RouterOutlet />
|
||||
<ServiceWorkerRegister />
|
||||
</body>
|
||||
</TodoContextProvider>
|
||||
</QwikCityProvider>
|
||||
);
|
||||
/**
|
||||
* The root of a QwikCity site always start with the <QwikCityProvider> component,
|
||||
* immediately followed by the document's <head> and <body>.
|
||||
*
|
||||
* Don't remove the `<head>` and `<body>` elements.
|
||||
*/
|
||||
useStyles$(globalStyles);
|
||||
return (
|
||||
<QwikCityProvider>
|
||||
<TodoContextProvider>
|
||||
<head>
|
||||
<meta charSet="utf-8" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<RouterHead />
|
||||
</head>
|
||||
<body lang="en">
|
||||
<RouterOutlet />
|
||||
<ServiceWorkerRegister />
|
||||
</body>
|
||||
</TodoContextProvider>
|
||||
</QwikCityProvider>
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
@@ -277,24 +277,24 @@ import { Form } from '@builder.io/qwik-city';
|
||||
import { TodoContext } from '@qwik-todo-app/data-access';
|
||||
|
||||
export default component$(() => {
|
||||
const todoStore = useContext(TodoContext);
|
||||
return (
|
||||
<div>
|
||||
<h1>Todos</h1>
|
||||
{todoStore.todos.map((t) => (
|
||||
<div key={`todo-${t.id}`}>
|
||||
<label>
|
||||
<input type="checkbox" /> {t.message}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
<Form>
|
||||
<input type="hidden" name="id" value={1} />
|
||||
<input type="text" name="message" />
|
||||
<button type="submit">Add</button>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
const todoStore = useContext(TodoContext);
|
||||
return (
|
||||
<div>
|
||||
<h1>Todos</h1>
|
||||
{todoStore.todos.map((t) => (
|
||||
<div key={`todo-${t.id}`}>
|
||||
<label>
|
||||
<input type="checkbox" /> {t.message}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
<Form>
|
||||
<input type="hidden" name="id" value={1} />
|
||||
<input type="text" name="message" />
|
||||
<button type="submit">Add</button>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
@@ -314,37 +314,37 @@ We’ll start by updating our `libs/data-access/src/lib/api.ts` to add our in-me
|
||||
|
||||
```ts {% fileName="libs/data-access/src/lib/api.ts" %}
|
||||
export interface Todo {
|
||||
id: number;
|
||||
message: string;
|
||||
id: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
interface DB {
|
||||
store: Record<string, any[]>;
|
||||
get: (storeName: string) => any[];
|
||||
set: (storeName: string, value: any[]) => boolean;
|
||||
add: (storeName: string, value: any) => boolean;
|
||||
store: Record<string, any[]>;
|
||||
get: (storeName: string) => any[];
|
||||
set: (storeName: string, value: any[]) => boolean;
|
||||
add: (storeName: string, value: any) => boolean;
|
||||
}
|
||||
export const db: DB = {
|
||||
store: { todos: [] },
|
||||
get(storeName) {
|
||||
return db.store[storeName];
|
||||
},
|
||||
set(storeName, value) {
|
||||
try {
|
||||
db.store[storeName] = value;
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
add(storeName, value) {
|
||||
try {
|
||||
db.store[storeName].push(value);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
store: { todos: [] },
|
||||
get(storeName) {
|
||||
return db.store[storeName];
|
||||
},
|
||||
set(storeName, value) {
|
||||
try {
|
||||
db.store[storeName] = value;
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
add(storeName, value) {
|
||||
try {
|
||||
db.store[storeName].push(value);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
@@ -358,51 +358,51 @@ import { Form, routeLoader$ } from '@builder.io/qwik-city';
|
||||
import { TodoContext, db } from '@qwik-todo-app/data-access';
|
||||
|
||||
export const useGetTodos = routeLoader$(() => {
|
||||
// A network request or db connection could be made here to fetch persisted todos
|
||||
// For illustrative purposes, we're going to seed a rudimentary in-memory DB if it hasn't been already
|
||||
// Then return the value from it
|
||||
if (db.get('todos')?.length === 0) {
|
||||
db.set('todos', [
|
||||
{
|
||||
id: 1,
|
||||
message: 'First todo',
|
||||
},
|
||||
]);
|
||||
}
|
||||
const todos: Todo[] = db.get('todos');
|
||||
const lastId = [...todos].sort((a, b) => b.id - a.id)[0].id;
|
||||
return { todos, lastId };
|
||||
// A network request or db connection could be made here to fetch persisted todos
|
||||
// For illustrative purposes, we're going to seed a rudimentary in-memory DB if it hasn't been already
|
||||
// Then return the value from it
|
||||
if (db.get('todos')?.length === 0) {
|
||||
db.set('todos', [
|
||||
{
|
||||
id: 1,
|
||||
message: 'First todo',
|
||||
},
|
||||
]);
|
||||
}
|
||||
const todos: Todo[] = db.get('todos');
|
||||
const lastId = [...todos].sort((a, b) => b.id - a.id)[0].id;
|
||||
return { todos, lastId };
|
||||
});
|
||||
export default component$(() => {
|
||||
const todoStore = useContext(TodoContext);
|
||||
const persistedTodos = useGetTodos();
|
||||
useTask$(({ track }) => {
|
||||
track(() => persistedTodos.value);
|
||||
if (persistedTodos.value) {
|
||||
todoStore.todos = persistedTodos.value.todos;
|
||||
todoStore.lastId =
|
||||
todoStore.lastId > persistedTodos.value.lastId
|
||||
? todoStore.lastId
|
||||
: persistedTodos.value.lastId;
|
||||
}
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<h1>Todos</h1>
|
||||
{todoStore.todos.map((t) => (
|
||||
<div key={`todo-${t.id}`}>
|
||||
<label>
|
||||
<input type="checkbox" /> {t.message}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
<Form>
|
||||
<input type="hidden" name="id" value={1} />
|
||||
<input type="text" name="message" />
|
||||
<button type="submit">Add</button>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
const todoStore = useContext(TodoContext);
|
||||
const persistedTodos = useGetTodos();
|
||||
useTask$(({ track }) => {
|
||||
track(() => persistedTodos.value);
|
||||
if (persistedTodos.value) {
|
||||
todoStore.todos = persistedTodos.value.todos;
|
||||
todoStore.lastId =
|
||||
todoStore.lastId > persistedTodos.value.lastId
|
||||
? todoStore.lastId
|
||||
: persistedTodos.value.lastId;
|
||||
}
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<h1>Todos</h1>
|
||||
{todoStore.todos.map((t) => (
|
||||
<div key={`todo-${t.id}`}>
|
||||
<label>
|
||||
<input type="checkbox" /> {t.message}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
<Form>
|
||||
<input type="hidden" name="id" value={1} />
|
||||
<input type="text" name="message" />
|
||||
<button type="submit">Add</button>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
@@ -422,64 +422,64 @@ import { Form, routeLoader$ } from '@builder.io/qwik-city';
|
||||
import { TodoContext, db } from '@qwik-todo-app/data-access';
|
||||
|
||||
export const useGetTodos = routeLoader$(() => {
|
||||
// A network request or db connection could be made here to fetch persisted todos
|
||||
// For illustrative purposes, we're going to seed a rudimentary in-memory DB if it hasn't been already
|
||||
// Then return the value from it
|
||||
if (db.get('todos')?.length === 0) {
|
||||
db.set('todos', [
|
||||
{
|
||||
id: 1,
|
||||
message: 'First todo',
|
||||
},
|
||||
]);
|
||||
}
|
||||
const todos: Todo[] = db.get('todos');
|
||||
const lastId = [...todos].sort((a, b) => b.id - a.id)[0].id;
|
||||
return { todos, lastId };
|
||||
// A network request or db connection could be made here to fetch persisted todos
|
||||
// For illustrative purposes, we're going to seed a rudimentary in-memory DB if it hasn't been already
|
||||
// Then return the value from it
|
||||
if (db.get('todos')?.length === 0) {
|
||||
db.set('todos', [
|
||||
{
|
||||
id: 1,
|
||||
message: 'First todo',
|
||||
},
|
||||
]);
|
||||
}
|
||||
const todos: Todo[] = db.get('todos');
|
||||
const lastId = [...todos].sort((a, b) => b.id - a.id)[0].id;
|
||||
return { todos, lastId };
|
||||
});
|
||||
export const useAddTodo = routeAction$(
|
||||
(todo: { id: string; message: string }) => {
|
||||
const success = db.add('todos', {
|
||||
id: parseInt(todo.id),
|
||||
message: todo.message,
|
||||
});
|
||||
return { success };
|
||||
},
|
||||
zod$({ id: z.string(), message: z.string() })
|
||||
(todo: { id: string; message: string }) => {
|
||||
const success = db.add('todos', {
|
||||
id: parseInt(todo.id),
|
||||
message: todo.message,
|
||||
});
|
||||
return { success };
|
||||
},
|
||||
zod$({ id: z.string(), message: z.string() })
|
||||
);
|
||||
export default component$(() => {
|
||||
const todoStore = useContext(TodoContext);
|
||||
const persistedTodos = useGetTodos();
|
||||
const addTodoAction = useAddTodo();
|
||||
const todoStore = useContext(TodoContext);
|
||||
const persistedTodos = useGetTodos();
|
||||
const addTodoAction = useAddTodo();
|
||||
|
||||
useTask$(({ track }) => {
|
||||
track(() => persistedTodos.value);
|
||||
if (persistedTodos.value) {
|
||||
todoStore.todos = persistedTodos.value.todos;
|
||||
todoStore.lastId =
|
||||
todoStore.lastId > persistedTodos.value.lastId
|
||||
? todoStore.lastId
|
||||
: persistedTodos.value.lastId;
|
||||
}
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<h1>Todos</h1>
|
||||
{todoStore.todos.map((t) => (
|
||||
<div key={`todo-${t.id}`}>
|
||||
<label>
|
||||
<input type="checkbox" /> {t.message}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
<Form action={addTodoAction}>
|
||||
<input type="hidden" name="id" value={todoStore.lastId + 1} />
|
||||
<input type="text" name="message" />
|
||||
<button type="submit">Add</button>
|
||||
</Form>
|
||||
{addTodoAction.value?.success && <p>Todo added!</p>}
|
||||
</div>
|
||||
);
|
||||
useTask$(({ track }) => {
|
||||
track(() => persistedTodos.value);
|
||||
if (persistedTodos.value) {
|
||||
todoStore.todos = persistedTodos.value.todos;
|
||||
todoStore.lastId =
|
||||
todoStore.lastId > persistedTodos.value.lastId
|
||||
? todoStore.lastId
|
||||
: persistedTodos.value.lastId;
|
||||
}
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<h1>Todos</h1>
|
||||
{todoStore.todos.map((t) => (
|
||||
<div key={`todo-${t.id}`}>
|
||||
<label>
|
||||
<input type="checkbox" /> {t.message}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
<Form action={addTodoAction}>
|
||||
<input type="hidden" name="id" value={todoStore.lastId + 1} />
|
||||
<input type="text" name="message" />
|
||||
<button type="submit">Add</button>
|
||||
</Form>
|
||||
{addTodoAction.value?.success && <p>Todo added!</p>}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
@@ -495,27 +495,27 @@ To separate the logic, create a new file `libs/data-access/src/lib/todos.ts` and
|
||||
import { db, Todo } from './api';
|
||||
|
||||
export function getTodos() {
|
||||
// A network request or db connection could be made here to fetch persisted todos
|
||||
// For illustrative purposes, we're going to seed a rudimentary in-memory DB if it hasn't been already
|
||||
// Then return the value from it
|
||||
if (db.get('todos')?.length === 0) {
|
||||
db.set('todos', [
|
||||
{
|
||||
id: 1,
|
||||
message: 'First todo',
|
||||
},
|
||||
]);
|
||||
}
|
||||
const todos: Todo[] = db.get('todos');
|
||||
const lastId = [...todos].sort((a, b) => b.id - a.id)[0].id;
|
||||
return { todos, lastId };
|
||||
// A network request or db connection could be made here to fetch persisted todos
|
||||
// For illustrative purposes, we're going to seed a rudimentary in-memory DB if it hasn't been already
|
||||
// Then return the value from it
|
||||
if (db.get('todos')?.length === 0) {
|
||||
db.set('todos', [
|
||||
{
|
||||
id: 1,
|
||||
message: 'First todo',
|
||||
},
|
||||
]);
|
||||
}
|
||||
const todos: Todo[] = db.get('todos');
|
||||
const lastId = [...todos].sort((a, b) => b.id - a.id)[0].id;
|
||||
return { todos, lastId };
|
||||
}
|
||||
export function addTodo(todo: { id: string; message: string }) {
|
||||
const success = db.add('todos', {
|
||||
id: parseInt(todo.id),
|
||||
message: todo.message,
|
||||
});
|
||||
return { success };
|
||||
const success = db.add('todos', {
|
||||
id: parseInt(todo.id),
|
||||
message: todo.message,
|
||||
});
|
||||
return { success };
|
||||
}
|
||||
```
|
||||
|
||||
@@ -532,51 +532,51 @@ Finally, let’s update `apps/todo/src/routes/todo/index.tsx` to use our newly c
|
||||
```tsx {% fileName="apps/todo/src/routes/todo/index.tsx" %}
|
||||
import { component$, useContext, useTask$ } from '@builder.io/qwik';
|
||||
import {
|
||||
Form,
|
||||
routeAction$,
|
||||
routeLoader$,
|
||||
z,
|
||||
zod$,
|
||||
Form,
|
||||
routeAction$,
|
||||
routeLoader$,
|
||||
z,
|
||||
zod$,
|
||||
} from '@builder.io/qwik-city';
|
||||
import { addTodo, getTodos, TodoContext } from '@acme/data-access';
|
||||
|
||||
export const useGetTodos = routeLoader$(() => getTodos());
|
||||
export const useAddTodo = routeAction$(
|
||||
(todo) => addTodo(todo),
|
||||
zod$({ id: z.string(), message: z.string() })
|
||||
(todo) => addTodo(todo),
|
||||
zod$({ id: z.string(), message: z.string() })
|
||||
);
|
||||
export default component$(() => {
|
||||
const todoStore = useContext(TodoContext);
|
||||
const persistedTodos = useGetTodos();
|
||||
const addTodoAction = useAddTodo();
|
||||
useTask$(({ track }) => {
|
||||
track(() => persistedTodos.value);
|
||||
if (persistedTodos.value) {
|
||||
todoStore.todos = persistedTodos.value.todos;
|
||||
todoStore.lastId =
|
||||
todoStore.lastId > persistedTodos.value.lastId
|
||||
? todoStore.lastId
|
||||
: persistedTodos.value.lastId;
|
||||
}
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<h1>Todos</h1>
|
||||
{todoStore.todos.map((t) => (
|
||||
<div key={`todo-${t.id}`}>
|
||||
<label>
|
||||
<input type="checkbox" /> {t.message}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
<Form action={addTodoAction}>
|
||||
<input type="hidden" name="id" value={todoStore.lastId + 1} />
|
||||
<input type="text" name="message" />
|
||||
<button type="submit">Add</button>
|
||||
</Form>
|
||||
{addTodoAction.value?.success && <p>Todo added!</p>}
|
||||
</div>
|
||||
);
|
||||
const todoStore = useContext(TodoContext);
|
||||
const persistedTodos = useGetTodos();
|
||||
const addTodoAction = useAddTodo();
|
||||
useTask$(({ track }) => {
|
||||
track(() => persistedTodos.value);
|
||||
if (persistedTodos.value) {
|
||||
todoStore.todos = persistedTodos.value.todos;
|
||||
todoStore.lastId =
|
||||
todoStore.lastId > persistedTodos.value.lastId
|
||||
? todoStore.lastId
|
||||
: persistedTodos.value.lastId;
|
||||
}
|
||||
});
|
||||
return (
|
||||
<div>
|
||||
<h1>Todos</h1>
|
||||
{todoStore.todos.map((t) => (
|
||||
<div key={`todo-${t.id}`}>
|
||||
<label>
|
||||
<input type="checkbox" /> {t.message}
|
||||
</label>
|
||||
</div>
|
||||
))}
|
||||
<Form action={addTodoAction}>
|
||||
<input type="hidden" name="id" value={todoStore.lastId + 1} />
|
||||
<input type="text" name="message" />
|
||||
<button type="submit">Add</button>
|
||||
</Form>
|
||||
{addTodoAction.value?.success && <p>Todo added!</p>}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
@@ -594,18 +594,18 @@ This journey through Qwik and Nx demonstrates how thoughtful architecture and th
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [Qwik](https://qwik.dev/)
|
||||
- [qwik-nx](https://github.com/qwikifiers/qwik-nx)
|
||||
- [Enforce Module Boundaries](/features/enforce-module-boundaries)
|
||||
- [Nx Core Concepts](/concepts)
|
||||
- [Qwik](https://qwik.dev/)
|
||||
- [qwik-nx](https://github.com/qwikifiers/qwik-nx)
|
||||
- [Enforce Module Boundaries](/features/enforce-module-boundaries)
|
||||
- [Nx Core Concepts](/concepts)
|
||||
|
||||
---
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -13,9 +13,9 @@ Victor and I are excited to announce that Nx has raised another $16M in a Series
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -38,8 +38,8 @@ Juri also highlighted the [Nx Champions](/community) program that got launched t
|
||||
|
||||
Finally there were also two **announcements**:
|
||||
|
||||
- the Nx team decided to move off Medium for a better publishing experience but mainly also to avoid the paywall, something that the team has no control over. The new blog is currently being built and will be hosted at [blog](/blog). This also allows to better resurface information by being able to integrate blog articles into the Nx docs search and make them also accessible to the Nx AI Assistant which was the 2nd announcement.
|
||||
- the **Nx AI Assistant** is an experiment the team is running to use AI to improve discoverability on the Nx docs. The ChatGPT powered assistant allows to ask natural language questions and responds based on the Nx docs training data, also including links to the sources. Try it out at [ai-chat](/ai-chat) and use the feedback thumbs-up/down buttons to help improve it over time 🙏.
|
||||
- the Nx team decided to move off Medium for a better publishing experience but mainly also to avoid the paywall, something that the team has no control over. The new blog is currently being built and will be hosted at [blog](/blog). This also allows to better resurface information by being able to integrate blog articles into the Nx docs search and make them also accessible to the Nx AI Assistant which was the 2nd announcement.
|
||||
- the **Nx AI Assistant** is an experiment the team is running to use AI to improve discoverability on the Nx docs. The ChatGPT powered assistant allows to ask natural language questions and responds based on the Nx docs training data, also including links to the sources. Try it out at [ai-chat](/ai-chat) and use the feedback thumbs-up/down buttons to help improve it over time 🙏.
|
||||
|
||||
Also, Nx is open source: [https://github.com/nrwl/nx](https://github.com/nrwl/nx). Contribute! And while you’re there, don’t forget to give us a star 😃.
|
||||
|
||||
@@ -63,11 +63,11 @@ This might be manageable in a static repository setup, but monorepos introduce a
|
||||
|
||||
Victor critiqued that most current CI setups are:
|
||||
|
||||
- Oriented towards machines
|
||||
- Low-level in their configuration
|
||||
- Maintenance-heavy
|
||||
- Detached from developer intentions
|
||||
- Challenging to implement with monorepos
|
||||
- Oriented towards machines
|
||||
- Low-level in their configuration
|
||||
- Maintenance-heavy
|
||||
- Detached from developer intentions
|
||||
- Challenging to implement with monorepos
|
||||
|
||||
The big question: how can we revolutionize CI? Victor then showcased a demo workspace and highlights where the complexity of setting up CI comes from:
|
||||
|
||||
@@ -75,10 +75,10 @@ The big question: how can we revolutionize CI? Victor then showcased a demo work
|
||||
|
||||
Even running e2e tests on CI requires:
|
||||
|
||||
- Building the application to be tested to produce an artifact
|
||||
- That usually requires first building all libraries the app depends on, in the correct order
|
||||
- Once all libraries are built, the application itself can be build
|
||||
- Finally e2e can be run on the application artifact
|
||||
- Building the application to be tested to produce an artifact
|
||||
- That usually requires first building all libraries the app depends on, in the correct order
|
||||
- Once all libraries are built, the application itself can be build
|
||||
- Finally e2e can be run on the application artifact
|
||||
|
||||
Notice, since we want to do this as fast as possible, we want to parallelize these operations across machines. This involves also taking care of transferring build artifacts between them.
|
||||
|
||||
@@ -86,17 +86,17 @@ This is where **Nx Cloud Workflows** shines. It enables developers to draft CI c
|
||||
|
||||
```yaml
|
||||
env:
|
||||
NODE_OPTIONS: '--max_old_space_size=4096'
|
||||
NODE_OPTIONS: '--max_old_space_size=4096'
|
||||
setup:
|
||||
- name: Git Checkout
|
||||
uses: 'nx-cloud-steps/checkout'
|
||||
- name: Npm Install
|
||||
uses: 'nx-cloud-steps/npm-install'
|
||||
- name: Git Checkout
|
||||
uses: 'nx-cloud-steps/checkout'
|
||||
- name: Npm Install
|
||||
uses: 'nx-cloud-steps/npm-install'
|
||||
steps:
|
||||
- name: CI Checks
|
||||
parallel-scripts: |
|
||||
nx affected -t build e2e --parallel=1
|
||||
nx affected -t test lint --parallel=3
|
||||
- name: CI Checks
|
||||
parallel-scripts: |
|
||||
nx affected -t build e2e --parallel=1
|
||||
nx affected -t test lint --parallel=3
|
||||
```
|
||||
|
||||
This elevated abstraction is possible because Nx Cloud & Nx are intimately familiar with the workspace, understanding the interdependencies between projects and tasks.
|
||||
@@ -109,9 +109,9 @@ Beyond simplifying CI configurations, Nx Cloud Workflows helps optimize computat
|
||||
|
||||
Victor highlighted that most current CI setups:
|
||||
|
||||
- Consistently utilize a predetermined number of agents, irrespective of the actual needs of the PR
|
||||
- Possess non-reusable agents since each is tailored to a specific task, like building or testing
|
||||
- Struggle with granular retries
|
||||
- Consistently utilize a predetermined number of agents, irrespective of the actual needs of the PR
|
||||
- Possess non-reusable agents since each is tailored to a specific task, like building or testing
|
||||
- Struggle with granular retries
|
||||
|
||||
As a metaphor Victor mentions that **Nx Cloud Workflows is to CI what S3 is to file uploads.**
|
||||
|
||||
@@ -163,21 +163,21 @@ Windows, macOS and Linux is currently in development which will use a Cloud VM s
|
||||
|
||||
Michael talks about how to leverage Nx to migrate multiple repositories into a monorepo to streamline development and increase developer productivity. He goes through
|
||||
|
||||
- how a project gets started
|
||||
- how to prep moving to a monorepo from a polyrepo situation
|
||||
- how to do the move in parallel
|
||||
- how to measure the progress
|
||||
- how a project gets started
|
||||
- how to prep moving to a monorepo from a polyrepo situation
|
||||
- how to do the move in parallel
|
||||
- how to measure the progress
|
||||
|
||||
The project usually starts with an architectural audit. That involves a detailed analysis of the underlying codebase, also including an executive summary for non technical folks. Once the audit is done, the actual move is planned and prepared. A part of that is to define “Nx migration goals”, like
|
||||
|
||||
- Single Version Policy
|
||||
- Improved Maintenance
|
||||
- Shared Infrastructure
|
||||
- Shared Architecture
|
||||
- Efficient Task Runs
|
||||
- Frictionless Code-Sharing
|
||||
- Frequent Deployments
|
||||
- Decouple Deployment
|
||||
- Single Version Policy
|
||||
- Improved Maintenance
|
||||
- Shared Infrastructure
|
||||
- Shared Architecture
|
||||
- Efficient Task Runs
|
||||
- Frictionless Code-Sharing
|
||||
- Frequent Deployments
|
||||
- Decouple Deployment
|
||||
|
||||
To prioritize which ones to address first, Michael uses the following metaphor:
|
||||
|
||||
@@ -188,10 +188,10 @@ The important part here is to understand why “apples get bad” in the first p
|
||||
Once the priorities are defined and roadmap laid out, the goal is to **move in parallel.**
|
||||
As part of that move the following gets produced:
|
||||
|
||||
- Migration Guide
|
||||
- Training Program
|
||||
- Communication Strategy
|
||||
- Impact Measurement
|
||||
- Migration Guide
|
||||
- Training Program
|
||||
- Communication Strategy
|
||||
- Impact Measurement
|
||||
|
||||
The migration guide defines where to start, what the company goals are, how the deliveries will be integrated into the existing process and how the interaction with the various teams will happen.
|
||||
|
||||
@@ -201,9 +201,9 @@ Finally the impact measurement; Nx Cloud already has graphs to measure how much
|
||||
|
||||
An interesting part is also how they perform the repository synching (from polyrepo to monorepo). They leverage an Nx plugin that
|
||||
|
||||
- contains shared build logic
|
||||
- has rules to run that produce actionable feedback about what is needed to sync/align the polyrepo repository s.t. it can be merged into the monorepo
|
||||
- it also allows to track progress and produce according reporting of where the company is at
|
||||
- contains shared build logic
|
||||
- has rules to run that produce actionable feedback about what is needed to sync/align the polyrepo repository s.t. it can be merged into the monorepo
|
||||
- it also allows to track progress and produce according reporting of where the company is at
|
||||
|
||||
Sounds interesting? Watch the full talk below:
|
||||
|
||||
@@ -223,32 +223,32 @@ Craigory did a deep dive into the new Nx inference API. This is particularly int
|
||||
|
||||
What is project inference:
|
||||
|
||||
- how Nx reads your project configuration
|
||||
- introduced between v13.3 and v14
|
||||
- initially to support package-based monorepos which use package.json scripts rather than `project.json`. Generalizing the project config reading mechanism also allowed to define an API that community plugins can leverage and which allows to integrate even languages outside the JS ecosystem into Nx (e.g. where projects are just defined differently, such as .Net, Java, Python,..)
|
||||
- how Nx reads your project configuration
|
||||
- introduced between v13.3 and v14
|
||||
- initially to support package-based monorepos which use package.json scripts rather than `project.json`. Generalizing the project config reading mechanism also allowed to define an API that community plugins can leverage and which allows to integrate even languages outside the JS ecosystem into Nx (e.g. where projects are just defined differently, such as .Net, Java, Python,..)
|
||||
|
||||
Inference API v1
|
||||
|
||||
- `projectFilePatterns` - identify files that represent the root of a project
|
||||
- `registerProjectTargets` - takes a project file and converts to a list of targets that Nx knows how to run
|
||||
- `projectFilePatterns` - identify files that represent the root of a project
|
||||
- `registerProjectTargets` - takes a project file and converts to a list of targets that Nx knows how to run
|
||||
|
||||
Shortcomings have been
|
||||
|
||||
- strict 1–1 mapping between project files and projects
|
||||
- the logic of finding proj files and targets had to be decoupled which introduced potential failure points
|
||||
- no way to add dynamic metadata to a project
|
||||
- strict 1–1 mapping between project files and projects
|
||||
- the logic of finding proj files and targets had to be decoupled which introduced potential failure points
|
||||
- no way to add dynamic metadata to a project
|
||||
|
||||
Project graph API v2
|
||||
|
||||
- `createNodes` - finds graph nodes based on files on disk
|
||||
- `createDependencies` - finds edges to be added to the graph
|
||||
- `createNodes` - finds graph nodes based on files on disk
|
||||
- `createDependencies` - finds edges to be added to the graph
|
||||
|
||||
Still 2 parts, but there’s no overlap between these two and they have very specific purposes.
|
||||
|
||||
`createNodes` is a tuple composed of:
|
||||
|
||||
- `projectFilePattern`
|
||||
- `CreateNodesFunction` It can return a map of projects and external nodes, so there's no more the shortcoming of a 1-1 as it was in v1 API. With this new setup multiple plugins might detect the same project. Nx merges the configuration that has been identified. Kinda what happens right now if you mix `package.json` and `project.json` targets in an Nx workspace.
|
||||
- `projectFilePattern`
|
||||
- `CreateNodesFunction` It can return a map of projects and external nodes, so there's no more the shortcoming of a 1-1 as it was in v1 API. With this new setup multiple plugins might detect the same project. Nx merges the configuration that has been identified. Kinda what happens right now if you mix `package.json` and `project.json` targets in an Nx workspace.
|
||||
|
||||
Craigory demos the inference API by building a spell checking plugin for Nx.
|
||||
|
||||
@@ -256,9 +256,9 @@ Craigory demos the inference API by building a spell checking plugin for Nx.
|
||||
|
||||
This API is still marked as experimental, next steps will be
|
||||
|
||||
- mark as stable
|
||||
- remove v1 API after deprecation period
|
||||
- plugin authors should start looking into the new API, provide feedback and think about migration scenarios
|
||||
- mark as stable
|
||||
- remove v1 API after deprecation period
|
||||
- plugin authors should start looking into the new API, provide feedback and think about migration scenarios
|
||||
|
||||
## Package-based to Integrated: One Small Step or One Giant Leap?
|
||||
|
||||
@@ -279,15 +279,15 @@ Currently, Nx offers support for two predominant monorepo styles: package-based
|
||||
|
||||
### Package-based Monorepos:
|
||||
|
||||
- These are tailored for flexibility and innovation.
|
||||
- Packages within this setup can have diverse configurations.
|
||||
- Every package boasts its individual node_modules and dependencies.
|
||||
- Crucially, each can be upgraded independently, offering a high degree of autonomy.
|
||||
- These are tailored for flexibility and innovation.
|
||||
- Packages within this setup can have diverse configurations.
|
||||
- Every package boasts its individual node_modules and dependencies.
|
||||
- Crucially, each can be upgraded independently, offering a high degree of autonomy.
|
||||
|
||||
### Integrated Monorepos:
|
||||
|
||||
- These are structured to prioritize consistency and maintainability.
|
||||
- Updates within this framework are automated, and the setup adheres to a single-version policy.
|
||||
- These are structured to prioritize consistency and maintainability.
|
||||
- Updates within this framework are automated, and the setup adheres to a single-version policy.
|
||||
|
||||
Isaac then drew parallels between the Apollo program and the package-based mindset. The Apollo missions were evolutionary in nature, constantly pushing the envelope and embracing innovation with each successive mission. However, this trailblazing approach wasn’t without its perils, as evidenced by tragic accidents. This experimental approach was feasible because the core team, responsible for creating the setup, remained consistent throughout the project’s duration.
|
||||
|
||||
@@ -295,12 +295,12 @@ In contrast, Isaac likened the International Space Station (ISS) to the integrat
|
||||
|
||||
Shifting gears, Isaac delved into a hands-on demonstration. He outlined the process of transitioning from a package-based monorepo to an integrated one, including demoing:
|
||||
|
||||
- Initializing Nx with `nx init`.
|
||||
- Establishing new projects to facilitate type sharing across applications.
|
||||
- Harnessing the power of the Nx graph visualization to navigate and understand the project structure.
|
||||
- Employing the module boundary rule, ensuring constraints are maintained in the revamped structure.
|
||||
- Devising a novel Nx generator, streamlining the process of setting up new libraries within the workspace.
|
||||
- Finally, he showcased the seamless upgrade mechanism, ensuring the workspace is always aligned with the latest version.
|
||||
- Initializing Nx with `nx init`.
|
||||
- Establishing new projects to facilitate type sharing across applications.
|
||||
- Harnessing the power of the Nx graph visualization to navigate and understand the project structure.
|
||||
- Employing the module boundary rule, ensuring constraints are maintained in the revamped structure.
|
||||
- Devising a novel Nx generator, streamlining the process of setting up new libraries within the workspace.
|
||||
- Finally, he showcased the seamless upgrade mechanism, ensuring the workspace is always aligned with the latest version.
|
||||
|
||||
## Nx’t Level Publishing
|
||||
|
||||
@@ -317,9 +317,9 @@ The nx core team decided to go into this problem space and provide an opinionate
|
||||
|
||||
New command `nx release`
|
||||
|
||||
- `nx release version` to determine and apply version updates
|
||||
- `nx release` changelog generate a CHANGELOG.md file and optional GitHub releases based on git commits
|
||||
- `nx release` publish takes a newly versioned project and publishes them to a remote registry (e.g. NPM)
|
||||
- `nx release version` to determine and apply version updates
|
||||
- `nx release` changelog generate a CHANGELOG.md file and optional GitHub releases based on git commits
|
||||
- `nx release` publish takes a newly versioned project and publishes them to a remote registry (e.g. NPM)
|
||||
|
||||
This new command is not tight to `package.json` files but is general purpose; clearly publishing JS/TS packages is the main use case right now in Nx
|
||||
Important to note that all the existing plugins are still valid and will still be going forward.
|
||||
@@ -337,9 +337,9 @@ The monorepo has a `pkg-a` and `pkg-b` where there's a relationship between them
|
||||
If the `version` command is used in such scenario, it will also be applied to the dependent packages (`pkg-b`) since Nx knows about the dependencies via the project graph.
|
||||
A nice feature is also that the changelog will...
|
||||
|
||||
- automatically group first by type (e.g. features grouped together, fixes etc)
|
||||
- within each type grouping it will be grouped by scope such as pkg-a etc which will be alphabetized
|
||||
- if there’s a fix on the entire repo that’ll come first before the per-package changes
|
||||
- automatically group first by type (e.g. features grouped together, fixes etc)
|
||||
- within each type grouping it will be grouped by scope such as pkg-a etc which will be alphabetized
|
||||
- if there’s a fix on the entire repo that’ll come first before the per-package changes
|
||||
|
||||
`nx release changelog --create-release=github` allows to also automatically push the changelog to a Github release.
|
||||
|
||||
@@ -347,9 +347,9 @@ When running `nx release publish`, Nx also takes into account the right order of
|
||||
|
||||
Future roadmap:
|
||||
|
||||
- ability to customize how the release works by defining it in `nx.json`
|
||||
- “release groups” will allow to group packages and define whether versions should be in sync or versioned independently; filter by projects, or even just publish a subset of projects of a workspace
|
||||
- publishing also automatically takes into account the provenance data on NPM
|
||||
- ability to customize how the release works by defining it in `nx.json`
|
||||
- “release groups” will allow to group packages and define whether versions should be in sync or versioned independently; filter by projects, or even just publish a subset of projects of a workspace
|
||||
- publishing also automatically takes into account the provenance data on NPM
|
||||
|
||||
## Lightning Talk: What if your stories were — already — your e2e tests?
|
||||
|
||||
@@ -423,9 +423,9 @@ The comparative analysis of their DIY solution versus DTE revealed roughly equiv
|
||||
|
||||
### Adrian’s Key Insights:
|
||||
|
||||
- DTE setup warrants a dual-pronged strategy: an immediate plan for initiation and a long-term vision for transition. Notably, Nx DTE supports incremental adoption.
|
||||
- Patience is paramount during the tuning phase to determine the optimal number of agents.
|
||||
- While results might vary, Adrian humorously assures that one can always bank on the Nx team for support. 😅
|
||||
- DTE setup warrants a dual-pronged strategy: an immediate plan for initiation and a long-term vision for transition. Notably, Nx DTE supports incremental adoption.
|
||||
- Patience is paramount during the tuning phase to determine the optimal number of agents.
|
||||
- While results might vary, Adrian humorously assures that one can always bank on the Nx team for support. 😅
|
||||
|
||||
## Vanquishing Deployment Dragons with Nx wizardry
|
||||
|
||||
@@ -456,11 +456,11 @@ Nx plays a crucial role in helping integrate and maintain these different tools:
|
||||
|
||||
How? Brandon dives straight into it by explaining how Nx plugins in particular can be useful, explaining:
|
||||
|
||||
- features of Nx plugins such as generators, executors, automated migrations, presets and how to use them just locally to automate your workspace
|
||||
- how to create a new plugin
|
||||
- the anatomy of a generator and how they can be useful in scaffolding new setups, but also integrating technology, like adding tRPC to your stack, etc.
|
||||
- similarly Nx executors provide a thin abstraction layer over the actual commands, allowing the plugin developer to update the underlying tooling without necessarily disrupting the end user
|
||||
- most importantly allowing to write automatic migrations he can leverage with Analog, like running `nx migrate @analogjs/platform@latest` to update a given workspace automatically to the latest version, across potentially breaking changes
|
||||
- features of Nx plugins such as generators, executors, automated migrations, presets and how to use them just locally to automate your workspace
|
||||
- how to create a new plugin
|
||||
- the anatomy of a generator and how they can be useful in scaffolding new setups, but also integrating technology, like adding tRPC to your stack, etc.
|
||||
- similarly Nx executors provide a thin abstraction layer over the actual commands, allowing the plugin developer to update the underlying tooling without necessarily disrupting the end user
|
||||
- most importantly allowing to write automatic migrations he can leverage with Analog, like running `nx migrate @analogjs/platform@latest` to update a given workspace automatically to the latest version, across potentially breaking changes
|
||||
|
||||
Brandon highlighted a pivotal aspect for OSS package/framework authors: the power to not just assimilate into pre-existing Nx workspaces via custom Nx plugins but also to steer the entire workspace setup process. This is particularly beneficial when tailored setups specific to individual use cases are required. By leveraging an [Nx preset](/extending-nx/recipes/create-preset), one can achieve this tailored configuration. Brandon also touched upon the possibility of advancing further by constructing an [install package](/extending-nx/recipes/create-install-package) through Nx.
|
||||
|
||||
@@ -490,9 +490,9 @@ If you enjoyed these, [subscribe to our YouTube channel](https://www.youtube.com
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -12,18 +12,18 @@ This article will cover the main things you need to know to get the most out of
|
||||
|
||||
Here’s a Table of Contents so you can skip straight to the updates you care about the most:
|
||||
|
||||
- [It's a Vue-tiful Day for Nx](#its-a-vuetiful-day-for-nx)
|
||||
- [Enhancements to Module Federation Support](#enhancements-to-module-federation-support)
|
||||
- [More Consistent Generator Paths](#more-consistent-generator-paths)
|
||||
- [The NEW Nx AI Chatbot](#the-new-nx-ai-chatbot)
|
||||
- [More Seamless Integration With Nx Cloud](#more-seamless-integration-with-nx-cloud)
|
||||
- [`nx.json` Simplification](#simplification)
|
||||
- [Nx Repo Begins Dog-Fooding Nx Workflows](#nx-repo-dogfooding-nx-workflows)
|
||||
- [Task Graphing Improvements](#task-graphing-improvements)
|
||||
- [`@nx/linter` Renames to `@nx/eslint`](#renamed-to)
|
||||
- [New Experimental Feature: Nx Release](#new-experimental-feature-nx-release)
|
||||
- [Experimental: Nx Project Inference API v2](#experimental-nx-project-inference-api-v2)
|
||||
- [20k Github Stars!!](#20k-github-stars)
|
||||
- [It's a Vue-tiful Day for Nx](#its-a-vuetiful-day-for-nx)
|
||||
- [Enhancements to Module Federation Support](#enhancements-to-module-federation-support)
|
||||
- [More Consistent Generator Paths](#more-consistent-generator-paths)
|
||||
- [The NEW Nx AI Chatbot](#the-new-nx-ai-chatbot)
|
||||
- [More Seamless Integration With Nx Cloud](#more-seamless-integration-with-nx-cloud)
|
||||
- [`nx.json` Simplification](#simplification)
|
||||
- [Nx Repo Begins Dog-Fooding Nx Workflows](#nx-repo-dogfooding-nx-workflows)
|
||||
- [Task Graphing Improvements](#task-graphing-improvements)
|
||||
- [`@nx/linter` Renames to `@nx/eslint`](#renamed-to)
|
||||
- [New Experimental Feature: Nx Release](#new-experimental-feature-nx-release)
|
||||
- [Experimental: Nx Project Inference API v2](#experimental-nx-project-inference-api-v2)
|
||||
- [20k Github Stars!!](#20k-github-stars)
|
||||
|
||||
**Prefer a video?**
|
||||
|
||||
@@ -91,21 +91,21 @@ Then, when consuming this library, you can use the `shared` method of the `Modul
|
||||
import { ModuleFederationConfig } from '@nx/webpack';
|
||||
|
||||
const config: ModuleFederationConfig = {
|
||||
name: 'my-remote',
|
||||
exposes: {
|
||||
'./Module': 'apps/my-remote/src/app/remote-entry/entry.module.ts',
|
||||
},
|
||||
remotes: ['federated-is-odd'],
|
||||
shared: (libName, configuration) => {
|
||||
if (libName === 'is-odd') {
|
||||
return {
|
||||
singleton: true,
|
||||
strictVersion: true,
|
||||
requiredVersion: '0.0.1',
|
||||
};
|
||||
}
|
||||
return configuration;
|
||||
},
|
||||
name: 'my-remote',
|
||||
exposes: {
|
||||
'./Module': 'apps/my-remote/src/app/remote-entry/entry.module.ts',
|
||||
},
|
||||
remotes: ['federated-is-odd'],
|
||||
shared: (libName, configuration) => {
|
||||
if (libName === 'is-odd') {
|
||||
return {
|
||||
singleton: true,
|
||||
strictVersion: true,
|
||||
requiredVersion: '0.0.1',
|
||||
};
|
||||
}
|
||||
return configuration;
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -223,9 +223,9 @@ In Nx 17, we removed any remaining traces of `tslint` from our linter package, s
|
||||
|
||||
`nx release` is a new top level command on the Nx CLI which is designed to help you with versioning, changelog generation, and publishing of your projects:
|
||||
|
||||
- `nx release version` - Determine and apply version updates to projects and their dependents
|
||||
- `nx release changelog` - Generate CHANGELOG.md files and optional Github releases based on git commits
|
||||
- `nx release publish` - Take the freshly versioned projects and publish them to a remote registry
|
||||
- `nx release version` - Determine and apply version updates to projects and their dependents
|
||||
- `nx release changelog` - Generate CHANGELOG.md files and optional Github releases based on git commits
|
||||
- `nx release publish` - Take the freshly versioned projects and publish them to a remote registry
|
||||
|
||||
`nx release` is still experiment and therefore subject to change, but the Nx repo itself is now using these commands to version itself, as well as generate changelogs, [Github releases](https://github.com/nrwl/nx/releases/tag/17.0.3), and publish our packages to npm.
|
||||
|
||||
@@ -279,9 +279,9 @@ That’s all for now folks! We’re just starting up a new iteration of developm
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -10,9 +10,9 @@ There are currently countless numbers of state management libraries out there. T
|
||||
|
||||
This blog will show:
|
||||
|
||||
- How to set up these libraries and their dev tools
|
||||
- How to build the sample page below in React Native / Expo with state management
|
||||
- How to do unit testing
|
||||
- How to set up these libraries and their dev tools
|
||||
- How to build the sample page below in React Native / Expo with state management
|
||||
- How to do unit testing
|
||||
|
||||
It will call an API and show a cat fact on the page, allowing users to like or dislike the data.
|
||||
|
||||
@@ -26,29 +26,29 @@ Github repo: [https://github.com/xiongemi/nx-expo-monorepo](https://github.com/x
|
||||
|
||||
From [TanStack Query documentation](https://tanstack.com/query/latest/docs/framework/react/guides/does-this-replace-client-state), it says:
|
||||
|
||||
- [TanStack Query](https://tanstack.com/query/latest/docs/framework/react/overview) is a **server-state** library.
|
||||
- [Redux](https://redux.js.org/) is a client-state library.
|
||||
- [TanStack Query](https://tanstack.com/query/latest/docs/framework/react/overview) is a **server-state** library.
|
||||
- [Redux](https://redux.js.org/) is a client-state library.
|
||||
|
||||
What is the difference between the server state and the client state?
|
||||
|
||||
In short:
|
||||
|
||||
- Calling an API, dealing with asynchronous data-> server state
|
||||
- Everything else about UI, dealing with synchronous data -> client state
|
||||
- Calling an API, dealing with asynchronous data-> server state
|
||||
- Everything else about UI, dealing with synchronous data -> client state
|
||||
|
||||
## Installation
|
||||
|
||||
To use **[TanStack Query / React Query](https://tanstack.com/query/latest)** for the server state, I need to install:
|
||||
|
||||
- Library: [@tanstack/react-query](https://tanstack.com/query/latest)
|
||||
- Dev tools: [@tanstack/react-query-devtools](https://tanstack.com/query/latest/docs/framework/react/devtools)
|
||||
- Library: [@tanstack/react-query](https://tanstack.com/query/latest)
|
||||
- Dev tools: [@tanstack/react-query-devtools](https://tanstack.com/query/latest/docs/framework/react/devtools)
|
||||
|
||||
I will use **Redux** for everything else.
|
||||
|
||||
- Library: [redux](https://github.com/reduxjs/redux), react-redux, @reduxjs/toolkit
|
||||
- Dev tools: [@redux-devtools/extension](https://github.com/zalmoxisus/redux-devtools-extension)
|
||||
- Logger: [redux-logger](https://github.com/LogRocket/redux-logger), [@types/redux-logger](https://www.npmjs.com/package/@types/redux-logger)
|
||||
- Storage: [redux-persist](https://github.com/rt2zz/redux-persist), [@react-native-async-storage/async-storage](https://github.com/react-native-async-storage/async-storage)
|
||||
- Library: [redux](https://github.com/reduxjs/redux), react-redux, @reduxjs/toolkit
|
||||
- Dev tools: [@redux-devtools/extension](https://github.com/zalmoxisus/redux-devtools-extension)
|
||||
- Logger: [redux-logger](https://github.com/LogRocket/redux-logger), [@types/redux-logger](https://www.npmjs.com/package/@types/redux-logger)
|
||||
- Storage: [redux-persist](https://github.com/rt2zz/redux-persist), [@react-native-async-storage/async-storage](https://github.com/react-native-async-storage/async-storage)
|
||||
|
||||
To install all the above packages:
|
||||
|
||||
@@ -76,13 +76,13 @@ import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
const App = () => {
|
||||
const queryClient = new QueryClient();
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
{Platform.OS === 'web' && <ReactQueryDevtools />}
|
||||
...
|
||||
</QueryClientProvider>
|
||||
);
|
||||
const queryClient = new QueryClient();
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
{Platform.OS === 'web' && <ReactQueryDevtools />}
|
||||
...
|
||||
</QueryClientProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
@@ -130,17 +130,17 @@ For this app, let’s use this API: [https://catfact.ninja/](https://catfact.nin
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
export const fetchCatFact = async (): Promise<string> => {
|
||||
const response = await fetch('https://catfact.ninja/fact');
|
||||
const data = await response.json();
|
||||
return data.fact;
|
||||
const response = await fetch('https://catfact.ninja/fact');
|
||||
const data = await response.json();
|
||||
return data.fact;
|
||||
};
|
||||
|
||||
export const useCatFact = () => {
|
||||
return useQuery({
|
||||
queryKey: ['cat-fact'],
|
||||
queryFn: fetchCatFact,
|
||||
enabled: false,
|
||||
});
|
||||
return useQuery({
|
||||
queryKey: ['cat-fact'],
|
||||
queryFn: fetchCatFact,
|
||||
enabled: false,
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
@@ -164,8 +164,8 @@ To solve this, you need to wrap your component inside the renderHook function fr
|
||||
|
||||
Depending on which library you use to make HTTP requests. (e.g. fetch, axios), you need to install a library to mock the response.
|
||||
|
||||
- If you use `fetch` to fetch data, you need to install `jest*fetch-mock`.
|
||||
- If you use `axios` to fetch data, you need to install `axio*-mock-adapter`.
|
||||
- If you use `fetch` to fetch data, you need to install `jest*fetch-mock`.
|
||||
- If you use `axios` to fetch data, you need to install `axio*-mock-adapter`.
|
||||
|
||||
For this example, since it uses `fetch`, you need to install `jest-fetch-mock`:
|
||||
|
||||
@@ -214,14 +214,14 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import React from 'react';
|
||||
|
||||
export interface TestWrapperProps {
|
||||
children: React.ReactNode;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function TestWrapper({ children }: TestWrapperProps) {
|
||||
const queryClient = new QueryClient();
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||
);
|
||||
const queryClient = new QueryClient();
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default TestWrapper;
|
||||
@@ -238,41 +238,41 @@ import { useCatFact } from './use-cat-fact';
|
||||
import fetchMock from 'jest-fetch-mock';
|
||||
|
||||
describe('useCatFact', () => {
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it('status should be success', async () => {
|
||||
// simulating a server response
|
||||
fetchMock.mockResponseOnce(
|
||||
JSON.stringify({
|
||||
fact: 'random cat fact',
|
||||
})
|
||||
);
|
||||
it('status should be success', async () => {
|
||||
// simulating a server response
|
||||
fetchMock.mockResponseOnce(
|
||||
JSON.stringify({
|
||||
fact: 'random cat fact',
|
||||
})
|
||||
);
|
||||
|
||||
const { result } = renderHook(() => useCatFact(), {
|
||||
wrapper: TestWrapper,
|
||||
});
|
||||
result.current.refetch(); // refetching the query
|
||||
expect(result.current.isLoading).toBeTruthy();
|
||||
const { result } = renderHook(() => useCatFact(), {
|
||||
wrapper: TestWrapper,
|
||||
});
|
||||
result.current.refetch(); // refetching the query
|
||||
expect(result.current.isLoading).toBeTruthy();
|
||||
|
||||
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
||||
expect(result.current.isSuccess).toBe(true);
|
||||
expect(result.current.data).toEqual('random cat fact');
|
||||
});
|
||||
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
||||
expect(result.current.isSuccess).toBe(true);
|
||||
expect(result.current.data).toEqual('random cat fact');
|
||||
});
|
||||
|
||||
it('status should be error', async () => {
|
||||
fetchMock.mockRejectOnce();
|
||||
it('status should be error', async () => {
|
||||
fetchMock.mockRejectOnce();
|
||||
|
||||
const { result } = renderHook(() => useCatFact(), {
|
||||
wrapper: TestWrapper,
|
||||
});
|
||||
result.current.refetch(); // refetching the query
|
||||
expect(result.current.isLoading).toBeTruthy();
|
||||
const { result } = renderHook(() => useCatFact(), {
|
||||
wrapper: TestWrapper,
|
||||
});
|
||||
result.current.refetch(); // refetching the query
|
||||
expect(result.current.isLoading).toBeTruthy();
|
||||
|
||||
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
||||
expect(result.current.isError).toBe(true);
|
||||
});
|
||||
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
||||
expect(result.current.isError).toBe(true);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
@@ -290,39 +290,39 @@ import MockAdapter from 'axios-mock-adapter';
|
||||
const mockAxios = new MockAdapter(axios);
|
||||
|
||||
describe('useCatFact', () => {
|
||||
afterEach(() => {
|
||||
mockAxios.reset();
|
||||
});
|
||||
afterEach(() => {
|
||||
mockAxios.reset();
|
||||
});
|
||||
|
||||
it('status should be success', async () => {
|
||||
// simulating a server response
|
||||
mockAxios.onGet().replyOnce(200, {
|
||||
fact: 'random cat fact',
|
||||
});
|
||||
it('status should be success', async () => {
|
||||
// simulating a server response
|
||||
mockAxios.onGet().replyOnce(200, {
|
||||
fact: 'random cat fact',
|
||||
});
|
||||
|
||||
const { result } = renderHook(() => useCatFact(), {
|
||||
wrapper: TestWrapper,
|
||||
});
|
||||
result.current.refetch(); // refetching the query
|
||||
expect(result.current.isLoading).toBeTruthy();
|
||||
const { result } = renderHook(() => useCatFact(), {
|
||||
wrapper: TestWrapper,
|
||||
});
|
||||
result.current.refetch(); // refetching the query
|
||||
expect(result.current.isLoading).toBeTruthy();
|
||||
|
||||
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
||||
expect(result.current.isSuccess).toBe(true);
|
||||
expect(result.current.data).toEqual('random cat fact');
|
||||
});
|
||||
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
||||
expect(result.current.isSuccess).toBe(true);
|
||||
expect(result.current.data).toEqual('random cat fact');
|
||||
});
|
||||
|
||||
it('status should be error', async () => {
|
||||
mockAxios.onGet().replyOnce(500);
|
||||
it('status should be error', async () => {
|
||||
mockAxios.onGet().replyOnce(500);
|
||||
|
||||
const { result } = renderHook(() => useCatFact(), {
|
||||
wrapper: TestWrapper,
|
||||
});
|
||||
result.current.refetch(); // refetching the query
|
||||
expect(result.current.isLoading).toBeTruthy();
|
||||
const { result } = renderHook(() => useCatFact(), {
|
||||
wrapper: TestWrapper,
|
||||
});
|
||||
result.current.refetch(); // refetching the query
|
||||
expect(result.current.isLoading).toBeTruthy();
|
||||
|
||||
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
||||
expect(result.current.isError).toBe(true);
|
||||
});
|
||||
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
||||
expect(result.current.isError).toBe(true);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
@@ -341,9 +341,9 @@ Now you run the test command `nx test queries-use-cat-fact`, it should pass:
|
||||
|
||||
Currently `userQuery` returns the following properties:
|
||||
|
||||
- `isLoading` or `status === 'loading'` - The query has no data yet
|
||||
- `isError` or `status === 'error'` - The query encountered an error
|
||||
- `isSuccess` or `status === 'success'` - The query was successful and data is available
|
||||
- `isLoading` or `status === 'loading'` - The query has no data yet
|
||||
- `isError` or `status === 'error'` - The query encountered an error
|
||||
- `isSuccess` or `status === 'success'` - The query was successful and data is available
|
||||
|
||||
Now with components controlled by the server state, you can leverage the above properties and change your component to follow the below pattern:
|
||||
|
||||
@@ -446,18 +446,18 @@ Then update the redux slice at `libs/states/cat/src/lib/likes/likes.slice.ts`:
|
||||
|
||||
```ts
|
||||
import {
|
||||
createEntityAdapter,
|
||||
createSelector,
|
||||
createSlice,
|
||||
EntityState,
|
||||
createEntityAdapter,
|
||||
createSelector,
|
||||
createSlice,
|
||||
EntityState,
|
||||
} from '@reduxjs/toolkit';
|
||||
|
||||
export const LIKES_FEATURE_KEY = 'likes';
|
||||
|
||||
export interface LikesEntity {
|
||||
id: string;
|
||||
content: string;
|
||||
dateAdded: number;
|
||||
id: string;
|
||||
content: string;
|
||||
dateAdded: number;
|
||||
}
|
||||
|
||||
export type LikesState = EntityState<LikesEntity>;
|
||||
@@ -467,13 +467,13 @@ export const likesAdapter = createEntityAdapter<LikesEntity>();
|
||||
export const initialLikesState: LikesState = likesAdapter.getInitialState();
|
||||
|
||||
export const likesSlice = createSlice({
|
||||
name: LIKES_FEATURE_KEY,
|
||||
initialState: initialLikesState,
|
||||
reducers: {
|
||||
like: likesAdapter.addOne,
|
||||
remove: likesAdapter.removeOne,
|
||||
clear: likesAdapter.removeAll,
|
||||
},
|
||||
name: LIKES_FEATURE_KEY,
|
||||
initialState: initialLikesState,
|
||||
reducers: {
|
||||
like: likesAdapter.addOne,
|
||||
remove: likesAdapter.removeOne,
|
||||
clear: likesAdapter.removeAll,
|
||||
},
|
||||
});
|
||||
|
||||
/*
|
||||
@@ -486,13 +486,13 @@ export const likesActions = likesSlice.actions;
|
||||
const { selectAll } = likesAdapter.getSelectors();
|
||||
|
||||
const getlikesState = <ROOT extends { likes: LikesState }>(
|
||||
rootState: ROOT
|
||||
rootState: ROOT
|
||||
): LikesState => rootState[LIKES_FEATURE_KEY];
|
||||
|
||||
const selectAllLikes = createSelector(getlikesState, selectAll);
|
||||
|
||||
export const likesSelectors = {
|
||||
selectAllLikes,
|
||||
selectAllLikes,
|
||||
};
|
||||
```
|
||||
|
||||
@@ -500,17 +500,17 @@ Every time the “like” button gets clicked, you want to store the content of
|
||||
|
||||
```ts
|
||||
export interface LikesEntity {
|
||||
id: string;
|
||||
content: string;
|
||||
dateAdded: number;
|
||||
id: string;
|
||||
content: string;
|
||||
dateAdded: number;
|
||||
}
|
||||
```
|
||||
|
||||
This state has 3 actions:
|
||||
|
||||
- like: when users click like
|
||||
- remove: when users cancel the like
|
||||
- clear: when users clear all the likes
|
||||
- like: when users click like
|
||||
- remove: when users cancel the like
|
||||
- clear: when users clear all the likes
|
||||
|
||||
### Root Store
|
||||
|
||||
@@ -524,33 +524,33 @@ Then you have to add the root store and create a transform function to stringify
|
||||
|
||||
Then in `apps/cats/src/app/App.tsx`, you have to:
|
||||
|
||||
- wrap the app inside the `StoreProvider` with the root store to connect with the Redux state.
|
||||
- wrap the app inside `PersistGate` to persist the redux state in the storage
|
||||
- wrap the app inside the `StoreProvider` with the root store to connect with the Redux state.
|
||||
- wrap the app inside `PersistGate` to persist the redux state in the storage
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { PersistGate } from 'redux-persist/integration/react';
|
||||
import {
|
||||
createRootStore,
|
||||
transformEntityStateToPersist,
|
||||
createRootStore,
|
||||
transformEntityStateToPersist,
|
||||
} from '@nx-expo-monorepo/states/cat';
|
||||
import { Loading } from '@nx-expo-monorepo/ui';
|
||||
import { Provider as StoreProvider } from 'react-redux';
|
||||
|
||||
const App = () => {
|
||||
const persistConfig = {
|
||||
key: 'root',
|
||||
storage: AsyncStorage,
|
||||
transforms: [transformEntityStateToPersist],
|
||||
};
|
||||
const { store, persistor } = createRootStore(persistConfig);
|
||||
const persistConfig = {
|
||||
key: 'root',
|
||||
storage: AsyncStorage,
|
||||
transforms: [transformEntityStateToPersist],
|
||||
};
|
||||
const { store, persistor } = createRootStore(persistConfig);
|
||||
|
||||
return (
|
||||
<PersistGate loading={<Loading />} persistor={persistor}>
|
||||
<StoreProvider store={store}>...</StoreProvider>
|
||||
</PersistGate>
|
||||
);
|
||||
return (
|
||||
<PersistGate loading={<Loading />} persistor={persistor}>
|
||||
<StoreProvider store={store}>...</StoreProvider>
|
||||
</PersistGate>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
@@ -560,20 +560,20 @@ In your component where the like button is located, you need to dispatch the lik
|
||||
|
||||
```ts
|
||||
import {
|
||||
likesActions,
|
||||
LikesEntity,
|
||||
RootState,
|
||||
likesActions,
|
||||
LikesEntity,
|
||||
RootState,
|
||||
} from '@nx-expo-monorepo/states/cat';
|
||||
import { AnyAction, ThunkDispatch } from '@reduxjs/toolkit';
|
||||
|
||||
const mapDispatchToProps = (
|
||||
dispatch: ThunkDispatch<RootState, void, AnyAction>
|
||||
dispatch: ThunkDispatch<RootState, void, AnyAction>
|
||||
) => {
|
||||
return {
|
||||
like(item: LikesEntity) {
|
||||
dispatch(likesActions.like(item));
|
||||
},
|
||||
};
|
||||
return {
|
||||
like(item: LikesEntity) {
|
||||
dispatch(likesActions.like(item));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
type mapDispatchToPropsType = ReturnType<typeof mapDispatchToProps>;
|
||||
@@ -608,17 +608,17 @@ Here is a simple app that uses TanStack Query and Redux for state management. Th
|
||||
|
||||
Nx is a powerful monorepo tool. Together with Nx and these 2 state management tools, it will be very easy to scale up any app.
|
||||
|
||||
- TanStack Query site: [https://tanstack.com/query/latest](https://tanstack.com/query/latest)
|
||||
- Official @nx/expo plugin: [/nx-api/expo](/nx-api/expo)
|
||||
- Official @nx/react-native plugin: [/nx-api/react-native](/nx-api/react-native)
|
||||
- TanStack Query site: [https://tanstack.com/query/latest](https://tanstack.com/query/latest)
|
||||
- Official @nx/expo plugin: [/nx-api/expo](/nx-api/expo)
|
||||
- Official @nx/react-native plugin: [/nx-api/react-native](/nx-api/react-native)
|
||||
|
||||
---
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -50,24 +50,24 @@ This part is copied from: [https://github.com/supabase-community/nextjs-openai-d
|
||||
|
||||
```js
|
||||
export function processMdxForSearch(content: string) {
|
||||
// …
|
||||
const mdTree = fromMarkdown(content, {});
|
||||
const sectionTrees = splitTreeBy(mdTree, (node) => node.type === 'heading');
|
||||
// …
|
||||
const sections = sectionTrees.map((tree: any) => {
|
||||
const [firstNode] = tree.children;
|
||||
const heading =
|
||||
firstNode.type === 'heading' ? toString(firstNode) : undefined;
|
||||
return {
|
||||
content: toMarkdown(tree),
|
||||
heading,
|
||||
slug,
|
||||
};
|
||||
});
|
||||
return {
|
||||
checksum,
|
||||
sections,
|
||||
};
|
||||
// …
|
||||
const mdTree = fromMarkdown(content, {});
|
||||
const sectionTrees = splitTreeBy(mdTree, (node) => node.type === 'heading');
|
||||
// …
|
||||
const sections = sectionTrees.map((tree: any) => {
|
||||
const [firstNode] = tree.children;
|
||||
const heading =
|
||||
firstNode.type === 'heading' ? toString(firstNode) : undefined;
|
||||
return {
|
||||
content: toMarkdown(tree),
|
||||
heading,
|
||||
slug,
|
||||
};
|
||||
});
|
||||
return {
|
||||
checksum,
|
||||
sections,
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
@@ -79,8 +79,8 @@ Ref in the code: [https://github.com/nrwl/nx/blob/76306f0bedc1297b64da6e58b4f7b9
|
||||
|
||||
```js
|
||||
const embeddingResponse = await openai.embeddings.create({
|
||||
model: 'text-embedding-ada-002',
|
||||
input,
|
||||
model: 'text-embedding-ada-002',
|
||||
input,
|
||||
});
|
||||
```
|
||||
|
||||
@@ -96,17 +96,17 @@ Ref in code: [https://github.com/nrwl/nx/blob/master/tools/documentation/create-
|
||||
|
||||
```js
|
||||
const { data: pageSection } = await supabaseClient
|
||||
.from('nods_page_section')
|
||||
.insert({
|
||||
page_id: page.id,
|
||||
slug,
|
||||
heading,
|
||||
longer_heading,
|
||||
content,
|
||||
url_partial,
|
||||
token_count,
|
||||
embedding,
|
||||
}); // …
|
||||
.from('nods_page_section')
|
||||
.insert({
|
||||
page_id: page.id,
|
||||
slug,
|
||||
heading,
|
||||
longer_heading,
|
||||
content,
|
||||
url_partial,
|
||||
token_count,
|
||||
embedding,
|
||||
}); // …
|
||||
```
|
||||
|
||||
## Step 2: User query analysis and search
|
||||
@@ -117,10 +117,10 @@ Ref in code: [https://github.com/nrwl/nx/blob/76306f0bedc1297b64da6e58b4f7b9c397
|
||||
|
||||
```js
|
||||
const embeddingResponse: OpenAI.Embeddings.CreateEmbeddingResponse =
|
||||
await openai.embeddings.create({
|
||||
model: 'text-embedding-ada-002',
|
||||
input: sanitizedQuery + getLastAssistantMessageContent(messages),
|
||||
});
|
||||
await openai.embeddings.create({
|
||||
model: 'text-embedding-ada-002',
|
||||
input: sanitizedQuery + getLastAssistantMessageContent(messages),
|
||||
});
|
||||
```
|
||||
|
||||
The assistant compares the query embedding with these documentation embeddings to identify relevant sections. This comparison is essentially measuring how close the query’s vector is to the documentation vectors. The closer they are, the more related the content. The way this works is that it sends the user’s question embedding to Supabase, to a PostgreSQL function, which runs a vector comparison between the user’s question embedding and the stored embeddings in the table. The PostgreSQL function returns all the similar documentation chunks.
|
||||
@@ -131,8 +131,8 @@ Ref in code: [https://github.com/nrwl/nx/blob/76306f0bedc1297b64da6e58b4f7b9c397
|
||||
|
||||
```js
|
||||
const { data: pageSections } = await supabaseClient.rpc('match_page_sections', {
|
||||
embedding,
|
||||
// …
|
||||
embedding,
|
||||
// …
|
||||
});
|
||||
```
|
||||
|
||||
@@ -142,10 +142,10 @@ With the relevant sections (documentation chunks) identified and retrieved, GPT
|
||||
|
||||
This approach the AI is instructed to use (in the **prompt**) is the following:
|
||||
|
||||
- Identify CLUES from the query and documentation.
|
||||
- Deduce REASONING based solely on the provided Nx Documentation.
|
||||
- EVALUATE its reasoning, ensuring alignment with Nx Documentation.
|
||||
- Rely on previous messages for contextual continuity.
|
||||
- Identify CLUES from the query and documentation.
|
||||
- Deduce REASONING based solely on the provided Nx Documentation.
|
||||
- EVALUATE its reasoning, ensuring alignment with Nx Documentation.
|
||||
- Rely on previous messages for contextual continuity.
|
||||
|
||||
### Ensuring Quality
|
||||
|
||||
@@ -307,9 +307,9 @@ This role, in the context of OpenAI’s chat models, is the response of the AI.
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -8,8 +8,8 @@ tags: [nx, unit testing]
|
||||
|
||||
In my latest [blog](https://dev.to/nx/step-by-step-guide-to-creating-an-expo-monorepo-with-nx-3b17), I successfully navigated through the steps of setting up an Expo Monorepo with [Nx](). The next challenge? Testing! This blog dives into:
|
||||
|
||||
- Crafting effective unit tests for Expo components utilizing Jest
|
||||
- Addressing common issues encountered during unit testing
|
||||
- Crafting effective unit tests for Expo components utilizing Jest
|
||||
- Addressing common issues encountered during unit testing
|
||||
|
||||
Repo:
|
||||
{% github-repository url="https://github.com/xiongemi/nx-expo-monorepo" /%}
|
||||
@@ -18,9 +18,9 @@ Repo:
|
||||
|
||||
Here’s my setup
|
||||
|
||||
- Testing framework: [jest](https://jestjs.io/)
|
||||
- Testing library: [@testing-library/react-native](https://callstack.github.io/react-native-testing-library/)
|
||||
- Jest Preset: [jest-expo](https://www.npmjs.com/package/jest-expo)
|
||||
- Testing framework: [jest](https://jestjs.io/)
|
||||
- Testing library: [@testing-library/react-native](https://callstack.github.io/react-native-testing-library/)
|
||||
- Jest Preset: [jest-expo](https://www.npmjs.com/package/jest-expo)
|
||||
|
||||
## Writing and Running Unit Tests
|
||||
|
||||
@@ -33,10 +33,10 @@ import React from 'react';
|
||||
import Loading from './loading';
|
||||
|
||||
describe('Loading', () => {
|
||||
it('should render successfully', () => {
|
||||
const { root } = render(<Loading />);
|
||||
expect(root).toBeTruthy();
|
||||
});
|
||||
it('should render successfully', () => {
|
||||
const { root } = render(<Loading />);
|
||||
expect(root).toBeTruthy();
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
@@ -99,7 +99,7 @@ In the app’s test-setup.ts file, add the below lines:
|
||||
|
||||
```typescript
|
||||
jest.mock('@react-native-async-storage/async-storage', () =>
|
||||
require('@react-native-async-storage/async-storage/jest/async-storage-mock')
|
||||
require('@react-native-async-storage/async-storage/jest/async-storage-mock')
|
||||
);
|
||||
```
|
||||
|
||||
@@ -196,14 +196,14 @@ To solve this, I can just mock the `useQuery` function:
|
||||
import * as ReactQuery from '@tanstack/react-query';
|
||||
|
||||
jest.spyOn(ReactQuery, 'useQuery').mockImplementation(
|
||||
jest.fn().mockReturnValue({
|
||||
data: 'random cat fact',
|
||||
isLoading: false,
|
||||
isSuccess: true,
|
||||
refetch: jest.fn(),
|
||||
isFetching: false,
|
||||
isError: false,
|
||||
})
|
||||
jest.fn().mockReturnValue({
|
||||
data: 'random cat fact',
|
||||
isLoading: false,
|
||||
isSuccess: true,
|
||||
refetch: jest.fn(),
|
||||
isFetching: false,
|
||||
isError: false,
|
||||
})
|
||||
);
|
||||
```
|
||||
|
||||
@@ -219,18 +219,18 @@ The fix this, I need to mock the `@react-nativgation/native` library. In the app
|
||||
|
||||
```typescript
|
||||
jest.mock('@react-navigation/native', () => {
|
||||
return {
|
||||
useNavigation: () => ({
|
||||
navigate: jest.fn(),
|
||||
dispatch: jest.fn(),
|
||||
setOptions: jest.fn(),
|
||||
}),
|
||||
useRoute: () => ({
|
||||
params: {
|
||||
id: '123',
|
||||
},
|
||||
}),
|
||||
};
|
||||
return {
|
||||
useNavigation: () => ({
|
||||
navigate: jest.fn(),
|
||||
dispatch: jest.fn(),
|
||||
setOptions: jest.fn(),
|
||||
}),
|
||||
useRoute: () => ({
|
||||
params: {
|
||||
id: '123',
|
||||
},
|
||||
}),
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
@@ -256,9 +256,9 @@ In the app’s `jest.config.ts`, there should be an option called `moduleNameMap
|
||||
|
||||
```typescript
|
||||
module.exports = {
|
||||
moduleNameMapper: {
|
||||
uuid: require.resolve('uuid'),
|
||||
},
|
||||
moduleNameMapper: {
|
||||
uuid: require.resolve('uuid'),
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
@@ -268,9 +268,9 @@ Alternatively, I can also mock this library in the test files:
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
jest.mock('uuid', () => {
|
||||
return {
|
||||
v4: jest.fn(() => 1),
|
||||
};
|
||||
return {
|
||||
v4: jest.fn(() => 1),
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
@@ -317,8 +317,8 @@ transformIgnorePatterns: \[
|
||||
|
||||
If I have an error related to a library with an unexpected token, I need to check whether they are compiled or not.
|
||||
|
||||
- If this library source files are already transformed to `.js`, then its name should match regex, so it would be ignored, so it will NOT be transformed.
|
||||
- If this library source files are NOT transformed to `.js` (e.g. still in `.ts` or `.tsx`), then its name should NOT match regex, so it will be transformed.
|
||||
- If this library source files are already transformed to `.js`, then its name should match regex, so it would be ignored, so it will NOT be transformed.
|
||||
- If this library source files are NOT transformed to `.js` (e.g. still in `.ts` or `.tsx`), then its name should NOT match regex, so it will be transformed.
|
||||
|
||||
## Summary
|
||||
|
||||
@@ -328,9 +328,9 @@ With Nx, you do not need to explicitly install any testing library, so you can d
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Add Cypress, Playwright, and Storybook to Nx Expo Apps](https://medium.com/@emilyxiong/add-cypress-playwright-and-storybook-to-nx-expo-apps-1d3e409ce834)
|
||||
- 🧠 [Nx Docs](/getting-started/intro)
|
||||
- 👩💻 [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- 💬 [Nx Community Discord](https://go.nx.dev/community)
|
||||
- 📹 [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- 🚀 [Speed up your CI](https://nx.app/)
|
||||
- [Add Cypress, Playwright, and Storybook to Nx Expo Apps](https://medium.com/@emilyxiong/add-cypress-playwright-and-storybook-to-nx-expo-apps-1d3e409ce834)
|
||||
- 🧠 [Nx Docs](/getting-started/intro)
|
||||
- 👩💻 [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- 💬 [Nx Community Discord](https://go.nx.dev/community)
|
||||
- 📹 [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- 🚀 [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -8,16 +8,16 @@ tags: [nx, changelog, release]
|
||||
|
||||
It’s been a bit since we launched [Nx 17](/blog/nx-17-release)! In this article, we’ll go over some of the new developments and improvements that have landed in Nx 17.2:
|
||||
|
||||
- [Nx Closes In On 4 Million Weekly NPM Downloads!!](#nx-closes-in-on-4-million-weekly-npm-downloads)
|
||||
- [New Simplified Project Configuration On the Way](#new-simplified-project-configuration-on-the-way)
|
||||
- [Rust for Speed, Typescript for Extensibility](#rust-for-speed-typescript-for-extensibility)
|
||||
- [Module Federation Updates](#module-federation-updates)
|
||||
- [Nx Release Updates](#nx-release-updates)
|
||||
- [Angular 17 (AND NgRx 17) Support](#angular-17-and-ngrx-17-support)
|
||||
- [Smart Monorepos — Fast CI](#smart-monorepos-fast-ci)
|
||||
- [New Canary Releases](#new-canary-releases)
|
||||
- [Upcoming Release Livestream](#upcoming-release-livestream)
|
||||
- [Automatically Update Nx](#automatically-update-nx)
|
||||
- [Nx Closes In On 4 Million Weekly NPM Downloads!!](#nx-closes-in-on-4-million-weekly-npm-downloads)
|
||||
- [New Simplified Project Configuration On the Way](#new-simplified-project-configuration-on-the-way)
|
||||
- [Rust for Speed, Typescript for Extensibility](#rust-for-speed-typescript-for-extensibility)
|
||||
- [Module Federation Updates](#module-federation-updates)
|
||||
- [Nx Release Updates](#nx-release-updates)
|
||||
- [Angular 17 (AND NgRx 17) Support](#angular-17-and-ngrx-17-support)
|
||||
- [Smart Monorepos — Fast CI](#smart-monorepos-fast-ci)
|
||||
- [New Canary Releases](#new-canary-releases)
|
||||
- [Upcoming Release Livestream](#upcoming-release-livestream)
|
||||
- [Automatically Update Nx](#automatically-update-nx)
|
||||
|
||||
## Nx Closes In On 4 Million Weekly NPM Downloads!!
|
||||
|
||||
@@ -37,8 +37,8 @@ Using Nx at that level is definitely useful as you get intelligent parallelizati
|
||||
|
||||
This is something that’s gonna change drastically in 2024. And we’ve layed the first cornerstone for that. But it is behind a feature flag still as we’re streamlining the last bits. The goal?
|
||||
|
||||
- Going almost configuration-less (good defaults, you customize when you need to)
|
||||
- Allowing easy drop-in of Nx plugins into existing workspaces (provides immediate productivity gains, but stays out of your way)
|
||||
- Going almost configuration-less (good defaults, you customize when you need to)
|
||||
- Allowing easy drop-in of Nx plugins into existing workspaces (provides immediate productivity gains, but stays out of your way)
|
||||
|
||||
This opens up a series of possibilities which we’re already super excited about. You’ll hear more about this in the new year ;)
|
||||
|
||||
@@ -86,15 +86,15 @@ To give you full flexibility, in 17.2, we’ve added a programmatic API, which w
|
||||
import { releaseChangelog, releasePublish, releaseVersion } from 'nx/release';
|
||||
|
||||
(async () => {
|
||||
const { workspaceVersion, projectsVersionData } = await releaseVersion({
|
||||
specifier: 'minor',
|
||||
});
|
||||
await releaseChangelog({
|
||||
versionData: projectsVersionData,
|
||||
version: workspaceVersion,
|
||||
});
|
||||
await releasePublish();
|
||||
process.exit(0);
|
||||
const { workspaceVersion, projectsVersionData } = await releaseVersion({
|
||||
specifier: 'minor',
|
||||
});
|
||||
await releaseChangelog({
|
||||
versionData: projectsVersionData,
|
||||
version: workspaceVersion,
|
||||
});
|
||||
await releasePublish();
|
||||
process.exit(0);
|
||||
})();
|
||||
```
|
||||
|
||||
@@ -207,9 +207,9 @@ That’s all for now folks! We’re just starting up a new iteration of developm
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -10,25 +10,25 @@ It is that time again: getting flooded by Year of Review blog posts. We did it l
|
||||
|
||||
**Table of Contents**
|
||||
|
||||
- [Top 10 Nx Highlights of 2023](#top-10-nx-highlights-of-2023)
|
||||
- [TypeScript for Extensibility — Rust for Speed](#typescript-for-extensibility-rust-for-speed)
|
||||
- [First Class Vite Support](#first-class-vite-support)
|
||||
- [Nx’t Level Publishing](#nxt-level-publishing)
|
||||
- [Improved Node Backend Development: Fastify and Docker](#improved-node-backend-development-fastify-and-docker)
|
||||
- [Nx Console support for IntelliJ](#nx-console-support-for-intellij)
|
||||
- [Playwright for e2e testing](#playwright-for-e2e-testing)
|
||||
- [TypeScript Packaging and Batch Mode](#typescript-packaging-and-batch-mode)
|
||||
- [Nx team maintained Vue plugin](#nx-team-maintained-vue-plugin)
|
||||
- [Extending Nx: Local Generators, Build your Own CLI, Verdaccio Support](#extending-nx-local-generators-build-your-own-cli-verdaccio-support)
|
||||
- [Module Federation](#module-federation)
|
||||
- [Many OSS repos adopt Nx](#many-oss-repos-adopt-nx)
|
||||
- [Nx Community](#nx-community)
|
||||
- [New Content & Improved Docs](#new-content-improved-docs)
|
||||
- [New Tagline: Smart Monorepos — Fast CI](#new-tagline-smart-monorepos-fast-ci)
|
||||
- [Nx Conf](#nx-conf)
|
||||
- [Looking ahead — 2024](#looking-ahead-2024)
|
||||
- [Solving CI](#solving-ci)
|
||||
- [Solving the Simplicity vs Power Dilemma](#solving-the-simplicity-vs-power-dilemma)
|
||||
- [Top 10 Nx Highlights of 2023](#top-10-nx-highlights-of-2023)
|
||||
- [TypeScript for Extensibility — Rust for Speed](#typescript-for-extensibility-rust-for-speed)
|
||||
- [First Class Vite Support](#first-class-vite-support)
|
||||
- [Nx’t Level Publishing](#nxt-level-publishing)
|
||||
- [Improved Node Backend Development: Fastify and Docker](#improved-node-backend-development-fastify-and-docker)
|
||||
- [Nx Console support for IntelliJ](#nx-console-support-for-intellij)
|
||||
- [Playwright for e2e testing](#playwright-for-e2e-testing)
|
||||
- [TypeScript Packaging and Batch Mode](#typescript-packaging-and-batch-mode)
|
||||
- [Nx team maintained Vue plugin](#nx-team-maintained-vue-plugin)
|
||||
- [Extending Nx: Local Generators, Build your Own CLI, Verdaccio Support](#extending-nx-local-generators-build-your-own-cli-verdaccio-support)
|
||||
- [Module Federation](#module-federation)
|
||||
- [Many OSS repos adopt Nx](#many-oss-repos-adopt-nx)
|
||||
- [Nx Community](#nx-community)
|
||||
- [New Content & Improved Docs](#new-content-improved-docs)
|
||||
- [New Tagline: Smart Monorepos — Fast CI](#new-tagline-smart-monorepos-fast-ci)
|
||||
- [Nx Conf](#nx-conf)
|
||||
- [Looking ahead — 2024](#looking-ahead-2024)
|
||||
- [Solving CI](#solving-ci)
|
||||
- [Solving the Simplicity vs Power Dilemma](#solving-the-simplicity-vs-power-dilemma)
|
||||
|
||||
## Top 10 Nx Highlights of 2023
|
||||
|
||||
@@ -74,8 +74,8 @@ James Henry gave a deep dive talk of an early version of it at this year’s Nx
|
||||
|
||||
Since its introduction, the “nx release” feature has significantly evolved, leveraging the power of the Nx project graph to effectively understand inter-package dependencies. This understanding is crucial as it allows for:
|
||||
|
||||
- Versioning packages offering support for both independent and “locked” versioning strategies.
|
||||
- Releasing packages in the correct sequence, ensuring dependency integrity.
|
||||
- Versioning packages offering support for both independent and “locked” versioning strategies.
|
||||
- Releasing packages in the correct sequence, ensuring dependency integrity.
|
||||
|
||||
Beyond these core functionalities, the feature also includes a robust grouping mechanism, supports semantic versioning, and changelog generation. Additionally, it provides various release targets, such as GitHub and NPM. For those having special requirements, the [programmatic API](/features/manage-releases#using-the-programmatic-api-for-nx-release) offers maximum flexibility.
|
||||
|
||||
@@ -99,8 +99,8 @@ This year we not only added a lot of new features to Nx Console, but also rewrot
|
||||
|
||||
Yes, this means you can now use the latest Nx Console directly in your [Webstorm IDE](https://www.jetbrains.com/webstorm/). Read the [announcement blog post](https://blog.nrwl.io/expanding-nx-console-to-jetbrains-ides-8a5b80fff2d7) for all the details or go ahead and install Nx Console if you didn’t already:
|
||||
|
||||
- [Nx Console for VSCode](https://marketplace.visualstudio.com/items?itemName=nrwl.angular-console)
|
||||
- [Nx Console for IntelliJ](https://plugins.jetbrains.com/plugin/21060-nx-console)
|
||||
- [Nx Console for VSCode](https://marketplace.visualstudio.com/items?itemName=nrwl.angular-console)
|
||||
- [Nx Console for IntelliJ](https://plugins.jetbrains.com/plugin/21060-nx-console)
|
||||
|
||||
### Playwright for e2e testing
|
||||
|
||||
@@ -267,8 +267,8 @@ At Nx, we’re excited about the Module Federation support we offer for our user
|
||||
|
||||
By simply installing the `nx` package (or initializing with `nx init` in any project or monorepo), you already get some cool features:
|
||||
|
||||
- Advanced task scheduling, including task pipelines and parallel execution.
|
||||
- Efficient caching mechanisms.
|
||||
- Advanced task scheduling, including task pipelines and parallel execution.
|
||||
- Efficient caching mechanisms.
|
||||
|
||||
> If you want to learn more about such setup, make sure to check out our blog post on [how to adopt Nx on a npm/yarn/pnpm workspace](https://dev.to/nx/setup-a-monorepo-with-pnpm-workspaces-and-speed-it-up-with-nx-1eem) or the corresponding [video version](https://www.youtube.com/watch?si=0XH6Sp025xM3Rru5&v=ngdoUQBvAjo&feature=youtu.be).
|
||||
|
||||
@@ -312,10 +312,10 @@ Our [Youtube channel](https://www.youtube.com/@nxdevtools) has grown to over 15k
|
||||
|
||||
We also poured a lot of [effort into the docs](/getting-started/intro). We restructured them following the [Diataxis](https://diataxis.fr/) to make pages less overwhelming and more structured based on their type of content. You’ll find
|
||||
|
||||
- [**Concept docs**](/concepts) — which explain some of the inner workings and mental model behind certain features. Like [how caching works](/concepts/how-caching-works).
|
||||
- [**Recipes**](/recipes) — which are solution oriented. You already know how to cook, we provide the exact recipe for it.
|
||||
- [**Tutorials**](/getting-started/tutorials) — for when you just want to sit down and follow along, step by step to learn how to use Nx in a certain context.
|
||||
- [**Reference**](/reference) and [**API docs**](/nx-api) — pure, raw and to the point.
|
||||
- [**Concept docs**](/concepts) — which explain some of the inner workings and mental model behind certain features. Like [how caching works](/concepts/how-caching-works).
|
||||
- [**Recipes**](/recipes) — which are solution oriented. You already know how to cook, we provide the exact recipe for it.
|
||||
- [**Tutorials**](/getting-started/tutorials) — for when you just want to sit down and follow along, step by step to learn how to use Nx in a certain context.
|
||||
- [**Reference**](/reference) and [**API docs**](/nx-api) — pure, raw and to the point.
|
||||
|
||||
We created a brand new [“Why Nx”](/getting-started/why-nx) page explaining the overall architecture of Nx including a [brand new video](https://www.youtube.com/watch?v=-_4WMl-Fn0w) giving you a holistic overview of what Nx is capable of.
|
||||
|
||||
@@ -361,9 +361,9 @@ Legacy CI systems are a performance and productivity bottleneck if you use a pow
|
||||
|
||||
It has three components:
|
||||
|
||||
- [**Nx Cach**](/ci/features/remote-cache): Built-in local and remote caching to speed up your tasks and save you time and money. Available now.
|
||||
- [**Nx Agents**](/ci/features/distribute-task-execution): A single line to enable distributed computation, across multiple machines. Fully managed agents, dynamically allocated based on PR size. Available early Feb.
|
||||
- **Nx Workflows**: Next generation, fully managed CI solution with distribution at its core, designed from the ground up for monorepos. _Available later in 2024._
|
||||
- [**Nx Cach**](/ci/features/remote-cache): Built-in local and remote caching to speed up your tasks and save you time and money. Available now.
|
||||
- [**Nx Agents**](/ci/features/distribute-task-execution): A single line to enable distributed computation, across multiple machines. Fully managed agents, dynamically allocated based on PR size. Available early Feb.
|
||||
- **Nx Workflows**: Next generation, fully managed CI solution with distribution at its core, designed from the ground up for monorepos. _Available later in 2024._
|
||||
|
||||
Optimal parallelization and distribution, using the right numbers of agents for each PR, rerunning flaky tests, splitting and distributing large test suites, handling dependencies between tasks across machines — are just some of the things we can now handle automatically for you. Turn it on and enjoy the speed.
|
||||
|
||||
@@ -383,10 +383,10 @@ Exciting stuff! So keep an eye on our channels, and subscribe if you haven’t a
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools)
|
||||
- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools)
|
||||
- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -11,15 +11,15 @@ Enhance, but don’t interfere! That’s the ideal! And this is how extensions w
|
||||
|
||||
Table of Contents
|
||||
|
||||
- [Adding Nx to an Existing Monorepo](#adding-nx-to-an-existing-monorepo)
|
||||
- [Project Crystal](#project-crystal)
|
||||
- [Project Crystal Plugins in an Nx Monorepo](#project-crystal-plugins-in-an-nx-monorepo)
|
||||
- [Inferred Targets](#inferred-targets)
|
||||
- [Visualizing Inferred Targets](#visualizing-inferred-targets)
|
||||
- [More Transparency and a Single Source of Truth](#more-transparency-and-a-single-source-of-truth)
|
||||
- [Enhancing existing Monorepos with Nx Plugins](#enhancing-existing-monorepos-with-nx-plugins)
|
||||
- [This is just the Beginning](#this-is-just-the-beginning)
|
||||
- [Learn more](#learn-more)
|
||||
- [Adding Nx to an Existing Monorepo](#adding-nx-to-an-existing-monorepo)
|
||||
- [Project Crystal](#project-crystal)
|
||||
- [Project Crystal Plugins in an Nx Monorepo](#project-crystal-plugins-in-an-nx-monorepo)
|
||||
- [Inferred Targets](#inferred-targets)
|
||||
- [Visualizing Inferred Targets](#visualizing-inferred-targets)
|
||||
- [More Transparency and a Single Source of Truth](#more-transparency-and-a-single-source-of-truth)
|
||||
- [Enhancing existing Monorepos with Nx Plugins](#enhancing-existing-monorepos-with-nx-plugins)
|
||||
- [This is just the Beginning](#this-is-just-the-beginning)
|
||||
- [Learn more](#learn-more)
|
||||
|
||||
---
|
||||
|
||||
@@ -59,10 +59,10 @@ However, this is a balancing act. More abstraction and automation means more sup
|
||||
|
||||
Some of the main objectives of Project Crystal are to...
|
||||
|
||||
- make Nx plugins more transparent
|
||||
- reduce the amount of configuration required
|
||||
- allow Nx plugins to be drop-in enhancements in existing npm/yarn/pnpm monorepos
|
||||
- allow for a migration to an Nx plugin-powered monorepo
|
||||
- make Nx plugins more transparent
|
||||
- reduce the amount of configuration required
|
||||
- allow Nx plugins to be drop-in enhancements in existing npm/yarn/pnpm monorepos
|
||||
- allow for a migration to an Nx plugin-powered monorepo
|
||||
|
||||
## Project Crystal Plugins in an Nx Monorepo
|
||||
|
||||
@@ -78,12 +78,12 @@ npx create-nx-workspace myorg
|
||||
|
||||
```json {% fileName="project.json" }
|
||||
{
|
||||
"name": "reactapp",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "apps/reactapp/src",
|
||||
"projectType": "application",
|
||||
"targets": {},
|
||||
"tags": []
|
||||
"name": "reactapp",
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "apps/reactapp/src",
|
||||
"projectType": "application",
|
||||
"targets": {},
|
||||
"tags": []
|
||||
}
|
||||
```
|
||||
|
||||
@@ -181,8 +181,8 @@ We just released Project Crystal, so this is just the beginning of it. While we
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -12,11 +12,11 @@ We're excited to introduce a new way to enhance your [Nuxt](https://nuxt.com/) d
|
||||
|
||||
Using Nx with your Nuxt.js projects presents the following advantages:
|
||||
|
||||
- **Monorepo Management**: Simplify the management of multiple projects within a single repository, facilitating code sharing and reducing overhead.
|
||||
- **Modular Development**: Break down your Nuxt app into manageable, independent modules that can be developed, tested, and deployed in isolation.
|
||||
- **Enhanced Caching**: Accelerate your development with Nx's intelligent caching, automatically configured for your Nuxt projects.
|
||||
- **Nx generators**: Nx provides generators for scaffolding new Nuxt applications, with support for Jest, Storybook, and e2e test generation with Cypress or Playwright.
|
||||
- **Automated upgrades**: Nx offers a set of migrators that help you upgrade your projects.
|
||||
- **Monorepo Management**: Simplify the management of multiple projects within a single repository, facilitating code sharing and reducing overhead.
|
||||
- **Modular Development**: Break down your Nuxt app into manageable, independent modules that can be developed, tested, and deployed in isolation.
|
||||
- **Enhanced Caching**: Accelerate your development with Nx's intelligent caching, automatically configured for your Nuxt projects.
|
||||
- **Nx generators**: Nx provides generators for scaffolding new Nuxt applications, with support for Jest, Storybook, and e2e test generation with Cypress or Playwright.
|
||||
- **Automated upgrades**: Nx offers a set of migrators that help you upgrade your projects.
|
||||
|
||||
## Getting Started with Nx and Nuxt.js
|
||||
|
||||
@@ -57,9 +57,9 @@ Integrating Nx into an existing Nuxt.js project has never been easier, with the
|
||||
|
||||
When you run `nx init` in your existing Nuxt.js project, Nx does the following:
|
||||
|
||||
- **Installs @nx/nuxt**: Adds the necessary Nx and @nx/nuxt dependencies to your project, enabling Nx's features while keeping your existing setup intact.
|
||||
- **Understands Existing Configurations**: Nx automatically recognizes your nuxt.config.js or nuxt.config.ts file, ensuring that all your custom configurations, scripts, and commands are preserved and utilized.
|
||||
- **Minimal Configuration**: Only a minimal `nx.json` file is added to your project. This file is used to configure the `@nx/nuxt` plugin if needed, but in most cases, your existing Nuxt.js configurations will suffice.
|
||||
- **Installs @nx/nuxt**: Adds the necessary Nx and @nx/nuxt dependencies to your project, enabling Nx's features while keeping your existing setup intact.
|
||||
- **Understands Existing Configurations**: Nx automatically recognizes your nuxt.config.js or nuxt.config.ts file, ensuring that all your custom configurations, scripts, and commands are preserved and utilized.
|
||||
- **Minimal Configuration**: Only a minimal `nx.json` file is added to your project. This file is used to configure the `@nx/nuxt` plugin if needed, but in most cases, your existing Nuxt.js configurations will suffice.
|
||||
|
||||
To begin the integration process, simply navigate to the root of your existing Nuxt.js project and run:
|
||||
|
||||
@@ -69,9 +69,9 @@ npx nx init
|
||||
|
||||
This approach offers several key benefits for teams looking to adopt Nx:
|
||||
|
||||
- **Zero Disruption**: Your project will continue to use its existing configurations, and the existing configuration entrypoint files. There's no need to learn new configuration syntaxes or reconfigure your project to start using Nx.
|
||||
- **Immediate Value**: Instantly gain access to Nx's powerful developer tools and build system, without significant changes to your project.
|
||||
- **Future Flexibility**: As your project grows, Nx is ready to scale with you. You can gradually adopt more Nx features and plugins over time, at a pace that suits your team.
|
||||
- **Zero Disruption**: Your project will continue to use its existing configurations, and the existing configuration entrypoint files. There's no need to learn new configuration syntaxes or reconfigure your project to start using Nx.
|
||||
- **Immediate Value**: Instantly gain access to Nx's powerful developer tools and build system, without significant changes to your project.
|
||||
- **Future Flexibility**: As your project grows, Nx is ready to scale with you. You can gradually adopt more Nx features and plugins over time, at a pace that suits your team.
|
||||
|
||||
## Using Nx to run your Nuxt app
|
||||
|
||||
@@ -182,9 +182,9 @@ Whether you're starting a new Nuxt project or looking to enhance an existing one
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X / Twitter](https://twitter.com/nxdevtools) - [LinkedIn](https://www.linkedin.com/company/nrwl)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Community Discord](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X / Twitter](https://twitter.com/nxdevtools) - [LinkedIn](https://www.linkedin.com/company/nrwl)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Community Discord](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app)
|
||||
|
||||
@@ -27,32 +27,32 @@ The script below is a very simple example with only three tasks and one file bei
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build_base:
|
||||
steps:
|
||||
- run: npm run build-base
|
||||
- name: Save assets for use by other jobs
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: base_output
|
||||
path: base/output.ts
|
||||
build_base:
|
||||
steps:
|
||||
- run: npm run build-base
|
||||
- name: Save assets for use by other jobs
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: base_output
|
||||
path: base/output.ts
|
||||
|
||||
build_app1:
|
||||
needs: build_base
|
||||
steps:
|
||||
- name: Download base output
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: base_output
|
||||
- run: npm run build-app1
|
||||
build_app1:
|
||||
needs: build_base
|
||||
steps:
|
||||
- name: Download base output
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: base_output
|
||||
- run: npm run build-app1
|
||||
|
||||
build_app2:
|
||||
needs: build_base
|
||||
steps:
|
||||
- name: Download base output
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: base_output
|
||||
- run: npm run build-app2
|
||||
build_app2:
|
||||
needs: build_base
|
||||
steps:
|
||||
- name: Download base output
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: base_output
|
||||
- run: npm run build-app2
|
||||
```
|
||||
|
||||
At any point in the future, if a task is added to the system or there is a change to the output files of build_base, this pipeline will need to be updated.
|
||||
@@ -79,15 +79,15 @@ The pipeline configuration below will work no matter how many projects are in th
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
main:
|
||||
# Tell Nx Cloud how many agents to use and the name of the last task
|
||||
- run: |
|
||||
nx-cloud start-ci-run \
|
||||
--distribute-on="3 linux-medium-js" \
|
||||
--stop-agents-after="e2e-ci"
|
||||
# Run tasks the same way you would locally
|
||||
- run: nx affected -t lint test build --parallel=3
|
||||
- run: nx affected -t e2e-ci --parallel=1
|
||||
main:
|
||||
# Tell Nx Cloud how many agents to use and the name of the last task
|
||||
- run: |
|
||||
nx-cloud start-ci-run \
|
||||
--distribute-on="3 linux-medium-js" \
|
||||
--stop-agents-after="e2e-ci"
|
||||
# Run tasks the same way you would locally
|
||||
- run: nx affected -t lint test build --parallel=3
|
||||
- run: nx affected -t e2e-ci --parallel=1
|
||||
```
|
||||
|
||||
The only reason to modify this file is if you need to change the number of agent machines or there is another type of task that needs to run in CI.
|
||||
@@ -120,8 +120,8 @@ If you have a task that can’t be run on Nx Agents for some reason, you can eas
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -28,16 +28,16 @@ As you can see `@tuskdesign/forms` relies on `@tuskdesign/buttons` and as such h
|
||||
|
||||
## Table Of Contents
|
||||
|
||||
- [Adding Nx](#adding-nx)
|
||||
- [Installing the JavaScript/TypeScript versioning Package](#installing-the-javascripttypescript-versioning-package)
|
||||
- [Running Nx Release](#running-nx-release)
|
||||
- [Excluding Packages](#excluding-packages)
|
||||
- [Running the Versioning and Changelog Generation](#running-the-versioning-and-changelog-generation)
|
||||
- [Versioning using Conventional Commits](#versioning-using-conventional-commits)
|
||||
- [Generating a GitHub Release](#generating-a-github-release)
|
||||
- [Programmatic Mode](#programmatic-mode)
|
||||
- [Wrapping Up](#wrapping-up)
|
||||
- [Learn more](#learn-more)
|
||||
- [Adding Nx](#adding-nx)
|
||||
- [Installing the JavaScript/TypeScript versioning Package](#installing-the-javascripttypescript-versioning-package)
|
||||
- [Running Nx Release](#running-nx-release)
|
||||
- [Excluding Packages](#excluding-packages)
|
||||
- [Running the Versioning and Changelog Generation](#running-the-versioning-and-changelog-generation)
|
||||
- [Versioning using Conventional Commits](#versioning-using-conventional-commits)
|
||||
- [Generating a GitHub Release](#generating-a-github-release)
|
||||
- [Programmatic Mode](#programmatic-mode)
|
||||
- [Wrapping Up](#wrapping-up)
|
||||
- [Learn more](#learn-more)
|
||||
|
||||
## Adding Nx
|
||||
|
||||
@@ -91,12 +91,12 @@ pnpm nx release --dry-run --first-release
|
||||
|
||||
If you inspect the console output, you can see that:
|
||||
|
||||
- it would increment the version in the package.json
|
||||
- update the pnpm (or npm) lockfile
|
||||
- stage the changes with git
|
||||
- creates a `CHANGELOG.md` file
|
||||
- git commits everything
|
||||
- git tags the commit using the version
|
||||
- it would increment the version in the package.json
|
||||
- update the pnpm (or npm) lockfile
|
||||
- stage the changes with git
|
||||
- creates a `CHANGELOG.md` file
|
||||
- git commits everything
|
||||
- git tags the commit using the version
|
||||
|
||||
The dry-run mode also nicely previews all `package.json` changes in a git diff style:
|
||||
|
||||
@@ -108,9 +108,9 @@ Note, if you want to get even more insights into what is happening when running
|
||||
|
||||
If you look closely at the dry-run logs, you may notice that Nx Release bumped the version on all of our packages:
|
||||
|
||||
- `@tuskdesign/forms`
|
||||
- `@tuskdesign/buttons`
|
||||
- `@tuskdesign/demo`
|
||||
- `@tuskdesign/forms`
|
||||
- `@tuskdesign/buttons`
|
||||
- `@tuskdesign/demo`
|
||||
|
||||

|
||||
|
||||
@@ -221,9 +221,9 @@ Use the `createRelease` property and set it to `github`.
|
||||
|
||||
To see the working, you need to make sure to:
|
||||
|
||||
- push the repo to GitHub
|
||||
- make some change so you can run the `nx release` command again and get a changelog generated
|
||||
- now also get a GH release created
|
||||
- push the repo to GitHub
|
||||
- make some change so you can run the `nx release` command again and get a changelog generated
|
||||
- now also get a GH release created
|
||||
|
||||
Note, you can still use `--dry-run` and it'd show you the URL where the GitHub release would be created. You can also use the `--skip-publish` to skip the NPM publishing.
|
||||
|
||||
@@ -242,47 +242,47 @@ import { releaseChangelog, releasePublish, releaseVersion } from 'nx/release';
|
||||
import * as yargs from 'yargs';
|
||||
|
||||
(async () => {
|
||||
const options = await yargs
|
||||
.version(false) // don't use the default meaning of version in yargs
|
||||
.option('version', {
|
||||
description:
|
||||
'Explicit version specifier to use, if overriding conventional commits',
|
||||
type: 'string',
|
||||
})
|
||||
.option('dryRun', {
|
||||
alias: 'd',
|
||||
description:
|
||||
'Whether or not to perform a dry-run of the release process, defaults to true',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
})
|
||||
.option('verbose', {
|
||||
description:
|
||||
'Whether or not to enable verbose logging, defaults to false',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
})
|
||||
.parseAsync();
|
||||
const options = await yargs
|
||||
.version(false) // don't use the default meaning of version in yargs
|
||||
.option('version', {
|
||||
description:
|
||||
'Explicit version specifier to use, if overriding conventional commits',
|
||||
type: 'string',
|
||||
})
|
||||
.option('dryRun', {
|
||||
alias: 'd',
|
||||
description:
|
||||
'Whether or not to perform a dry-run of the release process, defaults to true',
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
})
|
||||
.option('verbose', {
|
||||
description:
|
||||
'Whether or not to enable verbose logging, defaults to false',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
})
|
||||
.parseAsync();
|
||||
|
||||
const { workspaceVersion, projectsVersionData } = await releaseVersion({
|
||||
specifier: options.version,
|
||||
dryRun: options.dryRun,
|
||||
verbose: options.verbose,
|
||||
});
|
||||
const { workspaceVersion, projectsVersionData } = await releaseVersion({
|
||||
specifier: options.version,
|
||||
dryRun: options.dryRun,
|
||||
verbose: options.verbose,
|
||||
});
|
||||
|
||||
await releaseChangelog({
|
||||
versionData: projectsVersionData,
|
||||
version: workspaceVersion,
|
||||
dryRun: options.dryRun,
|
||||
verbose: options.verbose,
|
||||
});
|
||||
await releaseChangelog({
|
||||
versionData: projectsVersionData,
|
||||
version: workspaceVersion,
|
||||
dryRun: options.dryRun,
|
||||
verbose: options.verbose,
|
||||
});
|
||||
|
||||
// The returned number value from releasePublish will be zero if all projects are published successfully, non-zero if not
|
||||
const publishStatus = await releasePublish({
|
||||
dryRun: options.dryRun,
|
||||
verbose: options.verbose,
|
||||
});
|
||||
process.exit(publishStatus);
|
||||
// The returned number value from releasePublish will be zero if all projects are published successfully, non-zero if not
|
||||
const publishStatus = await releasePublish({
|
||||
dryRun: options.dryRun,
|
||||
verbose: options.verbose,
|
||||
});
|
||||
process.exit(publishStatus);
|
||||
})();
|
||||
```
|
||||
|
||||
@@ -296,8 +296,8 @@ Notice by default in the script we have `dry-run` enabled as a more cautious app
|
||||
|
||||
From here on you have full control and can pretty much do whatever works best for your workspace setup. Common examples include:
|
||||
|
||||
- moving files to a common root-level `dist/` folder and version and release them from there. This is pretty common to avoid messing with your src files and swapping versions there, allowing you to always depend on the latest local packages for instance.
|
||||
- setting up fully automated releases on CI, including enabling provenance support. Our docs have [more details on how to set that up](/recipes/nx-release/publish-in-ci-cd) or check out the linked talk above which goes through those steps.
|
||||
- moving files to a common root-level `dist/` folder and version and release them from there. This is pretty common to avoid messing with your src files and swapping versions there, allowing you to always depend on the latest local packages for instance.
|
||||
- setting up fully automated releases on CI, including enabling provenance support. Our docs have [more details on how to set that up](/recipes/nx-release/publish-in-ci-cd) or check out the linked talk above which goes through those steps.
|
||||
|
||||
## Wrapping Up
|
||||
|
||||
@@ -305,18 +305,18 @@ With this release of Nx Release it is fully ready to be used. Make sure to check
|
||||
|
||||
Here are some example repositories already leveraging Nx release:
|
||||
|
||||
- [Our own Nx Repo](https://github.com/nrwl/nx/blob/master/scripts/nx-release.ts)
|
||||
- [RxJS repo](https://github.com/ReactiveX/rxjs/tree/master/scripts)
|
||||
- [Typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/blob/main/tools/release/release.mts)
|
||||
- [Watch the live stream](https://www.youtube.com/watch?v=lYNa6Ct4RkY) with [Kent](https://twitter.com/kentcdodds) and [James](https://twitter.com/MrJamesHenry) as they enable Nx Release on the [EpicWeb workshop app repository](https://github.com/epicweb-dev/kcdshop)
|
||||
- [Our own Nx Repo](https://github.com/nrwl/nx/blob/master/scripts/nx-release.ts)
|
||||
- [RxJS repo](https://github.com/ReactiveX/rxjs/tree/master/scripts)
|
||||
- [Typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/blob/main/tools/release/release.mts)
|
||||
- [Watch the live stream](https://www.youtube.com/watch?v=lYNa6Ct4RkY) with [Kent](https://twitter.com/kentcdodds) and [James](https://twitter.com/MrJamesHenry) as they enable Nx Release on the [EpicWeb workshop app repository](https://github.com/epicweb-dev/kcdshop)
|
||||
|
||||
---
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X / Twitter](https://twitter.com/nxdevtools) — [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X / Twitter](https://twitter.com/nxdevtools) — [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -16,16 +16,16 @@ In this article, we’re going to recap all the things launched during Launch Nx
|
||||
|
||||
---
|
||||
|
||||
- [Nx 18.0 && Project Crystal](#nx-180-project-crystal)
|
||||
- [Project Crystal — By Juri Strumpflohner](#conference-talk-project-crystal)
|
||||
- [Project Crystal + .NET in Action — By Craigory Coppola](#conference-talk-project-crystal-net-in-action)
|
||||
- [New Plugin: @nx/nuxt](#new-plugin-nxnuxt)
|
||||
- [Nx Agents](#nx-agents-launched)
|
||||
- [Nx Agents Walkthrough: Effortlessly Fast CI Built for Monorepos — By Rares Matei](#conference-talk-nx-agents-walkthrough-effortlessly-fast-ci-built-for-monorepos)
|
||||
- [Solving E2E Tests — By Altan Stalker](#conference-talk-solving-e2e-tests)
|
||||
- [Tusky](#tusky)
|
||||
- [Nx Release](#nx-release-is-stable)
|
||||
- [Releasing Nx Release — By James Henry](#conference-talk-releasing-nx-release)
|
||||
- [Nx 18.0 && Project Crystal](#nx-180-project-crystal)
|
||||
- [Project Crystal — By Juri Strumpflohner](#conference-talk-project-crystal)
|
||||
- [Project Crystal + .NET in Action — By Craigory Coppola](#conference-talk-project-crystal-net-in-action)
|
||||
- [New Plugin: @nx/nuxt](#new-plugin-nxnuxt)
|
||||
- [Nx Agents](#nx-agents-launched)
|
||||
- [Nx Agents Walkthrough: Effortlessly Fast CI Built for Monorepos — By Rares Matei](#conference-talk-nx-agents-walkthrough-effortlessly-fast-ci-built-for-monorepos)
|
||||
- [Solving E2E Tests — By Altan Stalker](#conference-talk-solving-e2e-tests)
|
||||
- [Tusky](#tusky)
|
||||
- [Nx Release](#nx-release-is-stable)
|
||||
- [Releasing Nx Release — By James Henry](#conference-talk-releasing-nx-release)
|
||||
|
||||
## Nx 18.0 && Project Crystal
|
||||
|
||||
@@ -141,8 +141,8 @@ That’s all for now folks! We’re just starting up a new iteration of developm
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -14,15 +14,15 @@ Nx is a suite of powerful tools designed to optimize your development workflow,
|
||||
|
||||
The ability to iterate quickly and efficiently is vital for any software project. Speed in the development process offers several critical advantages:
|
||||
|
||||
- **Faster feedback loops:** Quick iterations mean immediate feedback, allowing teams to adapt, learn, and improve their work on the fly.
|
||||
- **Reduced time to market:** Accelerating the development process can significantly cut down the overall time to market, providing a competitive edge which reclaims revenue that would have otherwise been lost.
|
||||
- **Decreased developer frustration:** [No more waiting for builds and tests to complete](/ci/concepts/reduce-waste). A streamlined workflow keeps morale high and productivity higher.
|
||||
- **Faster feedback loops:** Quick iterations mean immediate feedback, allowing teams to adapt, learn, and improve their work on the fly.
|
||||
- **Reduced time to market:** Accelerating the development process can significantly cut down the overall time to market, providing a competitive edge which reclaims revenue that would have otherwise been lost.
|
||||
- **Decreased developer frustration:** [No more waiting for builds and tests to complete](/ci/concepts/reduce-waste). A streamlined workflow keeps morale high and productivity higher.
|
||||
|
||||
If you’re using Nx already, you’re already familiar with
|
||||
|
||||
- [**Affected**](/ci/features/affected) - identifying and running tasks only on projects impacted by code changes,
|
||||
- [**Nx Replay**](/ci/features/remote-cache) - our powerful cache and
|
||||
- [**Nx Agents**](/ci/features/distribute-task-execution) - the concept of [Parallelization and Distribution](/ci/concepts/parallelization-distribution).
|
||||
- [**Affected**](/ci/features/affected) - identifying and running tasks only on projects impacted by code changes,
|
||||
- [**Nx Replay**](/ci/features/remote-cache) - our powerful cache and
|
||||
- [**Nx Agents**](/ci/features/distribute-task-execution) - the concept of [Parallelization and Distribution](/ci/concepts/parallelization-distribution).
|
||||
|
||||
But let’s see all the extra things we did this past year to make everything faster.
|
||||
|
||||
@@ -54,13 +54,13 @@ With Nx Replay, you can see significant speed improvements in your CI pipelines
|
||||
|
||||
[Nx Agents](/ci/features/distribute-task-execution) represent the pinnacle of task distribution optimization, ensuring that tasks are executed as efficiently as possible based on the specific requirements of each change. Some features that make up this effort are:
|
||||
|
||||
- [Easy integration with existing providers](/ci/recipes/set-up)
|
||||
- Distribution is handled on the Nx Cloud infrastructure and all you need is a single line. What’s more, all results are played back to your original CI provider script which triggers the Nx Cloud distribution, so that you can make use of the resulting artifacts
|
||||
- [Efficient task distribution](/ci/features/dynamic-agents)
|
||||
- Save compute resources and reduce costs, minimizing idle time and compute waste
|
||||
- Dynamic sizing based on PR size
|
||||
- [Tusky](https://nx.app/products/tusky) - our AI solution - coming soon
|
||||
- You set your desired cost/speed ratio, and you forget about any more configuration. We ensure maximum speed up to limits you set yourself.
|
||||
- [Easy integration with existing providers](/ci/features/distribute-task-execution#cicd-guides)
|
||||
- Distribution is handled on the Nx Cloud infrastructure and all you need is a single line. What’s more, all results are played back to your original CI provider script which triggers the Nx Cloud distribution, so that you can make use of the resulting artifacts
|
||||
- [Efficient task distribution](/ci/features/dynamic-agents)
|
||||
- Save compute resources and reduce costs, minimizing idle time and compute waste
|
||||
- Dynamic sizing based on PR size
|
||||
- [Tusky](https://nx.app/products/tusky) - our AI solution - coming soon
|
||||
- You set your desired cost/speed ratio, and you forget about any more configuration. We ensure maximum speed up to limits you set yourself.
|
||||
|
||||
You can read more about Nx Agents [here](https://nx.app/products/agents#content).
|
||||
|
||||
@@ -96,10 +96,10 @@ Nx provides an unparalleled toolkit for developers and teams looking to optimize
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X / Twitter](https://twitter.com/nxdevtools)
|
||||
- [LinkedIn](https://www.linkedin.com/company/nrwl)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Community Discord](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X / Twitter](https://twitter.com/nxdevtools)
|
||||
- [LinkedIn](https://www.linkedin.com/company/nrwl)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Community Discord](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app)
|
||||
|
||||
@@ -4,7 +4,6 @@ slug: 'reliable-ci-a-new-execution-model-fixing-both-flakiness-and-slowness'
|
||||
authors: [Victor Savkin]
|
||||
cover_image: '/blog/images/2024-03-21/featured_img.png'
|
||||
tags: [nx, nx-cloud, releases]
|
||||
pinned: true
|
||||
---
|
||||
|
||||
The proverbial slow and flaky CI isn’t the failure of the developers or even the testing tools. It’s the failure of the CI execution model we relied on for the last 20 years.
|
||||
@@ -43,16 +42,16 @@ To understand why the traditional CI execution model fails to handle failures, l
|
||||
|
||||
Failures can be:
|
||||
|
||||
- hard _(npm fails to install, nothing can run)_
|
||||
- soft _(a test takes a lot longer than it should because, perhaps, due to an out-of-memory issue)_
|
||||
- hard _(npm fails to install, nothing can run)_
|
||||
- soft _(a test takes a lot longer than it should because, perhaps, due to an out-of-memory issue)_
|
||||
|
||||
Focusing on the latter is just as important as focusing on the former. **Slow CI is broken CI.**
|
||||
|
||||
Tasks can fail:
|
||||
|
||||
- legitimately _(a broken build)_
|
||||
- for external reasons _(npm install fails cause npm is down)_
|
||||
- for unknown reasons _(a flaky test)_
|
||||
- legitimately _(a broken build)_
|
||||
- for external reasons _(npm install fails cause npm is down)_
|
||||
- for unknown reasons _(a flaky test)_
|
||||
|
||||
**The traditional CI execution model doesn’t tolerate any of these failures.**
|
||||
|
||||
@@ -181,10 +180,10 @@ We also have a **Pro for Startups** plan which offers agents that are 3.5x cheap
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X / Twitter](https://twitter.com/nxdevtools)
|
||||
- [LinkedIn](https://www.linkedin.com/company/nrwl)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Community Discord](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X / Twitter](https://twitter.com/nxdevtools)
|
||||
- [LinkedIn](https://www.linkedin.com/company/nrwl)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Community Discord](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app)
|
||||
|
||||
@@ -16,9 +16,9 @@ The Nx Gradle plugin registers Gradle projects in your Nx workspace. It allows G
|
||||
|
||||
This blog will show you:
|
||||
|
||||
- [What is Nx?](#what-is-nx)
|
||||
- [How to add Nx to a Gradle workspace](#how-to-add-nx-to-a-gradle-workspace)
|
||||
- [How to add @nx/gradle to an existing Nx workspace](#how-to-add-nxgradle-to-an-existing-nx-workspace)
|
||||
- [What is Nx?](#what-is-nx)
|
||||
- [How to add Nx to a Gradle workspace](#how-to-add-nx-to-a-gradle-workspace)
|
||||
- [How to add @nx/gradle to an existing Nx workspace](#how-to-add-nxgradle-to-an-existing-nx-workspace)
|
||||
|
||||
---
|
||||
|
||||
@@ -30,10 +30,10 @@ From [nx.dev](): “Nx is a build system with built-in tooling and advanced CI c
|
||||
|
||||
Nx adds the following features to your workspace:
|
||||
|
||||
- [Cache task results](/features/cache-task-results): By storing task outputs in a cache, subsequent runs can skip redundant computations and reuse previously calculated results, significantly speeding up build processes. Nx intelligently manages this caching mechanism, invalidating the cache automatically when relevant inputs change.
|
||||
- [Distribute task execution](/ci/features/distribute-task-execution): Nx CI efficiently distributes tasks across multiple machines for faster build times. It uses a distributed task execution algorithm to intelligently divide and assign tasks to available resources, minimizing redundant work and maximizing parallelism.
|
||||
- [Run only tasks affected by a PR](/ci/features/affected): Nx identifies changes made since a specified base commit or branch, and then selectively runs tasks (like tests, linting, or builds) related to those changes.
|
||||
- [Interactively explore your workspace](/features/explore-graph): Nx allows developers to visualize and understand the dependencies and relationships within their projects.
|
||||
- [Cache task results](/features/cache-task-results): By storing task outputs in a cache, subsequent runs can skip redundant computations and reuse previously calculated results, significantly speeding up build processes. Nx intelligently manages this caching mechanism, invalidating the cache automatically when relevant inputs change.
|
||||
- [Distribute task execution](/ci/features/distribute-task-execution): Nx CI efficiently distributes tasks across multiple machines for faster build times. It uses a distributed task execution algorithm to intelligently divide and assign tasks to available resources, minimizing redundant work and maximizing parallelism.
|
||||
- [Run only tasks affected by a PR](/ci/features/affected): Nx identifies changes made since a specified base commit or branch, and then selectively runs tasks (like tests, linting, or builds) related to those changes.
|
||||
- [Interactively explore your workspace](/features/explore-graph): Nx allows developers to visualize and understand the dependencies and relationships within their projects.
|
||||
|
||||

|
||||
|
||||
@@ -147,8 +147,8 @@ Furthermore, instead of running the command in terminal, you can use the editor
|
||||
|
||||
To download:
|
||||
|
||||
- [**Nx Console - Visual Studio Marketplace**](https://marketplace.visualstudio.com/items?itemName=nrwl.angular-console)
|
||||
- [**Nx Console - IntelliJ IDEs Plugin | Marketplace**](https://plugins.jetbrains.com/plugin/21060-nx-console)
|
||||
- [**Nx Console - Visual Studio Marketplace**](https://marketplace.visualstudio.com/items?itemName=nrwl.angular-console)
|
||||
- [**Nx Console - IntelliJ IDEs Plugin | Marketplace**](https://plugins.jetbrains.com/plugin/21060-nx-console)
|
||||
|
||||
---
|
||||
|
||||
@@ -176,8 +176,8 @@ For example, if you run `./gradlew :app:build` or `gradlew.bat :app:build` using
|
||||
|
||||
The `@nx/gradle` plugin will create an Nx project for each Gradle configuration file present. Any of the following files will be recognized as a Gradle configuration file:
|
||||
|
||||
- `gradle.build`
|
||||
- `gradle.build.kts`
|
||||
- `gradle.build`
|
||||
- `gradle.build.kts`
|
||||
|
||||
### @nx/gradle Configuration
|
||||
|
||||
@@ -185,16 +185,16 @@ The `@nx/gradle` is configured in the plugins array in `nx.json`:
|
||||
|
||||
```json {% fileName="nx.json" %}
|
||||
{
|
||||
"plugins": [
|
||||
{
|
||||
"plugin": "@nx/gradle",
|
||||
"options": {
|
||||
"testTargetName": "test",
|
||||
"classesTargetName": "classes",
|
||||
"buildTargetName": "build"
|
||||
"plugins": [
|
||||
{
|
||||
"plugin": "@nx/gradle",
|
||||
"options": {
|
||||
"testTargetName": "test",
|
||||
"classesTargetName": "classes",
|
||||
"buildTargetName": "build"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -210,9 +210,9 @@ Here is how to set up Nx with the Gradle workspace. Hopefully, this gives you a
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -20,17 +20,17 @@ Nx 19 represents a return to form, matching the reliable 6-month schedule. Nx 19
|
||||
|
||||
Here's the rundown of the major things we'll cover in this update:
|
||||
|
||||
- [NEW PLUGIN: @nx/gradle](#new-plugin-nxgradle)
|
||||
- [Nx Atomizer Enhancements](#nx-atomizer-enhancements)
|
||||
- [Associated Technologies Added To Tasks](#associated-technologies-added-to-tasks)
|
||||
- [Generators to Convert to Project Crystal](#generators-to-convert-to-project-crystal)
|
||||
- [BREAKING CHANGE: Updating Bundled Environment Variables: `NX_` to `NX_PUBLIC_`](#breaking-change-updating-bundled-environment-variables-to)
|
||||
- [General Crystal Polishing](#general-crystal-polishing)
|
||||
- [Nx Cloud Updates!](#nx-cloud-updates)
|
||||
- [More Miscellaneous Updates!](#more-miscellaneous-updates)
|
||||
- [New Conference: Monorepo World 2024](#new-conference-monorepo-world-2024)
|
||||
- [Wrapping Up, And A Heartfelt Thank You](#wrapping-up-and-a-heartfelt-thank-you)
|
||||
- [Learn More](#learn-more)
|
||||
- [NEW PLUGIN: @nx/gradle](#new-plugin-nxgradle)
|
||||
- [Nx Atomizer Enhancements](#nx-atomizer-enhancements)
|
||||
- [Associated Technologies Added To Tasks](#associated-technologies-added-to-tasks)
|
||||
- [Generators to Convert to Project Crystal](#generators-to-convert-to-project-crystal)
|
||||
- [BREAKING CHANGE: Updating Bundled Environment Variables: `NX_` to `NX_PUBLIC_`](#breaking-change-updating-bundled-environment-variables-to)
|
||||
- [General Crystal Polishing](#general-crystal-polishing)
|
||||
- [Nx Cloud Updates!](#nx-cloud-updates)
|
||||
- [More Miscellaneous Updates!](#more-miscellaneous-updates)
|
||||
- [New Conference: Monorepo World 2024](#new-conference-monorepo-world-2024)
|
||||
- [Wrapping Up, And A Heartfelt Thank You](#wrapping-up-and-a-heartfelt-thank-you)
|
||||
- [Learn More](#learn-more)
|
||||
|
||||
**Prefer a video?**
|
||||
|
||||
@@ -82,7 +82,7 @@ Notice how all tasks are now appropriately grouped in the `E2E (CI)` group!
|
||||
|
||||
You can also find the same enhancements in Nx Cloud. Below is a view of all tasks in the [CI pipeline](https://staging.nx.app/runs/ctbAZfiLy3):
|
||||
|
||||
{% video-player src="/documentation/blog/media/2024-05-08/nx-cloud-atomizer-groupings.mp4" alt="Showing the Atomizer in Nx Cloud" link="https://staging.nx.app/runs/ctbAZfiLy3" /%}
|
||||
[](https://staging.nx.app/runs/ctbAZfiLy3)
|
||||
|
||||
Notice how all e2e groups are collapsed by default to give a concise view, while allowing you to expand to see how each individual task is progressing!
|
||||
|
||||
@@ -160,7 +160,7 @@ Since Nx 18 release, we also started using Project Crystal inside of the Nx repo
|
||||
|
||||
You can find a full list of fixes and features applied in this major release [here](https://github.com/nrwl/nx/releases/tag/19.0.0).
|
||||
|
||||
{% video-player src="/documentation/blog/media/2024-05-08/fixes.mp4" alt="A display listing the Github changelog" /%}
|
||||
[](https://github.com/nrwl/nx/releases/tag/19.0.0)
|
||||
|
||||
With Project Crystal landed now, we're also adjusting our priorities to place a higher importance on stability. You should see this reflected in Nx 19.
|
||||
|
||||
@@ -174,15 +174,15 @@ In addition - we are adding more process to make the triage of these issues more
|
||||
|
||||
We've got some cool stats to share from our users regarding the benefits of [Nx Cloud](https://nx.app), our premium CI service. The three areas we've identified as the critical aspects of a CI provider are: speed, cost, and reliablity. In these areas we've seen:
|
||||
|
||||
- **speed**: Reported 30% - 70% faster CI
|
||||
- **cost**: Reported 40% - 75% reduction in CI costs
|
||||
- **reliability**: Nx Cloud's automatic detection and retrying of flaky tests makes the issue of flaky tests largely go away entirely. You can read more on [our thoughts on reliability here](/blog/reliable-ci-a-new-execution-model-fixing-both-flakiness-and-slowness).
|
||||
- **speed**: Reported 30% - 70% faster CI
|
||||
- **cost**: Reported 40% - 75% reduction in CI costs
|
||||
- **reliability**: Nx Cloud's automatic detection and retrying of flaky tests makes the issue of flaky tests largely go away entirely. You can read more on [our thoughts on reliability here](/blog/reliable-ci-a-new-execution-model-fixing-both-flakiness-and-slowness).
|
||||
|
||||
In February, we launched two big enhancements to Nx Cloud: the [Atomizer](/ci/features/split-e2e-tasks) and [Nx Agents](https://nx.app/products/agents#content).
|
||||
|
||||
Since then, the Atomizer has received a nice UI update (as we had seen earlier):
|
||||
|
||||
{% video-player src="/documentation/blog/media/2024-05-08/nx-cloud-atomizer-groupings.mp4" alt="Showing the Atomizer in Nx Cloud" link="https://staging.nx.app/runs/ctbAZfiLy3" /%}
|
||||
[](https://staging.nx.app/runs/ctbAZfiLy3)
|
||||
|
||||
Since February, we also revamped our task distribution algorithms. This has resulted in a 5-20% (depending on the repo) increase in both speed and cost efficiency for our users.
|
||||
|
||||
@@ -230,9 +230,9 @@ Zack
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
title: 'Nx Enterprise Podcast Episode 1: Hicham El Hammouchi'
|
||||
slug: 'hicham-el-hammouchi-podcast-1'
|
||||
authors: ['Zack DeRose']
|
||||
tags: [podcast]
|
||||
cover_image: /blog/images/2024-06-18/ep-1-hicham.png
|
||||
podcastYoutubeId: 8iiLB_2djZ8
|
||||
podcastSpotifyId: 24yagCNpu9EGj0fCwSDQkj
|
||||
podcastAmazonUrl: https://music.amazon.com/podcasts/a221fdad-36fd-4695-a5b4-038d7b99d284/episodes/899a2e4c-2e56-4dfa-a3e3-e69eb216f2b0/the-enterprise-software-podcast-by-nx-the-enterprise-software-podcast-by-nx-1-hicham-el-hamouchi
|
||||
podcastAppleUrl: https://podcasters.spotify.com/pod/show/enterprise-software/episodes/The-Enterprise-Software-Podcast-By-Nx-1--Hicham-El-Hamouchi-e2l0302
|
||||
podcastIHeartUrl: https://www.iheart.com/podcast/269-the-enterprise-software-po-186891508/episode/the-enterprise-software-podcast-by-nx-186891511/
|
||||
---
|
||||
|
||||
In this episode, Zack DeRose from Nx chats with Hicham El Hammouchi, a veteran in enterprise software. Hicham dives into his background, sharing his career journey and the wealth of experience he's gathered along the way.
|
||||
|
||||
They tackle the tough challenges that companies face in software development. Hicham offers practical insights and real-life examples from his own career, making complex issues easier to understand. He also shares some tried-and-true strategies for overcoming these hurdles, emphasizing the importance of teamwork and effective project management.
|
||||
|
||||
As the chat continues, Zack and Hicham explore the latest tech trends and innovations that are shaking up the industry. Hicham's forward-thinking views provide a sneak peek into the future of enterprise software. They also discuss detailed case studies of successful projects, highlighting the importance of staying focused on customer needs and feedback.
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
title: 'Nx Enterprise Podcast Episode 2: Tine Kondo'
|
||||
slug: 'tine-kondo-podcast-2'
|
||||
authors: ['Zack DeRose']
|
||||
tags: [podcast]
|
||||
cover_image: /blog/images/2024-07-19/ep-2-tine.png
|
||||
podcastYoutubeId: Nzf3BmymfEo
|
||||
podcastSpotifyId: 0CCQaWCln7rvwkkVvsyxsk
|
||||
podcastAmazonUrl: https://music.amazon.com/podcasts/a221fdad-36fd-4695-a5b4-038d7b99d284/episodes/53934cd9-c521-441e-8523-8b947ed207ca/the-enterprise-software-podcast-by-nx-the-enterprise-software-podcast-by-nx-2-tine-kondo
|
||||
podcastAppleUrl: https://podcasts.apple.com/us/podcast/the-enterprise-software-podcast-by-nx-2-tine-kondo/id1752704996?i=1000662764990
|
||||
podcastIHeartUrl: https://www.iheart.com/podcast/269-the-enterprise-software-po-186891508/episode/the-enterprise-software-podcast-by-nx-197335640/
|
||||
---
|
||||
|
||||
In this episode, welcome Nx Champion and Nx Expert, Tine Kondo. Our discussion highlights how Nx is poised to make an impact in the Java space.
|
||||
|
||||
We touch on the difficulties larger organizations face when merging PRs in a timely manner, emphasizing how a monorepo alleviates the headache of coordinating multiple PRs across various repositories, and share firsthand experiences and frustrations with traditional multi-repo setups, underscoring the benefits of a unified approach.
|
||||
|
||||
In particular, Nx's new plugin: [@nx/gradle](/nx-api/gradle) is of interest, and Tine provides some valuable insight on the impact this plugin can make, as well as the importance for Maven support.
|
||||
@@ -1,59 +0,0 @@
|
||||
---
|
||||
title: Introducing Explain with AI
|
||||
slug: 'explain-with-ai'
|
||||
authors: ['Philip Fulcher']
|
||||
cover_image: '/blog/images/2024-07-29/explain-with-ai-header.avif'
|
||||
tags: [nx, nx-cloud, ai, release]
|
||||
youtubeUrl: https://youtu.be/g2m9cHp-O-Q?si=ax-SKCO0Xvy9vFIz
|
||||
pinned: true
|
||||
---
|
||||
|
||||
It's Friday, and you absolutely, positively have to deploy to production. But you can't get CI to pass your PR. What do you do? It's an inevitable part of your life as a developer, and you've built a collection of tools to deal with it: Google, MDN, Discord, ChatGPT. We've got one more tool for your toolbox: **"Explain with AI" for [Nx Cloud](/nx-cloud)**.
|
||||
|
||||
## Your ticket to fast error debugging
|
||||
|
||||
"[Explain with AI](/ci/features/explain-with-ai)" is a new feature for all Nx Cloud Pro users that is going to help you troubleshoot those pesky failing tasks. Whenever you get an error message on CI, look for the "Explain with AI" button on the upper right-hand corner:
|
||||
|
||||

|
||||
|
||||
Once you hit that button, we collect the terminal output and other Nx task information and sprinkle some AI on top of it to give you a suggested fix. That should help you quickly get to the bottom of the issue and get back to work quickly.
|
||||
|
||||

|
||||
|
||||
No more switching back and forth between a dozen tabs with different solutions. No more providing the right context for your masterfully written chat prompt. **Get your suggested fix and get back to work.**
|
||||
|
||||
Also make sure [to check out our docs](/ci/features/explain-with-ai) for more information.
|
||||
|
||||
## How can I start using this today?
|
||||
|
||||

|
||||
|
||||
Here's how you get started:
|
||||
|
||||
- **Step 1:** Go to your [Nx Cloud](https://cloud.nx.app/) organization settings
|
||||
- **Step 2:** Enable AI features
|
||||
- **Step 3:** Accept the Nx Cloud AI terms and conditions.
|
||||
- **Step 4:** You're all set ✨
|
||||
|
||||
Note that you'll need to be an organization admin for your Nx Cloud workspace to enable AI features.
|
||||
|
||||
{% call-to-action title="Log in to Nx Cloud" url="https://cloud.nx.app" icon="nxcloud" description="Enable AI features in your organization settings" %}
|
||||
Log in to Nx Cloud
|
||||
{% /call-to-action %}
|
||||
|
||||
### I want to try this, but I'm on the Hobby plan 🤔
|
||||
|
||||
If you're currently on the Hobby plan, you can start a free Pro plan trial for 14 days to try it out on your own workspace. No, we don't ask for credit cards to start a trial, so feel free to experiment!
|
||||
|
||||
## More to come!
|
||||
|
||||
This is just the first of a series of AI-powered features that we're going to be rolling out to your workspaces. We've got some cool features in the works already, which we're going to **announce publicly during the [Monorepo World](https://monorepo.world) conference in October**! So stay tuned!
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
@@ -1,295 +0,0 @@
|
||||
---
|
||||
title: 'Nx 19.5 is here! Stackblitz, Bun, Incremental Builds for Vite, Gradle Test Atomizer'
|
||||
slug: 'nx-19-5-adds-stackblitz-new-features-and-more'
|
||||
authors: ['Zack DeRose']
|
||||
cover_image: '/blog/images/2024-08-01/nx-19-5-thumbnail.png'
|
||||
tags: [nx, release]
|
||||
pinned: true
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
In this blog post:
|
||||
|
||||
- [Video Summary](#video-summary)
|
||||
- [Announcing Nx Cloud Hobby Tier](#announcing-nx-cloud-hobby-tier)
|
||||
- [StackBlitz Support](#stackblitz-support)
|
||||
- [Bun and Pnpm v9 Support](#bun-and-pnpm-v9-support)
|
||||
- [Local Flaky Task Detection](#local-flaky-task-detection)
|
||||
- [Project Detail View Enhancements](#project-detail-view-enhancements)
|
||||
- [Pattern Support for `targetDefaults`](#pattern-support-for-targetdefaults)
|
||||
- [Individual Targets Can Now Opt Out of Parallelism](#individual-targets-can-now-opt-out-of-parallelism)
|
||||
- [Support For Incremental Builds For Vite](#support-for-incremental-builds-for-vite)
|
||||
- [Project Crystal Conversion Generators](#project-crystal-conversion-generators)
|
||||
- [Gradle Composite Builds Support](#gradle-composite-builds-support)
|
||||
- [Experimental: Gradle Test Atomization](#experimental-gradle-test-atomization)
|
||||
- [Experimental: Nx Release Adds File Based Versioning Support](#experimental-nx-release-adds-file-based-versioning-support)
|
||||
- [Support for React 19 (rc) and Angular 18.1](#support-for-react-19-rc-and-angular-181)
|
||||
- [Automatically Update Nx](#automatically-update-nx)
|
||||
- [Monorepo World Conference Speakers Announced!!](#monorepo-world-conference-speakers-announced)
|
||||
- [Learn more](#learn-more)
|
||||
|
||||
## Video Summary
|
||||
|
||||
{% youtube
|
||||
src="https://youtu.be/ER-6sKbb9ck"
|
||||
title="Nx 19.5 is here! Stackblitz, Bun, AND MORE!"
|
||||
width="100%" /%}
|
||||
|
||||
## Announcing Nx Cloud Hobby Tier
|
||||
|
||||
We just added a new [Hobby Tier](/pricing#plan-details) to Nx Cloud! Why is this exciting? It is completely free and contains all major features, which includes the ability to [distribute your tasks with Nx Agents](/ci/features/distribute-task-execution).
|
||||
|
||||
This gives you plenty of opportunities to experiment with Nx Cloud on your workspace and see its impact on your teams productivity.
|
||||
|
||||
[](/pricing#plan-details)
|
||||
|
||||
Checkout the [plan details page](/pricing#plan-details) for more info, and see how Nx Cloud can help you! And in case you missed it, check out our latest blog on the latest Nx Cloud feature: [Explain with AI](/blog/explain-with-ai)!
|
||||
|
||||
## StackBlitz Support
|
||||
|
||||
Nx now has support for [Stackblitz](https://stackblitz.com/) (again). For a while it was not possible to use Nx on Stackblitz because we implemented some perf critical parts of Nx as native components with Rust. Huge shoutout to [LongYinan](https://github.com/Brooooooklyn) for [their amazing work of pushing napi-rs](https://napi.rs/) forward and helping us [add WebAssembly support to Nx](https://github.com/nrwl/nx/pull/22870) as well as the StackBlitz team who helped debug issues.
|
||||
|
||||
This means we are back and you can create a StackBlitz with a whole Nx Workspace inside it and run all Nx capabilities from their embedded terminal.
|
||||
|
||||
[](https://stackblitz.com/edit/stackblitz-webcontainer-api-starter-cwruaw?file=apps%2Freact-app%2Fsrc%2Fapp%2Fapp.tsx)
|
||||
|
||||
[Check out the example](https://stackblitz.com/edit/stackblitz-webcontainer-api-starter-cwruaw?file=apps%2Freact-app%2Fsrc%2Fapp%2Fapp.tsx) above. You can use the standard Nx commands in the Stackblitz terminal, like
|
||||
|
||||
```shell
|
||||
nx serve react-app
|
||||
```
|
||||
|
||||
We're excited about this as it opens up many interesting use cases, including easier ways of sharing examples, better opportunities for reproducing issues or bugs, and the potential for us to use embedded examples in our documentation in the future.
|
||||
|
||||
Again, special shout out to community contributor [LongYinan](https://github.com/Brooooooklyn) and [their napi-rs project](https://napi.rs/).
|
||||
|
||||
## Bun and Pnpm v9 Support
|
||||
|
||||
We've been monitoring [Bun](https://bun.sh/) for a while both as a runtime and as a package manager, and we've decided to take the first step in Bun support now by supporting [Bun as a package manager](https://bun.sh/docs/cli/install)! This means that you can now use Bun like you would use npm, pnpm, or yarn to install and manage your dependencies, and Nx will be able to correctly understand those dependencies as `externalNodes` in the Nx dependency graph.
|
||||
|
||||
Sending a big thank you to community contributor [Jordan Hall](https://github.com/Jordan-Hall) for completing [this work](https://github.com/nrwl/nx/pull/22602).
|
||||
|
||||
In addition to supporting Bun, Nx now supports the latest format of [`pnpm`](https://pnpm.io/) lockfiles which was introduced in version 9.
|
||||
|
||||
## Local Flaky Task Detection
|
||||
|
||||
Nx Cloud has long offered [flaky task detection](/ci/features/flaky-tasks) on CI, and now this capability is available **even when running them locally**.
|
||||
|
||||

|
||||
|
||||
If a task is detected as flaky during local execution, you’ll receive a warning. Nx identifies flaky tasks by tracking the outcomes of your tasks in relation to your source code and external dependencies. When the same code produces different results, Nx flags the task as flaky and triggers the warning.
|
||||
|
||||
Detecting flaky tasks in the local environment empowers developers to address issues early in the development cycle—before they affect your CI pipelines.
|
||||
|
||||
## Project Detail View Enhancements
|
||||
|
||||
As part of [project Crystal](/concepts/inferred-tasks) we've added the ability to our plugins to automatically infer tasks based on the tools and configuration files available in your workspace. As part of that we created the "project detail view", allowing you to visualize such dynamically created tasks. You can launch it by using the [Nx Console IDE plugin](/getting-started/editor-setup) or by running the command:
|
||||
|
||||
```shell
|
||||
nx show project [projectName]
|
||||
```
|
||||
|
||||
In this iteration we've added several enhancements to the project detail view. For one, we've added more instructions on how to discover options for the underlying tools, and included examples on how to adjust these options via your `project.json` file.
|
||||
|
||||

|
||||
|
||||
In addition, we've added a callout for tasks that [leverage the `Nx Atomizer`](/ci/features/split-e2e-tasks). Since atomizer tasks are designed to be used with [Nx Agents](/ci/features/distribute-task-execution#distribute-task-execution-nx-agents), this callout will appear in yellow to warn if your project is not yet configured to run them on CI, and you can click on this callout for an easy way to complete that setup:
|
||||
|
||||

|
||||
|
||||
Clicking this button will launch the [Nx Cloud onboarding](https://cloud.nx.app) process, which will generate a PR in your repository to complete the setup.
|
||||
|
||||

|
||||
|
||||
Note that the new, free [hobby tier for Nx Cloud](#new-nx-cloud-hobby-tier) includes the ability to run [Nx Agents](/ci/features/distribute-task-execution) without the need to immediately jump onto a paid plan.
|
||||
|
||||
## Pattern Support for `targetDefaults`
|
||||
|
||||
When using the [Atomizer features](/ci/features/split-e2e-tasks) of plugins like [`@nx/playwright`](/nx-api/playwright) and [`@nx/cypress`](/nx-api/cypress), you end up creating tasks with dynamic but predictable names.
|
||||
|
||||

|
||||
|
||||
Notice how the `e2e-ci--src/example.spec.ts` and `e2e-ci--src/test.spec.ts` tasks here are created by the `@nx/playwright` plugin dynamically based on the playwright spec files present in your workspace.
|
||||
|
||||
We've now **added pattern matching** to `targetDefaults` task names as a way to target these dynamic tasks.
|
||||
|
||||
In the past it was difficult to customize this dynamic set of targets. But with the new support for specifying a pattern to a target name, you can now customize this set of dynamic targets all at once.
|
||||
|
||||
The following will set all such tasks to depend on their `build` task:
|
||||
|
||||
```json
|
||||
{
|
||||
"targetDefaults": {
|
||||
"e2e-ci--**/*": {
|
||||
"dependsOn": ["build"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that our plugins will set sensible configurations here out of the box when creating new workspaces using our generators.
|
||||
|
||||
Read more about [reducing configuration with `targetDefaults`](/recipes/running-tasks/reduce-repetitive-configuration#reduce-configuration-with-targetdefaults) and [how you can define task pipelines with `targetDefaults`](/features/run-tasks#defining-a-task-pipeline).
|
||||
|
||||
## Individual Targets Can Now Opt Out of Parallelism
|
||||
|
||||
One of our goals in transforming the CI landscape is to **make CI more declarative** by focusing on defining the "what" rather than the "how."
|
||||
|
||||
To accommodate port collisions in end-to-end tests, we've long adjusted our generated CI script to look like this:
|
||||
|
||||
```yml
|
||||
- run: npx nx affected -t lint test build
|
||||
- run: npx nx affected --parallel 1 -t e2e-ci
|
||||
```
|
||||
|
||||
Unfortunately, this approach is more imperative, as it instructs how to run and order your CI rather than defining what should be run. Additionally, these instructions cause `lint`, `test`, and `build` targets to run first and wait until they all complete before running `e2e-ci`, leading to inefficiencies.
|
||||
|
||||
To address this, all tasks now support a [`parallelism` property](/reference/project-configuration#parallelism). By setting this property to `false`, you can instruct the Nx task runner not to run a specific task in parallel. This allows us to define parallelism as a task property, making our CI configuration more declarative.
|
||||
|
||||
Both our `@nx/playwright` and `@nx/cypress` plugins will now automatically set `targetDefaults` for atomized tests to disable parallelism:
|
||||
|
||||
```json {% fileName="nx.json" %}
|
||||
{
|
||||
// ...
|
||||
"targetDefaults": {
|
||||
"e2e-**/*": {
|
||||
// ...
|
||||
"parallelism": false
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This way we can simply run the command:
|
||||
|
||||
```shell
|
||||
nx affected --targets=lint,test,build,e2e-ci
|
||||
```
|
||||
|
||||
In CI, Nx Agents will allow all tasks to run in parallel on the same machine, except for the atomized end-to-end tasks, which will only run in isolation.
|
||||
|
||||
Learn more about how you can [Parallelize Tasks Across Multiple Machines Using Nx Agents](/ci/intro/tutorials/github-actions#parallelize-tasks-across-multiple-machines-using-nx-agents):
|
||||
|
||||
{% youtube
|
||||
src="https://youtu.be/0YxcxIR7QU0"
|
||||
title="Faster e2e Tests!"
|
||||
width="100%" /%}
|
||||
|
||||
## Support For Incremental Builds For Vite
|
||||
|
||||
Nx now supports incremental builds with our [`vite` plugin](/nx-api/vite). Incremental builds in Nx workspaces allow you to build any package in your workspace individually, and will then automatically use that built artifact when then building any project or application that consumes the package. This way you can speed up your build and CI times through optimizations like [only building packages that were affected](/nx-api/nx/documents/affected), using [Nx Replay](/ci/features/remote-cache) to effortlessly cache and share your built artifacts, and allowing you to run builds of your various packages in parallel using [Nx Agents](/ci/features/distribute-task-execution).
|
||||
|
||||
Read more about [buildable libraries and incremental builds](/concepts/buildable-and-publishable-libraries).
|
||||
|
||||
## Project Crystal Conversion Generators
|
||||
|
||||
Since launching [Nx Project Crystal](/concepts/inferred-tasks) in Nx version 18, we've adjusted our generators to leverage these features when creating new workspaces and projects. We've now added the `convert-to-inferred` generator to give you an automated way to opt into project crystal.
|
||||
|
||||
To run the generator, you can run the command:
|
||||
|
||||
```shell
|
||||
npx nx g convert-to-inferred
|
||||
```
|
||||
|
||||
The important thing to note here is that while this generator will make adjustments to the `project.json` file of the projects you convert, the behavior of your tasks should remain the same. You can see project details via the [Nx Console](/getting-started/editor-setup) plugin of your IDE, or in a browser by running the command: `nx show project [projectName]`.
|
||||
|
||||
In Nx 19, we were focused on adding `convert-to-inferred` to our [Playwright](/nx-api/playwright), [Cypress](/nx-api/cypress), and [ESLint](/nx-api/eslint) plugins - where bringing the [Nx Atomizer](/ci/features/split-e2e-tasks) provided the greatest value. Since then, we've added this generator to most other plugins. Currently, our React native plugins (react native, expo, detox) are the only plugins that are outstanding, and we'll be providing `convert-to-inferred` generators here in the near future.
|
||||
|
||||
## Gradle Composite Builds Support
|
||||
|
||||
In [Nx 19.0](/blog/nx-19-release), we introduced support for Gradle through our [Gradle plugin](/nx-api/gradle). With the latest update, this plugin now also supports [Gradle Composite builds](https://docs.gradle.org/current/userguide/composite_builds.html), in addition to multi-project builds.
|
||||
|
||||
Gradle Composite builds are commonly used in larger workspaces to manage dependencies across multiple projects. With this new support, Nx can now leverage composite builds to enhance the Nx Task Graph. For example, consider the following `settings.gradle.kts` file:
|
||||
|
||||
```kotlin
|
||||
rootProject.name = "app"
|
||||
|
||||
includeBuild("number-utils")
|
||||
includeBuild("string-utils")
|
||||
```
|
||||
|
||||
Nx will now be able to automatically determine the dependencies between the `app` project and the `number-utils` and `string-utils` workspaces:
|
||||
|
||||

|
||||
|
||||
You can read more on composite builds in the [Gradle documentation](https://docs.gradle.org/current/userguide/composite_builds.html).
|
||||
|
||||
## Experimental: Gradle Test Atomization
|
||||
|
||||
The new [`@nx/gradle` plugin](/nx-api/gradle) now includes experimental support for [Test Atomization](/ci/features/split-e2e-tasks).
|
||||
|
||||

|
||||
|
||||
With Test Atomization, as you add tests to your Gradle projects, Nx will automatically create a separate task for each test class. This allows you to distribute the execution of these tasks across multiple machines on CI, similar to the functionality provided by our `@nx/playwright` and `@nx/cypress` plugins.
|
||||
|
||||
## Experimental: Nx Release Adds File Based Versioning Support
|
||||
|
||||
Currently with [Nx release](/nx-api/nx/documents/release), you already have two different ways of figuring out the how to modify the current version of a package to get its updated version:
|
||||
|
||||
- Imperatively via the CLI/prompt by telling it your desired relative (semver keyword) or absolute (e.g. `1.2.3`) version.
|
||||
- Declaratively by letting Nx inspect your git history and determine the semver bump to apply based on the conventional commits specification.
|
||||
|
||||
Nx release now supports an experimental third way of deriving the version bump that we call "version plans".
|
||||
|
||||
The idea behind version plans is that you want to track your intended version bumps alongside your changes, just like you would do with conventional commits, but you want to make this tracking independent from your actual commit data. This might be because you do not want to/cannot use the conventional commits standard in your workspace, or it could just be that you find it a cleaner approach to versioning.
|
||||
|
||||
Version plan files use frontmatter enhanced markdown for their contents, and can be created by hand or by leveraging the new `nx release plan` subcommand. This will guide you through creating a git-tracked file within `.nx/version-plans` that will be committed alongside your normal changes.
|
||||
|
||||

|
||||
|
||||
When your team is ready to release, you can now simply run the CLI command `nx release` (or use the [powerful programmatic API](/features/manage-releases#using-the-programmatic-api-for-nx-release)) and nx will ingest all the outstanding version plan files and use the combined information to determine the resulting version for all referenced projects and/or release groups as part of the versioning, changelog generation, and publishing steps. (You can also run the command `nx release version` if all you want to do is update the version!)
|
||||
|
||||

|
||||
|
||||
Anyone who has used the tools "Changesets" or "Beachball" will be familiar with the concept of file based versioning, but with Nx release you get the power to combine one or more of the above mentioned versioning strategies all within the same workspace for different release groups, and we are really excited to keep building out this feature set and mark it as non-experimental (by fully documenting it) very soon. To learn more about the other features of [Nx Release in the meantime, check out our docs](/features/manage-releases).
|
||||
|
||||
## Support for React 19 (rc) and Angular 18.1
|
||||
|
||||
Nx 19.5 adds support for the React 19 release candidate and updated our Angular package to support the latest Angular minor version: 18.1.
|
||||
|
||||
When using our `@nx/angular` package, we'll automatically update you to the latest angular version when you run our migration. Using the `--interactive` flag you can choose to opt in or out of the latest Angular version:
|
||||
|
||||
```shell
|
||||
nx migrate latest --interactive
|
||||
✔ Do you want to update to TypeScript v5.5? (Y/n) · true
|
||||
✔ Do you want to update the Angular version to v18.1? (Y/n) · true
|
||||
Fetching @angular/core@18.1.2
|
||||
|
||||
NX The migrate command has run successfully.
|
||||
```
|
||||
|
||||
Our `@nx/react` package will now create new React applications using version 18.3, and we now support the new experimental `reactCompiler`. Users can install the [`babel-plugin-react-compiler` package](https://www.npmjs.com/package/babel-plugin-react-compiler) and you can follow [this guide for how to enable it with Nx](/recipes/react/react-compiler#react-compiler-with-nx).
|
||||
|
||||
Note that due to the extent of breaking changes coming with React 19, we will not be providing a automated migration to React 19 via [`nx migrate`](/nx-api/nx/documents/migrate).
|
||||
|
||||
## Automatically Update Nx
|
||||
|
||||
As always - updating Nx and its plugins is easy as we ship an [automated migration command](/features/automate-updating-dependencies).
|
||||
|
||||
```shell
|
||||
npx nx migrate latest
|
||||
```
|
||||
|
||||
After updating your dependencies, run any necessary migrations.
|
||||
|
||||
```shell
|
||||
npx nx migrate --run-migrations
|
||||
```
|
||||
|
||||
## Monorepo World Conference Speakers Announced!!
|
||||
|
||||
[](https://monorepo.world)
|
||||
|
||||
The [Monorepo World conference](https://monorepo.world) is coming up soon on October 7, 2024 at the Computer History museum in Mountain View, California.
|
||||
|
||||
[Get your tickets now](https://ti.to/nx-conf/monorepoworld2024), consider [requesting access to the invite-only Enterprise Summit on October 8](https://ti.to/nx-conf/monorepoworld2024), and be sure to check out our [list of speakers](https://monorepo.world/#speakers-title) that was just published!
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
@@ -1,16 +0,0 @@
|
||||
---
|
||||
title: 'Nx Enterprise Podcast Episode 3: Ahmed Elsakaan'
|
||||
slug: 'ahmed-elsakaan-podcast-3'
|
||||
authors: ['Zack DeRose']
|
||||
tags: [podcast]
|
||||
cover_image: /blog/images/2024-08-14/ep-3-ahmed.png
|
||||
podcastYoutubeId: l_b6EOXqYRg
|
||||
podcastSpotifyId: 4d4oE8B3y9BmECZ3P4uvDP
|
||||
podcastAmazonUrl: https://music.amazon.com/podcasts/a221fdad-36fd-4695-a5b4-038d7b99d284/episodes/28209cf9-1b88-48b5-a798-7b24c843e9b1/the-enterprise-software-podcast-by-nx-the-enterprise-software-podcast-by-nx-3-ahmed-elsakaan
|
||||
podcastAppleUrl: https://podcasts.apple.com/us/podcast/the-enterprise-software-podcast-by-nx-3-ahmed-elsakaan/id1752704996?i=1000665363260
|
||||
podcastIHeartUrl: https://www.iheart.com/podcast/269-the-enterprise-software-po-186891508/episode/the-enterprise-software-podcast-by-nx-205664230/
|
||||
---
|
||||
|
||||
In this episode we welcome Nx Champion and creator of [noodle](https://noodle.run) and [OrbitKit](https://orbitkit.dev/): Ahmed Elsakaan.
|
||||
|
||||
As a monorepo enthusiast, we explore Ahmed's thoughts on monorepos and how these tools can add value to developers - both in the space of setting up your monorepo (like Nx does) and in the space of creating reusable customizable modules (like OrbitKit is attempting).
|
||||
@@ -1,16 +0,0 @@
|
||||
---
|
||||
title: 'Nx Enterprise Podcast Episode 4: Cvent Platform Architecture Panel'
|
||||
slug: 'cvent-podcast-3'
|
||||
authors: ['Zack DeRose']
|
||||
tags: [podcast]
|
||||
cover_image: /blog/images/2024-08-21/ep-4-cvent.png
|
||||
podcastYoutubeId: _7uK1V_xu9k
|
||||
podcastSpotifyId: 1zWuMFxcnGy90AN41gkodx
|
||||
podcastAmazonUrl: https://music.amazon.com/podcasts/a221fdad-36fd-4695-a5b4-038d7b99d284/episodes/7e19eb25-76f9-4d1e-89c0-c2fd1f585f9b/the-enterprise-software-podcast-by-nx-the-enterprise-software-podcast-by-nx-4-cvent-platform-architect-panel
|
||||
podcastAppleUrl: https://podcasts.apple.com/us/podcast/the-enterprise-software-podcast-by-nx-4-cvent/id1752704996?i=1000666133320
|
||||
podcastIHeartUrl: https://www.iheart.com/podcast/269-the-enterprise-software-po-186891508/episode/the-enterprise-software-podcast-by-nx-207751657/
|
||||
---
|
||||
|
||||
In this edition of the Nx Enterprise Podcast, Zack sits down with a panel of Platform Architects from the event platform company, [Cvent](https://www.cvent.com/).
|
||||
|
||||
The panel, featuring Youssef Taghlabi, Kevin O'Brien, Josh Lartz, and Ladi Kobiti, dives into their approach to platform engineering—focusing on how they empower teams across their organization and the critical role Nx plays in achieving those goals.
|
||||
@@ -1,47 +0,0 @@
|
||||
---
|
||||
title: New Table Log View on CI with Nx Cloud
|
||||
slug: improved-ci-log-with-nx-cloud
|
||||
authors: ['Juri Strumpflohner']
|
||||
tags: [nx-cloud, release]
|
||||
cover_image: /blog/images/2024-08/nx-cloud-table-log-output-thumb.jpg
|
||||
youtubeUrl: https://youtu.be/aacrw0H0m4Q
|
||||
---
|
||||
|
||||
Whenever we talk about Nx Cloud, speed is often a major focus—and for good reason. However, Nx Cloud isn't just about speed. Similar to Nx itself, it's about making work within monorepos more pleasant and efficient. A key part of that is continuously **optimizing developer ergonomics**.
|
||||
|
||||
Structuring your log output is one example. In a polyrepo setup, this isn't a big deal since you typically run tasks for a single project. However, in a monorepo setup, you might be running hundreds of tasks in parallel across multiple projects. **Quickly finding a failed task in this context can be challenging.**
|
||||
|
||||
## New Table Log View
|
||||
|
||||
Today, we released an update that improves how logs are displayed on your CI provider when using Nx Cloud. Instead of streaming all logs directly into your CI provider's pipeline, **we now render a structured table view**. This table shows all tasks, their status (success or failure), timing, and whether they had a cache hit or miss.
|
||||
|
||||

|
||||
|
||||
At the end of the log output, you'll also see aggregated stats about executed tasks, cache hits, and a link to the Nx Cloud dashboard with full details of the run.
|
||||
|
||||

|
||||
|
||||
## Revert to the Old Behavior
|
||||
|
||||
If you prefer the previous log view in your CI, you can opt-out of the new table view. Simply go to your Nx Cloud workspace settings and enable the "Display live terminal outputs in CI pipeline log" option.
|
||||
|
||||

|
||||
|
||||
## Not Using Nx Cloud Yet?
|
||||
|
||||
If you're not on Nx Cloud yet, you can **connect your Nx workspace** by running:
|
||||
|
||||
```shell
|
||||
npx nx connect
|
||||
```
|
||||
|
||||
This command will guide you through the setup. We recently introduced a [new Hobby plan](/pricing), which lets you experiment with all the Nx Cloud features for free. This is a great way to see if it's a good fit for your team.
|
||||
|
||||
## Learn More
|
||||
|
||||
- [Nx on CI](/ci)
|
||||
- [Task Distribution with Nx Agents](/ci/features/distribute-task-execution)
|
||||
- [Automated e2e Test Splitting](/ci/features/split-e2e-tasks)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
title: How to Fast-Track Your PRs with Trunk.io | Nx Live
|
||||
slug: nx-live-trunk-io
|
||||
authors: ['Zack DeRose']
|
||||
tags: [livestream]
|
||||
cover_image: /blog/images/2024-08-29/nx-live-trunk.png
|
||||
youtubeUrl: https://youtube.com/live/E8Gh-Vkxok0
|
||||
---
|
||||
|
||||
In this episode of Nx Live, Zack sits down with David from [Trunk.io](https://trunk.io) to explore hands-on examples of how to fast-track your PRs using Nx and Trunk Merge Queues. They also discuss the latest [first-class support for Nx](https://docs.trunk.io/merge-queue/parallel-queues/nx) recently added to Trunk, demonstrating how these tools can streamline your development workflow.
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
title: Announcing your Monorepo World Speakers
|
||||
slug: announcing-your-monorepo-world-speakers
|
||||
authors: ['Mike Hartington']
|
||||
tags: [monorepo-world]
|
||||
cover_image: /blog/images/2024-08-30/mw-blog-post.avif
|
||||
---
|
||||
|
||||
[Monorepo World](https://monorepo.world) is our two-track conference bringing together experts in developer tooling and of course, monorepos. We’re thrilled to share some of this year's speakers, including folks from Zephyr Cloud, Atlassian, GitHub, and HeroDevs. Without further ado, let’s meet your first round of speakers!
|
||||
|
||||
### Hacking Bundlers in Nx
|
||||
|
||||
[Lois Zhao](https://x.com/zmzlois), Zephyr Cloud
|
||||
|
||||
Want to know how builders work and how they can impact your projects? Let’s look at various bundlers and see how they affect the build time and output while also potentially saving organizations millions of dollars.
|
||||
|
||||
### What's In Your Dependency Graph
|
||||
|
||||
[Josh VanAllen](https://x.com/JVAsays), HeroDevs
|
||||
|
||||
Ever ask yourself “why is this build taking so long?” You’re not alone. With monorepos, managing your workspace’s dependency graph can make the difference between spending countless hours waiting to see if your simple changes fixes your apps. Learn how to find the hidden bottlenecks in your dependency graphs and make them efficient!
|
||||
|
||||
### How To Use Git - The Right Way - For Monorepos
|
||||
|
||||
[Scott Arbeit](https://x.com/ScottArbeit), GitHub
|
||||
|
||||
We all use git in our day to day, and it’s great! Until you have to clone a large repository, like potentially a monorepo. Thankfully, there are some tips and tricks you can use to work with large repositories and git that can greatly improve your user experience.
|
||||
|
||||
### Atlassian Frontend's Journey To The Monorepo
|
||||
|
||||
Manoraj K & Sourav Shaw, Atlassian
|
||||
|
||||
Adopting a monorepo for an organization can be a transformative experience. Learn from the folks at Atlassian to hear how they migrated to a monorepo and what strategies they employ to merge multiple repositories into one unified structure.
|
||||
|
||||
## Get Your Tickets Today
|
||||
|
||||
We hope you’re excited to see these amazing sessions! We’ll have more to share soon about what other speakers you can expect to see at Monorepo world! Don’t forget to register and get your ticket before prices go up September 6th 😱!
|
||||
|
||||
[Get your tickets today!](https://bit.ly/3YZcb5r)
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
title: Introduction to Nx! | Nx Live
|
||||
slug: nx-live-intro-to-nx
|
||||
authors: ['Zack DeRose', 'Mike Hartington']
|
||||
tags: [livestream]
|
||||
cover_image: /blog/images/2024-09-05/thumbnail.png
|
||||
youtubeUrl: https://youtube.com/live/dgtZ6GHZ-tA
|
||||
---
|
||||
|
||||
In this episode of Nx Live, Zack introduces new Nx team member Mike Hartington to the value of Nx. Together, Zack and Mike build out a full-stack application in their workspace - complete with linting, testing, and end-to-end tests using Nx's generators, and they look at the capabilities that Nx offers in terms of defining their workspace, and how Nx can leverage that information for task-running - especially in CI!
|
||||
@@ -1,94 +0,0 @@
|
||||
---
|
||||
title: Better security with Personal Access Tokens
|
||||
slug: personal-access-tokens
|
||||
authors: ['Philip Fulcher']
|
||||
tags: [nx-cloud]
|
||||
cover_image: /blog/images/2024-09-10/personal-access-tokens-header.avif
|
||||
youtubeUrl: https://youtu.be/i51LPtagb2s
|
||||
---
|
||||
|
||||
Today, Nx Cloud gets a huge upgrade to managing access to your cached artifacts
|
||||
using [Nx Replay](/ci/features/remote-cache). Previously, workspaces
|
||||
were limited to defining access tokens with read or read/write permissions for an entire workspace. With the
|
||||
introduction of _personal access tokens_, you gain much more control over access. This is a feature request we've heard
|
||||
from many customers, especially our [Enterprise](/enterprise) customers, and we're happy to be able to deliver this
|
||||
enhancement.
|
||||
|
||||
## Access Tokens and the problem of revoking access
|
||||
|
||||
Our previous implementation of access tokens required you to commit the access token to your `nx.json` file. Typically,
|
||||
service providers don't recommend committing any kind of API token like this, and we've fielded a lot of questions about
|
||||
this practice in the past. It is safe to commit this token, as access to the cached artifacts of Nx Cloud rely on both
|
||||
the access token and the source code itself. Without access to both, you can't access the cache.
|
||||
|
||||
However, this did present the following problem: revoking someone's access to the cache became difficult as long as they
|
||||
had the source code. Imagine a scenario where someone has left an organization. As long as they have a clone of the
|
||||
repo, they have everything they need to access the cache, even if their credentials have been
|
||||
revoked. To fully revoke
|
||||
their access would require cycling the access token, which could interrupt the work of other developers and CI
|
||||
pipelines.
|
||||
|
||||
## Access Tokens become CI Access Tokens
|
||||
|
||||
What we previously called "access tokens" will now be called "[CI access tokens](/ci/recipes/security/access-tokens)."
|
||||
They are still defined at the workspace
|
||||
level, but are designed for use in CI. These tokens should be set as environment variables or secrets on your CI
|
||||
platform so that they're no longer committed to your repo.
|
||||
|
||||
## What are personal access tokens?
|
||||
|
||||
[Personal access tokens](/ci/recipes/security/personal-access-tokens) are a new type of access token that is scoped to
|
||||
an individual user, rather than the workspace. This token authenticates the user with Nx Cloud when running tasks, so that we can validate their access to the distributed cache for a workspace. As soon as a user loses access to an Nx Cloud organization, they will no longer be able to access the cache for any of the organization's workspaces. The user's token belongs to them and will still allow access to their remaining organizations.
|
||||
|
||||
This gets even more powerful when combined with the GitHub VCS integration. When a user's GitHub access is removed from
|
||||
a GitHub-connected organization, their access to your Nx Cloud organization is removed, and their access to the cache for any of the organization's workspaces is removed.
|
||||
This means that Nx Cloud can fit into existing user de-provisioning processes you already have.
|
||||
|
||||
Open source teams also benefit from personal access tokens. You can configure your access to allow anonymous users to
|
||||
read from the cache, but limit read/write access to core contributors.
|
||||
|
||||
## Controlling default access
|
||||
|
||||

|
||||
|
||||
By default, a workspace that opts in to personal access tokens will allow anonymous users (users without a personal
|
||||
access token defined) read-write access. This can be changed to disallow access to the cache for anonymous users
|
||||
in your workspace settings.
|
||||
|
||||
Users with personal access tokens will also have read-write access to the cache. This can be changed to enable read-only
|
||||
access in the workspace settings.
|
||||
|
||||
## Converting existing workspaces to use personal access tokens
|
||||
|
||||
Personal access tokens can be enabled with _Nx versions 13+_. These steps will get you started, but you
|
||||
can [find more details in our docs](/ci/recipes/security/personal-access-tokens).
|
||||
|
||||
1. **Convert to using `nxCloudId` by running `npx nx-cloud convert-to-nx-cloud-id`** - Previously, your `nx.json` had a
|
||||
CI
|
||||
access token defined in the `nxCloudAccessToken` property. This command will replace that with `nxCloudId`, a generic
|
||||
id that references your workspace but no longer provides access to the cache.
|
||||
2. **Generate a personal access token by running `npx nx login`** - Follow the directions in your terminal to log
|
||||
in
|
||||
to Nx Cloud. Each contributor with access to the workspace will need to complete this step.
|
||||
3. **Move CI access tokens to environment variables** - Now that the access token is no longer committed to your
|
||||
`nx.json`,
|
||||
you'll need to provide that CI access token via the
|
||||
`NX_CLOUD_ACCESS_TOKEN` [environment variable](/ci/reference/env-vars#nxcloudaccesstoken).
|
||||
4. **_Recommended_ Disable anonymous access** - By default, anyone without a personal access token will have read-write
|
||||
access
|
||||
to your cached artifacts. You can disable this anonymous access in
|
||||
your Nx Cloud workspace settings.
|
||||
|
||||
[Learn more about using personal access tokens](/ci/recipes/security/personal-access-tokens)
|
||||
|
||||
## Learn more
|
||||
|
||||
- [Nx Docs](/getting-started/intro)
|
||||
- [Nx Cloud Cache Security](/ci/concepts/cache-security)
|
||||
- [Nx Cloud Personal Access Tokens](/ci/recipes/security/personal-access-tokens)
|
||||
- [Nx Cloud CI Access Tokens](/ci/recipes/security/access-tokens)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx GitHub](https://github.com/nrwl/nx)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
- [Speed up your CI](https://nx.app/)
|
||||
@@ -1,487 +0,0 @@
|
||||
---
|
||||
title: Next-Gen Module Federation Deployments with Nx and Zephyr Cloud
|
||||
slug: next-gen-module-federation-deployment
|
||||
authors: ['Colum Ferry']
|
||||
tags: [nx, module federation, rspack, zephyr cloud]
|
||||
cover_image: /blog/images/2024-09-12/next-gen-module-federation-deployments.png
|
||||
published: true
|
||||
---
|
||||
|
||||
Nx has supported Module Federation for a long time now and its popularity is seeing year-on-year increase. It has proven
|
||||
to be the defacto solution for modern Micro Frontends and Nx has embraced this and helped developers scaffold projects
|
||||
that use Module Federation; offering the most scalable and the most developer friendly experience to do so.
|
||||
However, we have always taken a step back when it came to the final piece of the puzzle: **Deployment**.
|
||||
|
||||
Micro Frontends are, by their very nature, more complex to deploy. You are no longer deploying one build artifact but
|
||||
rather, many build artifacts that could even be on different release cadences from each other. And yet, we still expect
|
||||
the final application that our users interact with to be stable.
|
||||
|
||||
There are so many approaches to deployments - think Kubernetes, Storage Buckets with DNS, EC2 instances etc - that it
|
||||
has always been difficult for us to recommend a solution. That was until [Zephyr Cloud](https://www.zephyr-cloud.io/)
|
||||
entered the game.
|
||||
|
||||
Zephyr Cloud is a "bring your own cloud" deployment platform with best-in-class support for module federation projects
|
||||
that integrates right into your application build, providing seamless deployments without having to learn any new
|
||||
commands.
|
||||
With features such as:
|
||||
|
||||
- Auto-deployment on build
|
||||
- Live Preview link generation
|
||||
- Version rollback and roll-forward
|
||||
- Micro Frontend dependency management
|
||||
- A Chrome Extension to manage environments
|
||||
- Support for a wide range of Cloud Platforms (such as [Cloudflare](https://www.cloudflare.com/en-gb/)
|
||||
and [Netlify](https://www.netlify.com/))
|
||||
- A beautiful UI to visualize your deployments
|
||||
|
||||
And so much more, Zephyr Cloud really is one of the best deployment solutions available.
|
||||
|
||||
{% callout type="note" title="Zephyr Cloud Features" %}
|
||||
You can learn more about the full feature set that Zephyr Cloud
|
||||
offers [here](https://docs.zephyr-cloud.io/#main-features).
|
||||
{% /callout %}
|
||||
|
||||
I myself, Colum Ferry, after having been allowed to experiment with it in its infancy back in February 2024 said
|
||||
|
||||
> Zephyr Cloud is the Micro Frontend orchestration tool you never knew you needed.
|
||||
> What they have built will change the deployments for the better.
|
||||
> Think of the disruption k8s caused. Zephyr Cloud will do the same for the Micro Frontend world.
|
||||
>
|
||||
> _Reference: [Linkedin](https://www.linkedin.com/posts/colum-ferry-3a36a9169_zephyr-cloud-is-the-micro-frontend-orchestration-activity-7183207192991289344-6mSR)_
|
||||
|
||||
And I stand by that statement.
|
||||
|
||||
Therefore, in this article I'll show you how to set up React Module Federation with Nx and Rspack and how to integrate
|
||||
it with Zephyr Cloud for deployment.
|
||||
|
||||
## Step 1: Set Up the Nx Workspace
|
||||
|
||||
We'll start by creating an empty Nx workspace:
|
||||
|
||||
```{% command="npx create-nx-workspace myorg" path="~" %}
|
||||
NX Let's create a new workspace [https://nx.dev/getting-started/intro]
|
||||
|
||||
✔ Which stack do you want to use? · none
|
||||
✔ Package-based monorepo, integrated monorepo, or standalone project? · integrated
|
||||
✔ Which CI provider would you like to use? · github
|
||||
|
||||
NX Creating your v19.7.0 workspace.
|
||||
|
||||
✔ Installing dependencies with npm
|
||||
✔ Successfully created the workspace: myorg.
|
||||
✔ Nx Cloud has been set up successfully
|
||||
✔ CI workflow has been generated successfully
|
||||
|
||||
```
|
||||
|
||||
Next, we'll want to navigate into our new workspace:
|
||||
|
||||
```shell
|
||||
cd myorg
|
||||
```
|
||||
|
||||
And finally, we'll add the [`@nx/react`](/nx-api/react) plugin to our workspace.
|
||||
|
||||
```shell
|
||||
npx nx add @nx/react
|
||||
```
|
||||
|
||||
## Step 2: Scaffold the Module Federation Projects
|
||||
|
||||
Now that we have the `@nx/react` package installed, we have access to all the generators it offers. We'll use the `host`
|
||||
generator now to scaffold out Module Federation projects.
|
||||
|
||||
{% callout type="note" title="Generating host applications" %}
|
||||
If you'd like a more indepth recipe for scaffolding `host` and `remote` generators you can take a look through
|
||||
our [Module Federation Recipes](/recipes/module-federation).
|
||||
{% /callout %}
|
||||
|
||||
```{% command="npx nx g @nx/react:host shell --remotes=remote1 --bundler=rspack" path="~/myorg" %}
|
||||
NX Generating @nx/react:host
|
||||
|
||||
✔ Which stylesheet format would you like to use? · css
|
||||
✔ Which E2E test runner would you like to use? · playwright
|
||||
Fetching prettier...
|
||||
Fetching @nx/rspack...
|
||||
Fetching @nx/playwright...
|
||||
Fetching @nx/jest...
|
||||
|
||||
// REMOVED FOR BREVITY
|
||||
|
||||
NX 👀 View Details of shell
|
||||
|
||||
Run "nx show project shell" to view details about this project.
|
||||
|
||||
NX 👀 View Details of remote1
|
||||
Run "nx show project remote1" to view details about this project.
|
||||
```
|
||||
|
||||
With that, two applications will be added to our workspace `shell` and `remote` as well as their counterpart e2e
|
||||
projects.
|
||||
|
||||
{% callout type="note" title="Running tasks" %}
|
||||
These projects contain all the usual tasks you would expect to see with a Nx project such as `build`, `serve`, `test`,
|
||||
`lint`.
|
||||
You can learn more about Running Tasks in Nx [here](/features/run-tasks).
|
||||
{% /callout %}
|
||||
|
||||
We specified `--bundler=rspack` indicating that the applications should be built with [Rspack](https://rspack.dev/).
|
||||
_This support has been newly added to Nx since Nx 19.7.0._
|
||||
|
||||
You'll note the `shell/rspack.config.ts` file. It's contents should match the following:
|
||||
|
||||
```ts {% fileName="shell/rspack.config.ts" %}
|
||||
import { composePlugins, withNx, withReact } from '@nx/rspack';
|
||||
import {
|
||||
withModuleFederation,
|
||||
ModuleFederationConfig,
|
||||
} from '@nx/rspack/module-federation';
|
||||
|
||||
import baseConfig from './module-federation.config';
|
||||
|
||||
const config: ModuleFederationConfig = {
|
||||
...baseConfig,
|
||||
};
|
||||
|
||||
// Nx plugins for rspack to build config object from Nx options and context.
|
||||
/**
|
||||
* DTS Plugin is disabled in Nx Workspaces as Nx already provides Typing support for Module Federation
|
||||
* The DTS Plugin can be enabled by setting dts: true
|
||||
* Learn more about the DTS Plugin here: https://module-federation.io/configure/dts.html
|
||||
*/
|
||||
export default composePlugins(
|
||||
withNx(),
|
||||
withReact(),
|
||||
withModuleFederation(config, { dts: false })
|
||||
);
|
||||
```
|
||||
|
||||
If you have experience with our `webpack` Module Federation support, you'll note that this file is very similar to the
|
||||
`webpack.config.ts` files we would have generated. The only real difference is that the imports point to `@nx/rspack`.
|
||||
|
||||
{% callout type="note" title="Module Federation 2.0" %}
|
||||
Module Federation is still under active development, however, all new development is being included in Rspack as well as
|
||||
the `@module-federation/enhanced` package.
|
||||
|
||||
Module Federation 2.0 brings new features such
|
||||
as [Federation Runtime](https://module-federation.io/guide/basic/runtime.html)
|
||||
and [Runtime Plugins](https://module-federation.io/plugin/dev/index.html).
|
||||
These are significant advancements which offer a vast range of capabilities to Module Federation projects.
|
||||
|
||||
Nx itself has employed this strategy to solve a long-standing issue with shared workspace libraries wherein there was
|
||||
the possibility that a shared library would be served from a static remote. This in turn would prevent HMR updates to
|
||||
the library from being reflected in the locally served application.
|
||||
You can learn more about the
|
||||
`NxRuntimeLibraryControlPlugin` [here](/concepts/module-federation/nx-module-federation-technical-overview).
|
||||
{% /callout %}
|
||||
|
||||
## Step 4: Building and Serving
|
||||
|
||||
To build all the applications in the workspace, run the following:
|
||||
|
||||
```{% command="npx nx run-many -t build" path="~/myorg" %}
|
||||
|
||||
✔ nx run remote1:build:production (2s)
|
||||
✔ nx run shell:build:production (526ms)
|
||||
|
||||
———————————————————————————————————————————————————————————————————————————————————————
|
||||
|
||||
NX Successfully ran target build for 2 projects (3s)
|
||||
```
|
||||
|
||||
This will build the applications with Rspack. You can observe the build artifacts in the `dist/` folder.
|
||||
|
||||
To serve the Module Federation setup, we recommend only serving the `host` application.
|
||||
|
||||
{% callout type="note" title="Serving all Module Federation Projects" %}
|
||||
|
||||
Nx purpose-built a `serve` executor for Module Federation Projects. This executor will find all the `remote`
|
||||
applications that the `host` depends on and serves them, either statically or with HMR/Live Reloading.
|
||||
|
||||
Serving statically means that we can reuse the build artifacts for the `remotes` for a faster dev-server startup time
|
||||
that is scalable. Combined with Nx caching, this works well to ensure a great developer experience.
|
||||
|
||||
You can learn more about how this works in
|
||||
our [Nx Module Federation Technical Overview](/concepts/module-federation/nx-module-federation-technical-overview#what-happens-when-you-serve-your-host)
|
||||
document.
|
||||
|
||||
{% /callout %}
|
||||
|
||||
Run the following command to serve the `host` application with the `remote` served statically:
|
||||
|
||||
```{% command="npx nx serve shell" path="~/myorg" %}
|
||||
> nx run shell:serve
|
||||
|
||||
|
||||
NX Starting module federation dev-server for shell with 1 remotes
|
||||
|
||||
|
||||
NX Building 1 static remotes...
|
||||
|
||||
|
||||
NX Built 1 static remotes
|
||||
|
||||
|
||||
NX Starting static remotes proxies...
|
||||
|
||||
|
||||
NX Static remotes proxies started successfully
|
||||
|
||||
[ Module Federation Manifest Plugin ]: Manifest will use absolute path resolution via its host at runtime, reason: publicPath='auto'
|
||||
<i> [webpack-dev-server] Project is running at:
|
||||
<i> [webpack-dev-server] Loopback: http://localhost:4200/, http://[::1]:4200/
|
||||
<i> [webpack-dev-server] 404s will fallback to '/index.html'
|
||||
● ━━━━━━━━━━━━━━━━━━━━━━━━━ (70%) sealing after module optimization [ Module Federation Manifest Plugin ] Manifest Link: {auto}/mf-manifest.json
|
||||
● ━━━━━━━━━━━━━━━━━━━━━━━━━ (98%) emitting emit Starting up http-server, serving dist
|
||||
|
||||
http-server version: 14.1.1
|
||||
|
||||
http-server settings:
|
||||
CORS: true
|
||||
Cache: -1 seconds
|
||||
Connection Timeout: 120 seconds
|
||||
Directory Listings: visible
|
||||
AutoIndex: visible
|
||||
Serve GZIP Files: false
|
||||
Serve Brotli Files: false
|
||||
Default File Extension: none
|
||||
|
||||
Available on:
|
||||
http://localhost:4202
|
||||
Hit CTRL-C to stop the server
|
||||
|
||||
|
||||
NX Server ready at http://localhost:4200
|
||||
```
|
||||
|
||||
If you navigate to `http://localhost:4200` your application will render and you'll be able to navigate between the
|
||||
`host` and the `remote`.
|
||||
|
||||
## Step 4: Deployment
|
||||
|
||||
Granted what we have currently is not something you'd likely see in a production application, we'll use it as is to
|
||||
demonstrate deployment with Zephyr Cloud.
|
||||
|
||||
{% callout type="note" title="Zephyr Cloud Nx Recipe" %}
|
||||
|
||||
Zephyr Cloud also has a recipe that you can follow to set up Nx React Module Federation with Zephyr
|
||||
Cloud [here](https://docs.zephyr-cloud.io/recipes/react-rspack-nx).
|
||||
|
||||
{% /callout %}
|
||||
|
||||
I'll break this section into sub-steps to make it easier to follow.
|
||||
|
||||
### Step 1: Add `package.json` and First Commit
|
||||
|
||||
First, we need to add `package.json` files to our `shell` and `remote1` projects. This is used by Zephyr Cloud to
|
||||
determine the name and version of the projects for deployment.
|
||||
|
||||
Create the following files:
|
||||
|
||||
{% tabs %}
|
||||
{% tab label="shell/package.json" %}
|
||||
|
||||
```json {% fileName="shell/package.json" %}
|
||||
{
|
||||
"name": "shell",
|
||||
"version": "0.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
{% /tab %}
|
||||
{% tab label="remote1/package.json" %}
|
||||
|
||||
```json {% fileName="remote1/package.json" %}
|
||||
{
|
||||
"name": "remote1",
|
||||
"version": "0.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
{% /tab %}
|
||||
{% /tabs %}
|
||||
|
||||
Once this is done, add all staged files and create a git commit.
|
||||
|
||||
```shell
|
||||
git add .
|
||||
git commit -m "initial commit"
|
||||
```
|
||||
|
||||
### Step 2: Create a GitHub Repository
|
||||
|
||||
Next, we need to add a GitHub repository. It can be public or private, it will not affect the deployments by Zephyr
|
||||
Cloud.
|
||||
|
||||
{% callout type="note" title="Why is this needed?" %}
|
||||
Behind the scene, Zephyr Cloud will map your git configuration (remote origin url, organization or username, repository
|
||||
name and branch) to deploy your application. Without this step the deployment will fail.
|
||||
{% /callout %}
|
||||
|
||||
If you don't already have the [GitHub CLI](https://cli.github.com/) installed, I would highly recommend it.
|
||||
|
||||
You can then run the following to create your GitHub Repository from your terminal:
|
||||
|
||||
```{% command="gh repo create" path="~/myorg" %}
|
||||
? What would you like to do? Push an existing local repository to GitHub
|
||||
? Path to local repository .
|
||||
? Repository name nx-zephyr-cloud-example
|
||||
? Repository owner Coly010
|
||||
? Description Example of Nx React Rspack Module Federation with Zephyr Cloud
|
||||
? Visibility Private
|
||||
✓ Created repository Coly010/nx-zephyr-cloud-example on GitHub
|
||||
https://github.com/Coly010/nx-zephyr-cloud-example
|
||||
? Add a remote? Yes
|
||||
? What should the new remote be called? origin
|
||||
✓ Added remote https://github.com/Coly010/nx-zephyr-cloud-example.git
|
||||
? Would you like to push commits from the current branch to "origin"? Yes
|
||||
```
|
||||
|
||||
### Step 3: Add Zephyr Cloud
|
||||
|
||||
To add Zephyr Cloud itself, we need to install their `zephyr-webpack-plugin`.
|
||||
|
||||
{% callout type="note" title="Rspack and Webpack Interop" %}
|
||||
The plugin is indeed written for Webpack, however, one of the big advantages of Rspack is the interoperability it offers
|
||||
for the Webpack Ecosystem.
|
||||
You can learn more about this compatability [here](https://rspack.dev/guide/compatibility/plugin).
|
||||
{% /callout %}
|
||||
|
||||
Run the following to install the plugin:
|
||||
|
||||
```shell
|
||||
npm install zephyr-webpack-plugin
|
||||
```
|
||||
|
||||
Now that the plugin has been installed in our workspace, we need to update the `rspack.config.ts` files to use it.
|
||||
This is a very simple two line change:
|
||||
|
||||
```ts
|
||||
import { withZephyr } from 'zephyr-webpack-plugin';
|
||||
|
||||
export default composePlugins(
|
||||
...,
|
||||
withZephyr()
|
||||
)
|
||||
```
|
||||
|
||||
You'll need to make these updates to the following files:
|
||||
|
||||
- `shell/rspack.config.ts`
|
||||
- `shell/rspack.config.prod.ts`
|
||||
- `remote1/rspack.config.ts`
|
||||
|
||||
For example, your `shell/rspack.config.ts` file should now match the following:
|
||||
|
||||
```ts {% fileName="shell/rspack.config.ts" %}
|
||||
import { composePlugins, withNx, withReact } from '@nx/rspack';
|
||||
import {
|
||||
withModuleFederation,
|
||||
ModuleFederationConfig,
|
||||
} from '@nx/rspack/module-federation';
|
||||
import { withZephyr } from 'zephyr-webpack-plugin';
|
||||
|
||||
import baseConfig from './module-federation.config';
|
||||
|
||||
const config: ModuleFederationConfig = {
|
||||
...baseConfig,
|
||||
};
|
||||
|
||||
// Nx plugins for rspack to build config object from Nx options and context.
|
||||
/**
|
||||
* DTS Plugin is disabled in Nx Workspaces as Nx already provides Typing support for Module Federation
|
||||
* The DTS Plugin can be enabled by setting dts: true
|
||||
* Learn more about the DTS Plugin here: https://module-federation.io/configure/dts.html
|
||||
*/
|
||||
export default composePlugins(
|
||||
withNx(),
|
||||
withReact(),
|
||||
withModuleFederation(config, { dts: false }),
|
||||
withZephyr()
|
||||
);
|
||||
```
|
||||
|
||||
### Step 4: First Deployment
|
||||
|
||||
With all the `rspack.config.ts` files updated, getting your first deployment is as simple as running:
|
||||
|
||||
```{% command="npx nx run-many -t build --verbose" path="~/myorg" %}
|
||||
> nx run remote1:build:production
|
||||
...
|
||||
|
||||
ZEPHYR Opening browser for authentication...
|
||||
ZEPHYR Hi colum_nrwl_io!
|
||||
ZEPHYR remote1.nx-zephyr-cloud-example.coly010#6
|
||||
ZEPHYR
|
||||
ZEPHYR Uploaded local snapshot in 152ms
|
||||
ZEPHYR (12/12 assets uploaded in 235ms, 332.55kb)
|
||||
ZEPHYR Deployed to Zephyr's edge in 352ms.
|
||||
ZEPHYR
|
||||
ZEPHYR https://colum_nrwl_io_6-remote1-nx-zephyr-cloud-example-c-e7ab3d770-ze.zephyrcloud.app
|
||||
|
||||
...
|
||||
Rspack 1.0.4 compiled with 1 warning in 3.91 s
|
||||
|
||||
> nx run shell:build:production
|
||||
...
|
||||
|
||||
ZEPHYR Hi colum_nrwl_io!
|
||||
ZEPHYR shell.nx-zephyr-cloud-example.coly010#7
|
||||
ZEPHYR
|
||||
ZEPHYR Uploaded local snapshot in 165ms
|
||||
ZEPHYR (10/10 assets uploaded in 202ms, 326.42kb)
|
||||
ZEPHYR Deployed to Zephyr's edge in 248ms.
|
||||
ZEPHYR
|
||||
ZEPHYR https://colum_nrwl_io_7-shell-nx-zephyr-cloud-example-col-04ccb4027-ze.zephyrcloud.app
|
||||
|
||||
...
|
||||
Rspack 1.0.4 compiled with 1 warning in 1.29 s
|
||||
```
|
||||
|
||||
At this point, a page will likely be opened in your browser where you can create your Zephyr Cloud account and
|
||||
authenticate the CLI to allow it to deploy the applications to your account.
|
||||
|
||||
You'll note that the output from this is not the same as the output we received earlier when we ran
|
||||
`npx nx run-many -t build`.
|
||||
In particular, the most recent set of logs contains the URLs of the deployed application (_Note: your URL should be
|
||||
different_):
|
||||
|
||||
```{% command="npx nx run-many -t build --verbose" path="~/myorg" %}
|
||||
> nx run remote1:build:production
|
||||
...
|
||||
ZEPHYR https://colum_nrwl_io_6-remote1-nx-zephyr-cloud-example-c-e7ab3d770-ze.zephyrcloud.app
|
||||
|
||||
|
||||
> nx run shell:build:production
|
||||
...
|
||||
ZEPHYR https://colum_nrwl_io_7-shell-nx-zephyr-cloud-example-col-04ccb4027-ze.zephyrcloud.app
|
||||
```
|
||||
|
||||
Zephyr Cloud deployed our applications _during_ the build process!
|
||||
|
||||
With Zephyr Cloud, it really is _that_ easy to deploy your Module Federation Projects.
|
||||
|
||||
You can then visit the [Zephyr Cloud Dashboard](https://app.zephyr-cloud.io/) where you can get a more visual insight
|
||||
into your deployed projects.
|
||||
|
||||
## Conclusion
|
||||
|
||||
Deploying Micro Frontend applications has always been a complex task, especially when it comes to managing multiple
|
||||
build artifacts and maintaining stability. However, with Nx's continued support for Module Federation and the
|
||||
integration of Zephyr Cloud, developers now have access to a streamlined, scalable solution that simplifies the
|
||||
deployment process significantly.
|
||||
Zephyr Cloud's unique features, such as auto-deployment, live preview links, and seamless rollback capabilities, make it
|
||||
an invaluable tool for Micro Frontend orchestration. By following the steps outlined in this guide, you can effortlessly
|
||||
set up your Nx workspace, scaffold Module Federation projects, and leverage Zephyr Cloud for quick, hassle-free
|
||||
deployments.
|
||||
|
||||
For more information about Zephyr Cloud I highly recommend checking out their [docs](https://docs.zephyr-cloud.io/).
|
||||
|
||||
## Learn More
|
||||
|
||||
- [Nx on CI](/ci)
|
||||
- [Task Distribution with Nx Agents](/ci/features/distribute-task-execution)
|
||||
- [Automated e2e Test Splitting](/ci/features/split-e2e-tasks)
|
||||
- [X/Twitter](https://twitter.com/nxdevtools) -- [LinkedIn](https://www.linkedin.com/company/nrwl/)
|
||||
- [Nx Official Discord Server](https://go.nx.dev/community)
|
||||
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
|
||||
@@ -1,68 +1,56 @@
|
||||
[
|
||||
{
|
||||
"name": "Juri Strumpflohner",
|
||||
"image": "/blog/images/Juri Strumpfloner.jpeg",
|
||||
"twitter": "juristr",
|
||||
"github": "juristr"
|
||||
},
|
||||
{
|
||||
"name": "Colum Ferry",
|
||||
"image": "/blog/images/Colum Ferry.jpeg",
|
||||
"twitter": "FerryColum",
|
||||
"github": "Coly010"
|
||||
},
|
||||
{
|
||||
"name": "Emily Xiong",
|
||||
"image": "/blog/images/Emily Xiong.jpeg",
|
||||
"twitter": "xiongemily",
|
||||
"github": "xiongemi"
|
||||
},
|
||||
{
|
||||
"name": "Isaac Mann",
|
||||
"image": "/blog/images/Isaac Mann.jpeg",
|
||||
"twitter": "mannisaac",
|
||||
"github": "isaacplmann"
|
||||
},
|
||||
{
|
||||
"name": "Katerina Skroumpelou",
|
||||
"image": "/blog/images/Katerina Skroumpelou.jpeg",
|
||||
"twitter": "psybercity",
|
||||
"github": "mandarini"
|
||||
},
|
||||
{
|
||||
"name": "Max Kless",
|
||||
"image": "/blog/images/Max Kless.jpeg",
|
||||
"twitter": "MaxKless",
|
||||
"github": "MaxKless"
|
||||
},
|
||||
{
|
||||
"name": "Victor Savkin",
|
||||
"image": "/blog/images/Victor Savkin.jpeg",
|
||||
"twitter": "victorsavkin",
|
||||
"github": "vsavkin"
|
||||
},
|
||||
{
|
||||
"name": "Zack DeRose",
|
||||
"image": "/blog/images/Zack DeRose.jpeg",
|
||||
"twitter": "zackderose",
|
||||
"github": "ZackDeRose"
|
||||
},
|
||||
{
|
||||
"name": "Jeff Cross",
|
||||
"image": "/blog/images/Jeff Cross.jpeg",
|
||||
"twitter": "jeffbcross",
|
||||
"github": "jeffbcross"
|
||||
},
|
||||
{
|
||||
"name": "Philip Fulcher",
|
||||
"image": "/blog/images/Philip Fulcher.jpeg",
|
||||
"twitter": "philipjfulcher",
|
||||
"github": "philipjfulcher"
|
||||
},
|
||||
{
|
||||
"name": "Mike Hartington",
|
||||
"image": "/blog/images/Mike Hartington.png",
|
||||
"twitter": "mhartington",
|
||||
"github": "mhartington"
|
||||
}
|
||||
{
|
||||
"name": "Juri Strumpflohner",
|
||||
"image": "/blog/images/Juri Strumpfloner.jpeg",
|
||||
"twitter": "juristr",
|
||||
"github": "juristr"
|
||||
},
|
||||
{
|
||||
"name": "Colum Ferry",
|
||||
"image": "/blog/images/Colum Ferry.jpeg",
|
||||
"twitter": "FerryColum",
|
||||
"github": "Coly010"
|
||||
},
|
||||
{
|
||||
"name": "Emily Xiong",
|
||||
"image": "/blog/images/Emily Xiong.jpeg",
|
||||
"twitter": "xiongemily",
|
||||
"github": "xiongemi"
|
||||
},
|
||||
{
|
||||
"name": "Isaac Mann",
|
||||
"image": "/blog/images/Isaac Mann.jpeg",
|
||||
"twitter": "mannisaac",
|
||||
"github": "isaacplmann"
|
||||
},
|
||||
{
|
||||
"name": "Katerina Skroumpelou",
|
||||
"image": "/blog/images/Katerina Skroumpelou.jpeg",
|
||||
"twitter": "psybercity",
|
||||
"github": "mandarini"
|
||||
},
|
||||
{
|
||||
"name": "Max Kless",
|
||||
"image": "/blog/images/Max Kless.jpeg",
|
||||
"twitter": "MaxKless",
|
||||
"github": "MaxKless"
|
||||
},
|
||||
{
|
||||
"name": "Victor Savkin",
|
||||
"image": "/blog/images/Victor Savkin.jpeg",
|
||||
"twitter": "victorsavkin",
|
||||
"github": "vsavkin"
|
||||
},
|
||||
{
|
||||
"name": "Zack DeRose",
|
||||
"image": "/blog/images/Zack DeRose.jpeg",
|
||||
"twitter": "zackderose",
|
||||
"github": "ZackDeRose"
|
||||
},
|
||||
{
|
||||
"name": "Jeff Cross",
|
||||
"image": "/blog/images/Jeff Cross.jpeg",
|
||||
"twitter": "jeffbcross",
|
||||
"github": "jeffbcross"
|
||||
}
|
||||
]
|
||||
|
||||
|
After Width: | Height: | Size: 35 MiB |
|
After Width: | Height: | Size: 17 MiB |
|
Before Width: | Height: | Size: 159 KiB |
|
Before Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 165 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 244 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 427 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 754 KiB |
|
Before Width: | Height: | Size: 921 KiB |
|
Before Width: | Height: | Size: 519 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 980 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 478 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 709 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 774 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 212 KiB |
@@ -1,12 +1,12 @@
|
||||
[
|
||||
"cypress",
|
||||
"express",
|
||||
"jest",
|
||||
"linter",
|
||||
"nest",
|
||||
"node",
|
||||
"storybook",
|
||||
"web",
|
||||
"workspace",
|
||||
"js"
|
||||
"cypress",
|
||||
"express",
|
||||
"jest",
|
||||
"linter",
|
||||
"nest",
|
||||
"node",
|
||||
"storybook",
|
||||
"web",
|
||||
"workspace",
|
||||
"js"
|
||||
]
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
We were so excited about the features in Nx 18 that we created a whole [Launch Nx Week](/launch-nx) to share our excitement with you. During the launch week, we made the following announcements:
|
||||
|
||||
- [Project Crystal](/blog/what-if-nx-plugins-were-more-like-vscode-extensions) allows you to use inferred tasks
|
||||
- A new [`@nx/nuxt`](/blog/introducing-nx-nuxt-enhanced-nuxt-js-support-in-nx) plugin is available
|
||||
- [Nx Agents](/blog/fast-effortless-ci) are publicly available
|
||||
- [`nx release`](/blog/versioning-and-releasing-packages-in-a-monorepo) is out of beta
|
||||
- [Project Crystal](/blog/what-if-nx-plugins-were-more-like-vscode-extensions) allows you to use inferred tasks
|
||||
- A new [`@nx/nuxt`](/blog/introducing-nx-nuxt-enhanced-nuxt-js-support-in-nx) plugin is available
|
||||
- [Nx Agents](/blog/fast-effortless-ci) are publicly available
|
||||
- [`nx release`](/blog/versioning-and-releasing-packages-in-a-monorepo) is out of beta
|
||||
|
||||
{% youtube
|
||||
src="https://youtu.be/Ed1ZCNqWF1Q"
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
# Nx 19.5 Adds StackBlitz, New Features, And More!!
|
||||
|
||||
[](/blog/nx-19-5-adds-stackblitz-new-features-and-more)
|
||||
|
||||
Read the [blogpost](/blog/nx-19-5-adds-stackblitz-new-features-and-more) for full details.
|
||||
|
||||
## Features
|
||||
|
||||
{% cards cols="2" %}
|
||||
{% card title="Announcing Nx Cloud Hobby Tier" type="document" url="/blog/nx-19-5-adds-stackblitz-new-features-and-more#announcing-nx-cloud-hobby-tier" /%}
|
||||
{% card title="StackBlitz Support" type="document" url="/blog/nx-19-5-adds-stackblitz-new-features-and-more#stackblitz-support" /%}
|
||||
{% card title="Bun and Pnpm v9 Support" type="document" url="/blog/nx-19-5-adds-stackblitz-new-features-and-more#bun-and-pnpm-v9-support" /%}
|
||||
{% card title="Local Flaky Task Detection" type="document" url="/blog/nx-19-5-adds-stackblitz-new-features-and-more#local-flaky-task-detection" /%}
|
||||
{% card title="Project Detail View Enhancements" type="document" url="/blog/nx-19-5-adds-stackblitz-new-features-and-more#project-detail-view-enhancements" /%}
|
||||
{% card title="Pattern Support for `targetDefaults`" type="document" url="/blog/nx-19-5-adds-stackblitz-new-features-and-more#pattern-support-for-targetdefaults" /%}
|
||||
{% card title="Individual Targets Can Now Opt Out of Parallelism" type="document" url="/blog/nx-19-5-adds-stackblitz-new-features-and-more#individual-targets-can-now-opt-out-of-parallelism" /%}
|
||||
{% card title="Support For Incremental Builds For Vite" type="document" url="/blog/nx-19-5-adds-stackblitz-new-features-and-more#support-for-incremental-builds-for-vite" /%}
|
||||
{% card title="Project Crystal Conversion Generators" type="document" url="/blog/nx-19-5-adds-stackblitz-new-features-and-more#project-crystal-conversion-generators" /%}
|
||||
{% card title="Gradle Composite Builds Support" type="document" url="/blog/nx-19-5-adds-stackblitz-new-features-and-more#gradle-composite-builds-support" /%}
|
||||
{% card title="Experimental: Gradle Test Atomization" type="document" url="/blog/nx-19-5-adds-stackblitz-new-features-and-more#experimental-gradle-test-atomization" /%}
|
||||
{% card title="Experimental: Nx Release Adds Version Plans Support" type="document" url="/blog/nx-19-5-adds-stackblitz-new-features-and-more#experimental-nx-release-adds-version-plans-support" /%}
|
||||
{% card title="Support for React 19 (rc) and Angular 18.1" type="document" url="/blog/nx-19-5-adds-stackblitz-new-features-and-more#support-for-react-19-rc-and-angular-181" /%}
|
||||
|
||||
{% /cards %}
|
||||
@@ -1,15 +0,0 @@
|
||||
# Nx 19.6
|
||||
|
||||
## Features
|
||||
|
||||
{% cards cols="2" %}
|
||||
{% card title="Explain with AI" type="document" url="/ci/features/explain-with-ai" /%}
|
||||
{% card title="File-Based Versioning for Nx Release (Version Plans)" type="document" url="/recipes/nx-release/file-based-versioning-version-plans" /%}
|
||||
{% card title="Migrate to Inferred Tasks (Project Crystal)" type="document" url="/recipes/running-tasks/convert-to-inferred" /%}
|
||||
{% card title="Angular 18.2.0 Support" type="document" url="https://github.com/nrwl/nx/pull/27379" /%}
|
||||
{% card title="Storybook 8 Support" type="document" url="https://github.com/nrwl/nx/pull/27214" /%}
|
||||
{% /cards %}
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
We updated `webpack-dev-server` to v5 in `@nx/webpack`, which comes with some breaking changes. See their [migration guide](https://github.com/webpack/webpack-dev-server/blob/master/migration-v5.md) for more details.
|
||||