What's new in Angular CLI 17.0?

Angular CLI 17.0.0 is out!✨

If you want to upgrade to 17.0.0 without pain (or to any other version, by the way), I have created a Github project to help: angular-cli-diff. Choose the version you’re currently using (16.2.0 for example), and the target version (17.0.0 for example), and it gives you a diff of all files created by the CLI: angular-cli-diff/compare/16.2.0…17.0.0. It can be a great help along with the official ng update @angular/core @angular/cli command. You have no excuse for staying behind anymore!

Let’s see what we’ve got in this release.

Standalone applications with Vite by default!

The --standalone flag is now the default behavior of the CLI. This means generating a new project with ng new now uses standalone components by default, and that the ng generate component/pipe/directive command now generates standalone components/pipes/directives.

Another notable change to ng new is that the routing is now enabled by default.

But the most important change is that the CLI now uses Vite out-of-the-box! A new builder called application has been introduced, and is used when generating a new project. This builder has a very similar configuration to the browser builder, so the migration is quite easy if you want to use Vite in an existing project You have to change the builder from browser to application in the angular.json file, rename the main property to browser, and remove a few options from the development configuration (buildOptimizer, vendorChunk).

Once migrated, the ng serve command will use Vite instead of Webpack. Build time should be faster, especially for cold starts (I saw 2-3x times improvement on my machine). There is no HMR by default yet, but the global style changes are detected and applied automatically without reloading the page.

Note that the output of the ng build Vite-based command is now in dist/my-project/browser instead of dist/my-project.

The browser-esbuilder builder still exists, but will be removed in the future. You should use the application builder instead.

ng new –ssr

A new flag --ssr has been added to the ng new command to generate a new project with SSR enabled out of the box.

It generates a project similar to what you usually get and then runs the @angular/ssr schematics (you can also use the schematics directly on an existing project with ng add @angular/ssr). @angular/ssr is a new package and replaces the Angular Universal package. If you were using the Angular Universal package, ng update migrates your configuration to use @angular/ssr automatically.

This schematic does the following:

  • adds the @angular/ssr package
  • adds the @angular/platform-server package
  • adds the express and @types/express packages
  • adds the main.server.ts file (entry point for the application when running on the server)
  • adds the app.config.server.ts file (providers for the application when running on the server)
  • adds the tsconfig.server.json file
  • adds the server.ts file (the Express server, responsible for serving the application)

It updates the angular.json configuration to add the following options to the build target:

"server": "src/main.server.ts",
"prerender": true,
"ssr": {
  "entry": "server.ts"
}

and adds the provideClientHydration() to the (browser) application providers, to have a smooth transition between the server and the client. This is a new feature of Angular v16, and we talked about it in our article about the v16 release.

When running ng build, the CLI will now build the server bundle (in dist/my-project/server) and the client bundle (in dist/my-project/browser). You can then run the generated server with:

node dist/my-project/server/main.server.mjs

This starts an Express server on port 4000 by default, which serves the rendered pages.

The rendered pages are in the browser folder, and are named ${page}/index.html:

dist/my-project/browser/index.html
dist/my-project/browser/login/index.html
dist/my-project/browser/register/index.html

If you use localize in your application, the CLI will also build the localized bundles (in dist/my-project/server/${lang}).

The prerendering mechanism should be quite accurate now, as it uses the Angular router under the hood to navigate to each route and render it (routes with parameters or redirections are skipped). When prerendering is enabled, the CLI generates a prerendered-routes.json file that contains all the prerendered routes. This is useful if you deploy on the cloud as this file is usually recognized by providers to serve these files as static.

{
  "routes": [
    "/",
    "/login",
    "/register"
    ...
  ]
}

You can disable the auto-discovery of routes by setting the discoverRoutes option to false in the angular.json file. You can also provide your own list of routes in this file by defining routeFiles:

"ssr": {
  "discoverRoutes": false,
  "routeFiles": "ssg-routes.txt"
}

This file must contain a list of routes that you want to render (and can contain parameterized routes).

When running ng serve, the CLI serves the application via Vite, and only pre-renders the requested page (the one you’re currently on).

You can also use a new option to CommonEngine called enablePerformanceProfiler to trace the performance of each step of the rendering:

const commonEngine = new CommonEngine({
  enablePerformanceProfiler: true
});

When using SSR, it is recommended to use the Fetch version of the HTTP client, by using provideHttpClient(withFetch()) (as introduced in Angular v16.1). This is for performance and compatibility reasons.

NG02801: Angular detected that `HttpClient` is not configured to use `fetch` APIs. It's strongly recommended to enable `fetch` for applications that use Server-Side Rendering for better performance and compatibility. To enable `fetch`, add the `withFetch()` to the `provideHttpClient()` call at the root of the application.

Functional HTTP interceptors by default

The CLI now generates functional interceptors by default, without the need to specify --functional anymore. Class-based interceptors are still available with the --no-functional option, but you’re now encouraged to use the functional ones.

Summary

That’s all for the CLI v17.0 release! You’ll find more interesting features in our article about the framework v17.0.0 release.

All our materials (ebook, online training and training) are up-to-date with these changes if you want to learn more!



blog comments powered by Disqus