Skip to content

tinesoft/nx-multi-stacks-monorepo

Repository files navigation

Nx Multi Stacks Monorepo

✨ This workspace has been generated by Nx, a Smart, fast and extensible build system. ✨ for the Sfeir School Nx

How to recreate this exact workspace?

General Instructions

  1. Create the workspace: npx --yes [email protected] nx-multi-stacks-monorepo --preset=apps --workspaceType=integrated --nxCloud=false

  2. Move into the created repo: cd nx-multi-stacks-monorepo and open it inside you IDE of choice

  3. Add @nx/[email protected] @nx/[email protected] @nxrocks/nx-spring-boot@latest plugins as a dev dependencies: npm install -D @nx/[email protected] @nx/[email protected] @nxrocks/nx-spring-boot@latest

    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore: add angular, react and spring-boot plugins'

Angular Stack Instructions

  1. Generate the angular application: npx nx generate @nx/angular:application --name=ngapp --directory=frontend/apps/ngapp --routing=true --standalone=true --projectNameAndRootFormat=as-provided --style=scss --prefix=ngapp --port=1200 --backendProject=api --tags="type:app, type:angular, type:frontend" --no-interactive

    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore(ngapp): generate a basic angular application'
  2. Generate the angular library: npx nx g @nx/angular:library --name=nglib --buildable=true --directory=frontend/libs/nglib --changeDetection=OnPush --prefix=nglib --projectNameAndRootFormat=as-provided --style=scss --tags="type:lib, type:angular, type:frontend" --skipModule=true --no-interactive

    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore(nglib): generate a basic angular library'
  3. Generate a Welcome Component inside the nglib above: npx nx g @nx/angular:component --name=welcome --directory=frontend/libs/nglib/src/components --export=true --standalone=true --changeDetection=OnPush --nameAndDirectoryFormat=as-provided --prefix=nglib

    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore(nglib): generate a basic `Welcome` component inside `nglib`'
  4. Update the generated Welcome component above and use it in ngapp as such:

    • frontend/libs/nglib/src/components/welcome.component.html :
    -<p>welcome works!</p>
    +<div class="welcome">
    +    <p>Welcome again, from <strong>nglib!</strong></p>
    +    <p>Today is: <strong>{{ today | date}}</strong></p>
    +</div>
    • frontend/libs/nglib/src/components/welcome.component.scss :
    +.welcome {
    +    border-radius: 4px;
    +    border: 2px solid red;
    +    padding: 1rem;
    +    margin-top: 0.5rem;
    +    margin-bottom: 0.5rem;
    +}
    • frontend/libs/nglib/src/components/welcome.component.ts :
    -export class WelcomeComponent {}
    +export class WelcomeComponent {
    +  today = new Date();
    +}
    • frontend/apps/ngapp/src/app/nx-welcome.component.ts :
    import { Component, ViewEncapsulation } from '@angular/core';
    import { CommonModule } from '@angular/common';
    +import { WelcomeComponent } from '@nx-multi-stacks-monorepo/nglib';
    
    @Component({
    selector: 'ngapp-nx-welcome',
    standalone: true,
    -  imports: [CommonModule],
    +  imports: [CommonModule, WelcomeComponent],
    template: `
        <!--
          * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    import { CommonModule } from '@angular/common';
                <span> Hello there, </span>
                Welcome ngapp πŸ‘‹
            </h1>
    +       <nglib-welcome></nglib-welcome>
            </div>
            <!--  HERO  -->
            <div id="hero" class="rounded">
    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore(ngapp): update `Welcome` component from `nglib` and use it in `ngapp`'

React Stack Instructions

  1. Generate the react application: npx nx g @nx/react:application --name=reactapp --directory=frontend/apps/reactapp --projectNameAndRootFormat=as-provided --routing=true --style=scss --tags="type:app, type:react, type:frontend" --no-interactive

    • Open frontend/apps/reactapp/project.json and change default port use to serve the app to 2200 (to avoid conflict with other apps):
    "serve": {
        "executor": "@nx/webpack:dev-server",
        "defaultConfiguration": "development",
        "options": {
            "buildTarget": "reactapp:build",
    -        "hmr": true
    +        "hmr": true,
    +        "port": 2200
        },
    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore(reactapp): generate a basic react application'
  2. Generate the react library: npx nx generate @nx/react:library --name=reactlib --unitTestRunner=jest --directory=frontend/libs/reactlib --component=false --projectNameAndRootFormat=as-provided --style=scss --tags="type:lib, type:react, type:frontend" --no-interactive

    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore(reactlib): generate a basic react library'
  3. Generate a Welcome Component inside the reactlib above: npx nx g @nx/react:component --name=welcome --directory=frontend/libs/reactlib/src/components --export=true --standalone=true --changeDetection=OnPush --nameAndDirectoryFormat=as-provided --prefix=reactlib

    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore(reactlib): generate a basic `Welcome` component inside `reactlib`'
  4. Update the generated Welcome component above and use it in reactapp as such:

    • frontend/libs/reactlib/src/components/welcome.tsx :
    export interface WelcomeProps {}
    
    export function Welcome(props: WelcomeProps) {
    +  const today = new Date().toDateString();
    return (
    -    <div className={styles['container']}>
    -      <h1>Welcome to Welcome!</h1>
    +    <div className={styles['welcome']}>
    +      <h1>Welcome again, from <strong>reactlib!</strong></h1>
    +      <p>Today is: <strong>{today}</strong></p>
        </div>
    );
    }
    • frontend/libs/reactlib/src/components/welcome.module.scss :
    -/*
    - * Replace this with your own classes
    - *
    - * e.g.
    - * .container {
    - * }
    -*/
    +.welcome {
    +    border-radius: 4px;
    +    border: 2px solid red;
    +    padding: 1rem;
    +    margin-top: 0.5rem;
    +    margin-bottom: 0.5rem;
    +}
    • frontend/apps/reactapp/src/app/nx-welcome.tsx :
    -/*
    - * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    - This is a starter component and can be deleted.
    - * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    - Delete this file and get started with your project!
    - * * * * * * * * * * * * * * * * * * * * * * * * * * * *
    - */
    +import { Welcome } from "@nx-multi-stacks-monorepo/reactlib";
    +
    export function NxWelcome({ title }: { title: string }) {
    return (
        <>
    export function NxWelcome({ title }: { title: string }) {
                Welcome {title} πŸ‘‹
                </h1>
            </div>
    -
    +       <Welcome/>
            <div id="hero" className="rounded">
                <div className="text-container">
                <h2>
    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore(reactapp): update `Welcome` component from `reaclib` and use it in `reactapp`'

Common JS/TS Stack Instructions

  1. Generate the common js/ts library: npx nx generate @nx/js:library --name=commonlib --unitTestRunner=jest --directory=frontend/libs/commonlib --projectNameAndRootFormat=as-provided --tags="type:lib, type:js, type:frontend" --no-interactive

    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore(commonlib): generate a basic JS/TS library'
  2. Update the generated commonlib file above (by adding a getTodayDate() util) and use it in nglib and reactlib as such:

    • frontend/libs/commonlib/src/lib/commonlib.ts :
    export function commonlib(): string {
    return 'commonlib';
    }
    +
    +export function getTodayDate(){
    +  return new Date();
    +}
    • frontend/libs/nglib/src/components/welcome.component.ts :
    import { ChangeDetectionStrategy, Component } from '@angular/core';
    import { CommonModule } from '@angular/common';
    +import { getTodayDate } from '@nx-multi-stacks-monorepo/commonlib';
    
    @Component({
    selector: 'nglib-welcome',
    import { CommonModule } from '@angular/common';
    changeDetection: ChangeDetectionStrategy.OnPush,
    })
    export class WelcomeComponent {
    -  today = new Date();
    +  today = getTodayDate();
    }
    • frontend/libs/reactlib/src/components/welcome.tsx:
    +import { getTodayDate } from '@nx-multi-stacks-monorepo/commonlib';
    import styles from './welcome.module.scss';
    
    /* eslint-disable-next-line */
    export interface WelcomeProps {}
    
    export function Welcome(props: WelcomeProps) {
    -  const today = new Date().toDateString();
    +  const today = getTodayDate().toDateString();
    return (
        <div className={styles['welcome']}>
        <h1>Welcome again, from <strong>reactlib!</strong></h1>
    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore(frontend): update `nglib` and `reactlib` to use utils from `commonlib`'

Spring Boot Stack Instructions

  1. Generate the Spring Boot application inside a parent module boot-parent: npx nx g @nxrocks/nx-spring-boot:project --name=bootapp --dependencies="web,jpa,h2,actuator,devtools" --artifactId=bootapp --directory=backend/bootapp --packageName=com.example.bootapp --keepProjectLevelWrapper=false --parentModuleName=boot-parent --transformIntoMultiModule=true --tags="type:api, type:java, type:backend" --projectNameAndRootFormat=as-provided --no-interactive

    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore(bootapp): generate a spring boot application inside a parent module'
  2. Create a WelcomeController.java file in backend/boot-parent/bootapp/src/main/java/com/example/bootapp/controller/ with content:

    package com.example.bootapp.controller;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController("/api")
    public class WelcomeController {
    
        private static final String WELCOME_TEMPLATE = "Welcome, %s, from '%s'!";
        public static record WelcomeMessage(String user, String message) { }
    
        @GetMapping("/welcome")
        public WelcomeMessage welcome(@RequestParam(value = "user", defaultValue = "Sfeir School Nx Attendee") String user) {
            return new WelcomeMessage(user, String.format(WELCOME_TEMPLATE, user, "bootapp"));
        }
    }
    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore(bootapp): add a `Welcome` REST controller inside `bootapp`'
  3. Generate the Spring Boot library inside the boot-parent module: npx nx generate @nxrocks/nx-spring-boot:project --name=bootlib --projectType=library --artifactId=bootlib --directory=backend/bootlib --packageName=com.example.bootlib --addToExistingParentModule=true --keepProjectLevelWrapper=false --parentModuleName=boot-parent --tags="type:api, type:java, type:backend" --projectNameAndRootFormat=as-provided --no-interactive

    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore(bootlib): generate a spring boot library inside a parent module'
  4. Update the generated bootapp application to use the bootlib :

    • Open backend/boot-parent/bootapp/pom.xml and update it as such (to use the bootlib library from above):
    	</dependency>
    +	<dependency>
    +		<groupId>com.example</groupId>
    +		<artifactId>bootlib</artifactId>
    +		<version>${project.version}</version>
    +	</dependency>
    +</dependencies>
    • Open backend/boot-parent/bootapp/src/main/java/com/example/bootapp/controller/WelcomeController.java and update it as such (to use the MyService from the bootlib) :
    package com.example.bootapp.controller;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    +import com.example.bootlib.service.MyService;
    
    @RestController("/api")
    public class WelcomeController {
    
        private static final String WELCOME_TEMPLATE = "Welcome, %s, from '%s'!";
        public static record WelcomeMessage(String user, String message) { }
    
    +   private final MyService myService;
    
    +   public WelcomeController(MyService myService) {
    +       this.myService = myService;
    +   }
    
        @GetMapping("/welcome")
        public WelcomeMessage welcome(@RequestParam(value = "user", defaultValue = "Sfeir School Nx Attendee") String user) {
    -        return new WelcomeMessage(user, String.format(WELCOME_TEMPLATE, user, "bootapp"));
    +        return new WelcomeMessage(user, String.format(WELCOME_TEMPLATE, user, this.myService.message()));
        }
    }
    • Open backend/boot-parent/bootapp/src/main/resources/application.properties and update it as such (to define the property from the bootlib library from above):
    +bootlib.service.message = bootlib
    • Open backend/boot-parent/bootapp/src/main/java/com/example/bootapp/BootappApplication.java and update it as such (to include beans from com.example package, common to both bootapp and bootlib):
    -@SpringBootApplication
    +@SpringBootApplication(scanBasePackages = "com.example")
    public class BootappApplication {
    πŸ’Ύ Save the current state!
    $ git add --all
    $ git commit -m 'chore(bootapp): update the `bootapp` to use the `bootlib`'

Link Angular and Spring Boot Stacks

  1. Add an implicit link between the backend Spring Boot application (bootapp) and the frontend Angular application (ngapp) that uses its API: npx nx g @nxrocks/nx-spring-boot:link --sourceProjectName=bootapp --targetProjectName=ngapp --no-interactive

Visualize the workspace

Run nx graph to visualize this workspace

Generate code

If you happen to use Nx plugins, you can leverage code generators that might come with it.

Run nx list to get a list of available plugins and whether they have generators. Then run nx list <plugin-name> to see what generators are available.

Learn more about Nx generators on the docs.

Running tasks

To execute tasks with Nx use the following syntax:

nx <target> <project> <...options>

You can also run multiple targets:

nx run-many -t <target1> <target2>

..or add -p to filter specific projects

nx run-many -t <target1> <target2> -p <proj1> <proj2>

Targets can be defined in the package.json or projects.json. Learn more in the docs.

Want better Editor Integration?

Have a look at the Nx Console extensions. It provides autocomplete support, a UI for exploring and running tasks & generators, and more! Available for VSCode, IntelliJ and comes with a LSP for Vim users.

Ready to deploy?

Just run nx build demoapp to build the application. The build artifacts will be stored in the dist/ directory, ready to be deployed.

Set up CI!

Nx comes with local caching already built-in (check your nx.json). On CI you might want to go a step further.

Connect with us!

Releases

No releases published

Packages

No packages published