Skip to main content

angular-20

That's an excellent and very current observation. You are absolutely right. The Angular team has been actively moving away from the classic webpack build system in favor of a new, faster one that uses esbuild and Vite.^1^

Here's a breakdown of what that means for you:

  • esbuild for Builds: For new projects created with ng new in recent versions of Angular (starting with Angular 17 and continuing in 20), the default build builder is @angular-devkit/build-angular:application, which uses esbuild under the hood. esbuild is written in Go, which makes it significantly faster than the previous JavaScript-based webpack.^2^

  • Vite for the Dev Server: For the development server (ng serve), Angular is now using Vite. ^3^Vite leverages native ES modules and is known for its incredibly fast startup and hot module replacement (HMR).^4^

  • The "Application" Builder: This new build system is all rolled into one builder in your angular.json file called "@angular-devkit/build-angular:application". It replaces the older "browser" and "server" builders, creating a more streamlined and performant experience.

The core benefit is a massive improvement in build and serve times, which leads to a better developer experience.^5^

Even with this new tooling, the angular.json budgets still work as intended. The new build system still generates the same types of output files, so the budget checks remain relevant.

As for analyzing your bundle size with this new builder, the webpack-bundle-analyzer might not work directly. The Angular team has not yet provided a dedicated tool for the esbuild build, but you can still get a very good sense of your bundle size and composition by simply looking at the output of a production build. The ng build --stats-json command still works, but you would likely need a different tool to visualize that stats file. However, simply looking at the file sizes in your dist directory is often enough to find large, unoptimized assets like images.

So, while the underlying tooling has changed, the need for optimization remains, and your angular.json budgets are a great way to enforce those goals.

instructions/angular.instructions.md

General Guidelines for Lines of Code (LOC)

  • HTML (.component.html):

    • "Yellow Flag" (Consider decomposition): 100-150 LOC.
    • "Red Flag" (Definitely decompose): 200+ LOC.
    • Why: Large templates are difficult to read and manage. They often contain complex *ngIf, *ngFor, and [ngClass] logic.
  • SCSS/CSS (.component.scss):

    • "Yellow Flag": 150-200 LOC.
    • "Red Flag": 300+ LOC.
    • Why: A large stylesheet for a single component suggests it's styling too many different parts of the UI, or the styles are overly complex and could be shared.
  • TypeScript (.component.ts):

    • "Yellow Flag": 200-300 LOC.
    • "Red Flag": 400+ LOC.
    • Why: A large TypeScript file often indicates the component is doing too much: fetching data, handling complex form logic, managing state, and rendering the view. It violates the "Single Responsibility Principle."

Flow Syntax

Angular's move to a more block-based, imperative-looking control flow syntax (@if, @for, @switch) is indeed a significant shift, and it draws inspiration from trends seen in other popular frontend frameworks that have historically offered more direct, less "directive-heavy" ways to handle conditional rendering and lists.

Here are the key frameworks that either pioneered or popularized similar approaches:

  1. Svelte

    • Trendsetter for compile-time reactivity and concise syntax. Svelte is often cited as a major influence. From its inception, Svelte has used a very direct, HTML-like syntax for control flow, directly embedded in its .svelte component files.
    • Syntax:
      • Conditionals: {#if condition} ... {:else if anotherCondition} ... {:else} ... {/if}
      • Loops: {#each array as item, index (key)} ... {/each}
    • Key Idea: Svelte is a compiler. It takes your Svelte code and compiles it down to highly optimized vanilla JavaScript, rather than relying on a runtime virtual DOM or complex change detection. This allows it to offer very concise and intuitive template syntax that gets transformed into efficient code. Angular's new control flow, while not a full compiler like Svelte, aims for similar readability benefits and performance optimizations.
    • When: Svelte introduced this block syntax very early on in its development (initial public release in 2016).
  2. Vue.js

    • Pioneer of directives as attributes. Vue.js, while still using directives as attributes (like v-if and v-for), offers a very readable and often less verbose approach than traditional AngularJS or even older Angular versions.
    • Syntax:
      • Conditionals: v-if="condition", v-else-if="anotherCondition", v-else
      • Loops: v-for="item in items" :key="item.id"
    • Key Idea: Vue's template syntax is HTML-based with special attributes (directives) that add reactive behavior. While it doesn't use the block syntax exactly like Svelte or new Angular, its v-if and v-else can be placed directly on elements or template tags, making it feel very integrated into the HTML.
    • When: Vue.js first released in 2014, and its core v-if and v-for directives have been central to its template syntax since its early days.
  3. React (and JSX)

    • JavaScript-first approach. React doesn't have a separate "template language" in the same way Angular, Vue, or Svelte do. Instead, it uses JSX, which is a syntax extension for JavaScript that allows you to write HTML-like markup directly within your JavaScript code.
    • Syntax: Since it's just JavaScript, you use standard JavaScript control flow:
      • Conditionals: Ternary operator (condition ? <TrueComponent /> : <FalseComponent />), logical AND (condition && <Component />), or actual if/else statements outside the JSX return.
      • Loops: array.map(item => <ListItem key={item.id} />)
    • Key Idea: React's philosophy is "JavaScript all the way down." This means developers use familiar JavaScript constructs for all logic, including conditional rendering and lists. While this isn't a dedicated "block syntax" in the same visual way as Angular's new feature or Svelte's, it achieves the same goal of tightly integrating logic with the UI structure using standard language features.
    • When: JSX was introduced with React's initial public release in 2013.

How they influenced Angular's New Control Flow:

Angular's new control flow draws inspiration from these frameworks by:

  • Svelte: Directly adopting a block-based syntax for if, for, and switch, making the template logic feel more like a mini-program within the HTML, similar to Svelte's approach. The @empty block for @for is also very Svelte-like ({:else} or {#if !array.length} in Svelte's #each). The mandatory track clause in @for is a direct nod to Svelte's key mechanism for efficient list rendering.
  • Vue: The desire for a more concise else if and else with @if directly addresses a pain point that Vue's v-if, v-else-if, v-else handled more elegantly than *ngIf.
  • General trend towards clarity and performance: All these frameworks, in their own ways, aim to provide clear, performant, and intuitive ways to handle common UI patterns like conditionals and lists, moving away from overly verbose or magic-string-based approaches.

Angular, being a more opinionated and "batteries-included" framework, traditionally had its own distinct way of handling these things with structural directives. The move to @if, @for, @switch is a significant step to modernize its template syntax, improve performance, and align it more closely with successful patterns observed in the broader frontend ecosystem.