Skip to content

Nx project setup guide

Matěj Chalk edited this page Aug 31, 2022 · 21 revisions

Prerequisites

  • Node.js (LTS version)

Creating a new Nx workspace with Angular application

  1. Run npx create-nx-workspace@latest and fill in the prompts:
    • enter a workspace name (typically same as repository and references organization and/or product)
    • select a workspace with a single Angular app
    • select a name for your application (more specific than workspace name, e.g. client or website)
    • select scss stylesheet format
  2. Once dependencies have been installed and workspace has been created, navigate to workspace directory (or open it in your IDE). Try running Angular app with ng serve or ng serve <app-name> and visit http://localhost:4200/ in your browser.
  3. Optionally, you may also verify production build by running ng build or ng build <app-name> and then previewing resulting static assets via npx lite-server --baseDir=dist/apps/<app-name>.

Customizing workspace configuration

Customize TypeScript compiler defaults

To ensure strict type-checking across your entire workspace, add the following flags to the root tsconfig.base.json:

{
  // ...
  "compilerOptions": {
    // ...
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noPropertyAccessFromIndexSignature": true,
  },
}

Customize Nx workspace settings (optional)

  1. Change npmScope in nx.json with your workspace-wide prefix (Nx uses it for TypeScript path aliases in new libraries).
  2. Nx assumes a name for your default branch. If you wish to use another default branch name, then modify affected.defaultBase in nx.json accordingly (so that nx affected commands work properly).

Customize Prettier formatting

  1. Replace contents of .prettierrc with company-standard .prettierrc.
  2. Install Prettier plugins with npm i -D @trivago/prettier-plugin-sort-imports.
  3. In .prettierrc, replace @fu-prefix with npmScope from nx.json.
  4. Apply new formatting rules to workspace files using npx nx format --all.

Tip: If you like, you can configure your IDE to automatically format saved files with Prettier (see instructions for VS Code, WebStorm etc.).

Customize ESLint configuration

  1. Replace contents of .eslintrc.json with company-standard .eslintrc.json.

  2. Remove overrides section from apps/<project>/.eslintrc.json, and add **/*.spec.ts, src/test-setup.ts (and **/*.stories.ts if using Storybook) to ignorePatterns. It's contents should then look something like:

    {
      "extends": ["../../.eslintrc.json"],
      "ignorePatterns": [
        "!**/*",
        "**/*.spec.ts",
        "**/*.stories.ts",
        "src/test-setup.ts"
      ]
    }
  3. In root .eslintrc.json, replace "fu" in prefix rules with your project's prefix (typically 2-3 lowercase characters).

  4. If you're not using NgRx in your project, remove rules prefixed by ngrx/ and remove "ngrx" from plugins in root .eslintrc.json.

  5. Install additional ESLint plugins with npm i -D eslint-plugin-{functional,rxjs,import,ngrx,max-params-no-constructor} eslint-import-resolver-typescript (skip eslint-plugin-ngrx if not applicable - see previous point).

  6. Running npx nx affected:lint should now result in new lint errors based on the new rules. Fix these issues to make linter succeed.

    Expand to see tips on fixing lint errors (for Nx 14)
    • Rename AppComponent's selector in apps/<app>/src/app/app.component.ts and apps/<app>/src/index.html to match your chosen prefix.
    • Add changeDetection: ChangeDetectionStrategy.OnPush to AppComponent's decorator metadata in apps/<app>/src/app/app.component.ts.
    • Add // eslint-disable-next-line import/no-unassigned-import comment before import 'zone.js'; in apps/<app>/src/polyfills.ts.
    • Fix @typescript-eslint/no-confusing-void-expression error in .catch-method in apps/<app>/src/main.ts by putting function body in curly braces (err => { console.error(err); }).
    • In apps/<app>-e2e/src/support/commands.ts, disable @typescript-eslint/consistent-type-definitions rule via comment for line with Chainable interface declaration, convert method signatures to function properties, and replace console.log with console.info.
    • In apps/<app>-e2e/src/support/e2e.ts, disable import/no-unassigned-import via comment for line with import './commands';.
    • In apps/<app>-e2e/.eslintrc.json, add new item in overrides array item for *.ts files - "rules": { "@typescript-eslint/explicit-function-return-type": "off", "import/no-default-export": "off", "import/no-extraneous-dependencies": "off" }.
    Expand to see tips on fixing lint errors (for Nx 13)
    • Rename AppComponent's selector in apps/<app>/src/app/app.component.ts and apps/<app>/src/index.html to match your chosen prefix.
    • Add changeDetection: ChangeDetectionStrategy.OnPush to AppComponent's decorator metadata in apps/<app>/src/app/app.component.ts.
    • In apps/<app>-e2e/src/support/commands.ts, disable @typescript-eslint/consistent-type-definitions rule via comment for line with Chainable interface declaration, convert method signatures to function properties, and replace console.log with console.info.
    • In apps/<app>-e2e/.eslintrc.json, add new item to overrides array - { "files": ["*.po.ts"], "rules": { "@typescript-eslint/explicit-function-return-type": "off" } },.
    Expand to see tips on fixing lint errors (for Nx 12)
    • Rename AppComponent's selector in apps/<app>/src/app/app.component.ts and apps/<app>/src/index.html to match your chosen prefix.
    • Add changeDetection: ChangeDetectionStrategy.OnPush to AppComponent's decorator metadata in apps/<app>/src/app/app.component.ts.
    • In apps/<app>-e2e/src/support/commands.ts, remove Cypress namespace declaration and replace console.log with console.info.

Tip: If you intend to organize your workspace using Nx libraries (e.g. to reuse code across multiple apps, publish them to NPM/GPR, or just encourage a more modular architecture), consider using tags (defined in nx.json) as the base for dependency graph constraints (defined in root .eslintrc.json) - see Nx docs for more info.

Customize Angular schematics

To automatically set OnPush change detection strategy when generating new Angular components (and optionally prevent automatically creating *.component.spec.ts file), extend the @nrwl/angular:component schematic in angular.json:

{
  // ...
  "schematics": {
    // ...
    "@nrwl/angular:component": {
      "style": "scss",
      "changeDetection": "OnPush",
      "skipTests": true
    }
  }
}

Add Git hooks with Husky

If you wish to automatically trigger actions (e.g. format, lint, test) based on locally executed Git commands (e.g. commit, push), integrating Husky allows you to share that configuration with the rest of your team.

  1. Install Husky with:
    npm i -D husky
  2. Set up prepare NPM script to ensure Husky gets installed:
    npm set-script prepare "husky install" # if your NPM version is older than 7, replace npm with npx npm@7
    npm run prepare
  3. Add a husky Git hook:
    • E.g. to format files on each commit:
      npx husky add .husky/pre-commit 'FILES=$(git diff --name-only --cached --diff-filter=d)'
      npx husky add .husky/pre-commit 'npx prettier --write --ignore-unknown $FILES'
      npx husky add .husky/pre-commit 'git add $FILES'
Expand to see modified instructions if Nx workspace is a sub-directory within Git repo

Let's say your Git repository places your Nx workspace inside a Frontend directory...

  1. Set up prepare NPM script to ensure Husky gets installed:
    npm set-script prepare "cd .. && husky install Frontend/.husky" # if your NPM version is older than 7, replace npm with npx npm@7
    npm run prepare
  2. Add a husky Git hook:
    • E.g. to format files on each commit:
      npx husky add .husky/pre-commit "cd Frontend"
      npx husky add .husky/pre-commit "CHANGED_FILES=$(git diff --name-only --cached --diff-filter=d --relative)"
      npx husky add .husky/pre-commit "FORMATTED_FILES=$(npx prettier --write --ignore-unknown --no-error-on-unmatched-pattern --list-different $CHANGED_FILES)"
      npx husky add .husky/pre-commit "echo Formatted files: $FORMATTED_FILES"
      npx husky add .husky/pre-commit "git add $FORMATTED_FILES"
Clone this wiki locally