Enterprise Angular

Monorepos and Tooling


The Goal

We will discuss how available tooling such as Nx can greatly accelerate our ability to generate applications.

We will also talk about how we can decouple our applications while operating in the same code base using monorepos.

A few variations for how to structure your files will be explored with the pros and cons of each being pointed out.

As a bonus, we will see how you can create a few custom, lightweight tools to 10x your ability to create applications.

Our goal is to use Nx to scaffolds out a project based on our domain model.

The Commands

Data

Create the feature libraries for remote services.

npx nx g @nx/angular:library challenges-data --directory=libs/challenges-data --standalone=false --projectNameAndRootFormat=as-provided && \
npx nx g @nx/angular:library flashcards-data --directory=libs/flashcards-data --standalone=false --projectNameAndRootFormat=as-provided && \
npx nx g @nx/angular:library notes-data --directory=libs/notes-data --standalone=false --projectNameAndRootFormat=as-provided

Create the service for each feature.

npx nx g @nx/angular:service services/challenges --project=challenges-data && \
npx nx g @nx/angular:service services/flashcards --project=flashcards-data && \
npx nx g @nx/angular:service services/notes --project=notes-data

Components

Generate the master-detail view components for the challenges feature.

npx nx g @schematics/angular:component challenges --project=challenges --style=scss && \
npx nx g @schematics/angular:component challenges/challenges-list --project=challenges --style=scss && \
npx nx g @schematics/angular:component challenges/challenge-details --project=challenges --style=scss

Generate the master-detail view components for the flashcards feature.

npx nx g @schematics/angular:component flashcards --project=flashcards --style=scss && \
npx nx g @schematics/angular:component flashcards/flashcards-list --project=flashcards --style=scss && \
npx nx g @schematics/angular:component flashcards/flashcard-details --project=flashcards --style=scss

Generate the master-detail view components for the notes feature.

npx nx g @schematics/angular:component notes --project=notes --style=scss && \
npx nx g @schematics/angular:component notes/notes-list --project=notes --style=scss && \
npx nx g @schematics/angular:component notes/note-details --project=notes --style=scss

Vertical Development

Generate the master-detail view components for the users feature.

npx nx g @nx/angular:library users-data 
  --directory=libs/users-data \
  --standalone=false \
  --projectNameAndRootFormat=as-provided && \

npx nx g @nx/angular:service services/users --project=users-data && \

npx nx g @schematics/angular:component users --project=users --style=scss && \
npx nx g @schematics/angular:component users/users-list --project=users --style=scss && \
npx nx g @schematics/angular:component users/user-details --project=users --style=scss

Challenges

Create an app called workshop in a school directory.

Generate a state lib for the workshops feature.

npx nx g @nx/angular:host workshop \
  --directory=school/workshop \
  --style=scss \
  --e2eTestRunner=cypress \
  --addTailwind=true \
  --prefix=proto \
  --ssr=false -d

Fedarated Modules Example


npx create-nx-workspace@18.0.8 workshop \
  --appName=portal \
  --preset=angular-monorepo \
  --workspaceType=integrated \
  --bundler=esbuild \
  --e2eTestRunner=cypress \
  --style=scss \
  --ci=skip \
  --ssr=false

Create a host app called dashboard with a remote app called challenges.

npx nx g @nx/angular:host dashboard \
  --style=scss \
  --e2eTestRunner=cypress \
  --projectNameAndRootFormat=derived \
  --ssr=false
npx nx g @nx/angular:remote challenges --host=dashboard \
  --style=scss \
  --e2eTestRunner=cypress \
  --projectNameAndRootFormat=derived
npx nx g @nx/angular:remote flashcards --host=dashboard \
  --style=scss \
  --e2eTestRunner=cypress \
  --projectNameAndRootFormat=derived
npx nx g @nx/angular:remote notes --host=dashboard \
  --style=scss \
  --e2eTestRunner=cypress \
  --projectNameAndRootFormat=derived
npx nx g @nx/angular:remote users --host=dashboard \
  --style=scss \
  --e2eTestRunner=cypress \
  --projectNameAndRootFormat=derived
npx nx serve dashboard

Add tailwind for because when you look good, you feel good.

npx nx g @nx/angular:setup-tailwind dashboard
npx nx g @nx/angular:setup-tailwind challenges
<div class="bg-black">
  <section class="p-16 mb-16 text-white">
    <div class="inline-flex">
      <a
        routerLink="/"
        class="bg-transparent border hover:border-transparent text-green-300 hover:bg-green-500 hover:text-white font-bold py-2 w-60 text-center"
      >
        HOME
      </a>
      <a
        routerLink="challenges"
        class="bg-transparent border hover:border-transparent text-green-300 hover:bg-green-500 hover:text-white font-bold py-2 w-60 text-center"
      >
        CHALLENGES
      </a>
      <a
        routerLink="flashcards"
        class="bg-transparent border hover:border-transparent text-green-300 hover:bg-green-500 hover:text-white font-bold py-2 w-60 text-center"
      >
        FLASHCARDS
      </a>
    </div>
  </section>
  <router-outlet></router-outlet>
</div>
<section class="bg-black p-16 mb-16 text-white">
  <div class="mt-5 p-8">
    <div class="grid grid-cols-12 gap-4 pb-5">
      <div class="col-span-5">
        <div class="text-9xl font-black">CHALLENGES</div>
        <div class="text-2xl my-10 font-bold">Lorem Ipsum dolor sit amet.</div>
        <div class="font-bold pr-5">
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat.
        </div>
        <div class="font-bold pt-5 pr-5">
          Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
          dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
          proident, sunt in culpa qui officia deserunt mollit anim id est
          laborum.
        </div>
        <button
          class="bg-transparent border hover:border-transparent hover:bg-white hover:text-black font-black text-4xl p-3 mt-12"
        >
          LET'S GO!
        </button>
      </div>
    </div>
  </div>
</section>
< Angular Home