davidlj95 / chrislb

Lazaro's website. Fashion stylist
https://christianlazaro.es
Apache License 2.0
1 stars 0 forks source link

build(ng): migrate to standalone app #332

Closed davidlj95 closed 7 months ago

davidlj95 commented 7 months ago

Description

Migrates the app to standalone

Steps

1. Convert all components, directives and pipes

Ran the command

ng g @angular/core:standalone (--mode convert-to-standalone)

Then ran all tests. Fixed some errors:

Git hooks ran the code formatting for us ✅

ng-mocks discovery: in order to use MockComponents APIs, you need to import the component under test in TestBed.configureTestingModule. Spread operator for MockComponents is not needed

Reviewing diff, found out that NgOptimizedImage is present in TestBed.configureTestingModule calls. But it's actually not needed, given the standalone component already imports it.

Also, not needed to import / declare the component under test if MockComponent APIs are not used. For instance, you can import RoutingTestingModule to mock Router APIs but don't declare the component under test under imports / declarations and create it directly.

2. Fix build

https://github.com/davidlj95/chrislb/actions/runs/8222927399/job/22484997305?pr=332

Custom schemas now need to be declared in the standalone component, not in the module where it belongs (given it's now standalone / module-independent). Moving custom schemas declaration to use swiper from project module to images swiper component. Which is way better indeed (custom schemas were only needed for that component). Removing custom schemas from test, given component already declares custom schemas.

3. Remove modules

Ran the command

ng g @angular/core:standalone (--mode prune-ng-modules)

But nothing could be done automagically. So removing them manually

About module

Moved routes from about routing module to about routes file. To later lazy load that instead (following standalone guide on lazy loading many routes at once). Font Awesome module is already imported by standalone components social / resume. Same for optimized image. Moving ngx-meta imports as providers in the routes file. No need to declare components, removing them. Providing the resume service in the ResumeComponent in the providers of it.

Projects module

Routes were already in a separate file. But whole module was loaded at bootstrap as it's main page, so no need to change routing things. Components, pipes are already standalone. Router APIs are already imported in each component. Projects service is declared where needed: in projects page and project page route (given resolver requires it). Resolver is then provided in the project page route. Assets collections is provided in only component that reqs it: project page. We can then remove project module.

Tests failed though: https://github.com/davidlj95/chrislb/actions/runs/8223441344/job/22486141495?pr=332

Seems that when providing a service through component providers, you need to mock it by calling TestBed.overrideComponent API

Routing module

Moved app routing module into app.routes.ts. Exports routes array instead of a module. Then, in app module, we use provideRouter + routes from file. Then, the features that were passed to RouterModule.forRoot are transformed into withX APIs.

Seems scrolling navigation stop working #333 But already happened before, so moving forward

4. Standalone bootstrap

Ran the command again

ng g @angular/core:standalone (--mode standalone-bootstrap)

App module disappeared. All configuration was placed in main.ts. Moved it to app.config.ts, which is the file created by Angular CLI for new Angular v17 projects.

HttpClientModule was transformed into provideHttpClient(withInterceptorsFromDi()). But given we don't use interceptors, removing that feature.

Removed RouterOutlet from app config providers, given the app component is now standalone and imports it.

SSR was broken, given app server module wasn't migrated. And it was trying to import the now removed app module. Generated a new app with pnpx @angular/cli@17 new --ssr and observed how that works for standalone apps. Seems a configuration file exists app.config.server.ts. Created that file and movied the local JSON fetcher provider there. The file provides the SSR provider + extra providers only for use with SSR. Then, main.server.ts exports bootstrap function instead that takes the server config instead. This bootstrap is eventually used in server.ts (as migration in Angular v17 tried to do #330 ).

5. ngx-meta standalone APIs

Instead of modules. In app.config.ts

davidlj95 commented 7 months ago

This stack of pull requests is managed by Graphite. Learn more about stacking.

Join @davidlj95 and the rest of your teammates on Graphite Graphite