Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Managing Your Node.js Monorepos With NX

Tamar Twena-Stern
October 24, 2023
27

Managing Your Node.js Monorepos With NX

Tamar Twena-Stern

October 24, 2023
Tweet

Transcript

  1. Should I Write My Code In The Same Git Repository

    ? Or Should I Write Every Service In It’s Own Repository ?
  2. Monorepo - All micro service in one git repository Multi-repo

    - Every micro service in a separate git repo
  3. In Multi-repos - All Those Are Easy Maintain version for

    each component Each service to have it’s own deployment cycle and releases Define access control to different components
  4. Advantages Of Mono-repos Easier for new developers to get familiar

    with the code and setup environment Less copy-paste, more code reuse between components Easier to refactor code across services / components Separate development teams to share the same culture - libraries, programming methodologies, development tools
  5. Disadvantages Of Mono-repos Maintain feature branches for a long period,

    conflict resolving becomes very complicated Version control slow down - Pulling, cloning, checking out becomes long, it slows down the team’s work Managing access control - Impossible to block read access to all the code
  6. Long, Complicated build process and CI/CD No ability to test

    separately only specific service Inability to version and deploy specific service One Build For All Services
  7. NX In A Nutshell A tool to manage all your

    code components in one repo Gives the ability to build, deploy and test each component separately
  8. Project Structure Under Packages - All the packages in the

    repo will be located. Each package will have each own package.json and it’s own node_modules folder A global package.json to control the main build Typescript is not installed - if you use it , you need to install it globally/ per package
  9. Index.ts const getRandomInt = (max) : number => { return

    Math.floor(Math.random() * max); } export default getRandomInt;
  10. Print Number - Index.ts import getRandomInt from 'rand-number'; const printRandomInt

    = (max) : void => { console.log('Printing number' + getRandomInt(max)) } export default printRandomInt;
  11. Print Number - Package.json { "name": "print-number", "version": "0.0.0", "main":

    "dist/index.js", "devDependencies": {}, "scripts": { "build": "tsc index.ts --outDir dist", "test": "jest --coverage", "lint": "eslint src --ext .ts" }, "dependencies": { "rand-number": "*" } }
  12. NX Tasks - All Scripts Defined In Package.json "scripts": {

    "build": "tsc index.ts --outDir dist", "test": "jest --coverage", "lint": "eslint src --ext .ts" } A project can have thousands of tasks !
  13. NX Tasks • Each script in package json defined as

    a task • Possibility to run single task, multiple tasks or all of them • If a specific task is running - nx will run all the task dependencies • Possibility to control the order of tasks
  14. Setup The Cache- nx.json { "extends": "nx/presets/npm.json", "$schema": "./node_modules/nx/schemas/nx-schema.json", "tasksRunnerOptions":

    { "default": { "runner": "@nrwl/nx-cloud", "options": { "cacheableOperations": [ "build", "lint", "test", "E2e" ], "accessToken": "<GENERATED_TOKEN>" } } } }
  15. Setup The Cache- nx.json { "extends": "nx/presets/npm.json", "$schema": "./node_modules/nx/schemas/nx-schema.json", "tasksRunnerOptions":

    { "default": { "runner": "@nrwl/nx-cloud", "options": { "cacheableOperations": [ "build", "lint", "test", "E2e" ], "accessToken": "<GENERATED_TOKEN>" } } } }
  16. What The Cache Is Storing ? • Build Operations -

    Output of typescript compiler / babel • Test - test results of Jest/Mocha • Lint - ESlint results
  17. The Elements Used To Build The Graph import getRandomInt from

    'rand-number'; "dependencies": { "rand-number": "*" } Typescript Imports: Package.json dependencies
  18. What You Can Do With The Project Graph ? See

    How Projects Are dependent Technical Description Of Each Module
  19. General Information - Node.js NX Project • A skeleton project

    is generated with native support of Typescript and Jest. • A single API file is generated under the root directory containing express endpoints • Utilities can be generated as a NX modules inside the project.
  20. Main Server File Under src/ Folder - Node.js Project import

    express from 'express'; import { doAuth } from '@products-api/auth'; const host = process.env.HOST ?? 'localhost'; const port = process.env.PORT ? Number(process.env.PORT) : 3000; const app = express(); app.get('/', (req, res) => { res.send({ message: 'Hello API' }); }); app.post('/auth', (req, res) => { res.send(doAuth()); }); app.listen(port, host, () => { console.log(`[ ready ] http://${host}:${port}`); });
  21. Which NX Project Type Fit To Which Component In Our

    Architecture ? Packaged Based NX Project
  22. Which NX Project Type Fit To Which Component In Our

    Architecture ? Node Standalone NX Project
  23. Testing Each Component Separately • A CI / CD which

    contains all the tests of all the micro services of the component can be very complex. • By adding a test script for each microservice package.json we can build a CI/CD that will enable you to test each component by itself.
  24. NX Cache - Solving Long Builds Problem NX cache optimizes

    the build process saves a lot of time - especially when you have hundreds of different services and libraries Critical aspect that will make you consider add it to you projects
  25. Why ‘Packaged Based’ Is The Best Project Type To Integrate

    Existing Code With ? • You generally leave the module/express/nest code’s existing build/test/lint tooling untouched. • In other NX project types - you need to change your build/test/lint tools to fit to NX built in tools
  26. Steps To Integrate Existing Code With Packaged Based NX Project

    • Move an existing express/nest/utility into a package-based including package.json • NX will detect the your code as a package, cache the relevant scripts and build the package dependency graph.