How to upgrade your Angular CLI project to Angular v7 (or v6) without too much manual pain

I recently upgraded a relatively big project to Angular and Angular CLI v7.
The instructions were the same as upgrading to v6. Except, for both versions there were missing pieces that I didn’t see fully documented in one place, and the most comprehensive docs I saw on how to do it involved more manual work than I liked, so, I decided to share my findings here for the next person.

Let’s upgrade…

Prerequisites

NPM

Before we continue, make sure to have latest NPM (at least 6.2). You can upgrade your NPM by running:

We’ll use the npx tool from NPM to run binaries from local and global packages as needed.
I don’t like installing the CLI globally, that’s why you’ll see me often run npx ng instead of just ng.

Angular v7 Or Angular v6

If for some reason you really want to upgrade to v6 first, replace latest below with something like ^6.0.0 and add a --to argument to ng update, but in my experience, going to v7 from v5 didn’t require this step.

ng update

This is the tool that takes care of upgrading all dependencies in package.json, and some breaking code changes between Angular versions.

It’s awesome, but it doesn’t do everything as we’ll see below.

Installing Latest Angular CLI

First, you need to install the latest Angular CLI locally before running ng update.
We cannot just run it with npx without install, because the global CLI always passes commands to the project specific version if applicable, so, to run the command, it needs to be locally installed.

There’s another missing dependency which might break the upgrade, and you’ll have to install it as well.

Later below you’ll run npx ng build to make sure everything else is alright. If it or ng update itself complain about missing packages, just add them. For example, my project required me to add date-fns for some reason to build.

Running The Update Command

The minimum you need is something like:

The --force is required to ignore peer dependency warning.
The --from must be the previous Angular CLI version you had before. Angular CLI can be confused without it.

If you have other libraries that support upgrading, and you probably do, the more generic form of above becomes:

See below for more about libraries.

Manual File Changes

Unfortunately the following files will have to be updated and merged by hand:

  • angular.json, from an existing .angular-cli.json or similar
  • tsline.json
  • src/polyfills.ts

Create a new project using the CLI, copy the files from that project, and then look in git diff or something to restore any customizations you might have, like styles / scripts / assets in angular.json, or uncommenting/restoring some import statements in src/polyfills.ts.

Remember to go to a different directory outside your project to create a new project to copy the files from.
The command for creating new project without installing the CLI is:

RxJS Automatic Upgrade

That’s another one where order of steps is important.

First, you need to install these 2 packages:

Then import the compatibility package in your code, so that the app still compiles, as it’ll be broken with RxJS upgraded to v6+. Add the following line at the end of src/main.ts.

Then, automatically convert all files to the new RxJS syntax:

Note that this command might take LONG time if you have a big project.
Give it time. Don’t panic!
Also note that I used tsconfig.json here, the one intended for the editor, not the project specific tsconfig.app.json. It’s because it might be better to upgrade any code in tests too.

The reason I used tslint directly is that the -c flag didn’t work for me on Windows, not from rxjs-5-to-6-migrate directly (it is a CLI), and not from npx ng lint.
After you finish. You can also copy the contents of node_modules/rxjs-tslint/rxjs-5-to-6-migrate.json and merge them into your project’s tslint.json file, and do the whole thing using just npx ng lint --fix.

After that, run npx ng build and see if there are any few left over errors, and correct them manually.

Then you can try removing the import in main.ts, and npx ng serve to see if everything is good, and no other library breaks.

Manual RXJS Upgrades

After the RxJS automatic upgrade, npx ng build will probably still give you RxJS related errors.

Don’t worry about cannot find module ... errors. These are fake and caused by other errors above them.

The one manual change I had to do after running the above command was to go in VS Code, and Find & Replace all ObservableOf to just of. I didn’t need to fix the import statements.

You may also get a few duplicate import errors. This is rare. In my project it was caused by some file importing delay from lodash, and using the RxJS delay operator instead. They should be few enough to be not too bad to fix manually.

If you get too many errors for too many operators, make sure you did install and import rxjs-compat BEFORE running the RxJS upgrade.

Manual Library Upgrades

Some libraries might require manual upgrade.

For example, The Telerik (now Progress) Kendo UI library can be upgraded by running:

Some libraries will be upgraded automatically for you, but have some code left behind.
You’ll just have to run ng build, and fix errors manually by checking the libraries’ docs and searching.

In my experience on a relatively big project, that wasn’t too much work.

That’s It

Hopefully no pain from libraries etc.

If you are able to get the site running in the browser, and all functionality seems to be working as before, create a pull request for your team, and apologize to them for the massive size of changes due to RxJS upgrade!

Cheers,

Try latest Angular CLI Beta / RC, with Angular v7 and the new Ivy compiler, no install required thanks to npm and npx

There are some pretty nice features in Angular CLI 7, like user prompts offering multiple options when creating new projects. Also it comes with Angular 7 support, which itself has some nice features like performance and routing improvements, the new Ivy compiler, and support for latest TypeScript.

In this post I’ll show how to try out the new combo easily.

TL;DR

Prerequisites

Make sure you have Node 8.x or higher (run node -v to check). Then that you have NPM 6.2 or higher (run npm -v to check).

I highly recommend upgrading NPM at least to latest, by running npm install --global npm, or npm i -g npm for short.

Using the CLI Without Install

Recent versions of NPM come with a nice utility called npx. It allows us to run any CLI package without installing it. If we are inside a Node project already (we have package.json), it allows us to call any CLI tool from inside our project’s node_modules/.bin folder.

For Angular CLI, the NPM package name is @angular/cli, and it gives you the CLI command ng.
So, this is how I’d create a new project using the current version of the CLI, and run it in the browser, using ng serve -o (-o opens it in the browser).

In the first line, we downloaded @angular/cli from the NPM registry, that’s why we needed the full package name. In the last line we just used the command ng that we knew was available in sample-project/node_modules/.bin.

Note that we didn’t need to escape the -o flag in the last command.
The Angular CLI usually sets the npm start script to ng serve, so the line npx ng serve -o is the same as:

Except we didn’t need the -- bit, that makes npm send the argument to the actual CLI command instead of NPM itself.

Managing The Correct Version

If we already have the Angular CLI globally installed (via npm i -g @angular/cli), npx will use the version that’s installed by default. We can force a download of the current version by adding -p to the first line, and specifying that we want the ng command manually, like:

Another way is to include the version in the command, like:

I added ^ to ensure I get the latest 6.x.x, but it’s optional.

Instead of a version, we can use a tag (a named version), let’s see what tags are available for Angular CLI by running npm info @angular/cli dist-tags. The output might look like:

You can run npm info @angular/cli, without appending dist-tags, to learn so much more about the package, like all versions, description, license, dependencies, and more.

Now, to make sure we get the latest version of the CLI, we can use the tag instead of the version, like:

You do NOT need to do this if you never install the package globally (or if you globally remove it).
I usually do NOT install it myself.
But there’s benefit in learning about the gotchas, and about tags.

Using Prerelease Version (No Ivy Yet)

As you saw above, we don’t have many tags really. The only tag other than latest, is next.
So, to create a new Angular project using the latest beta/RC version of the Angular CLI, we can simply run:

You’ll see the fancy new project prompts, and after that, you can confirm the version that was installed by running:

npm ls shows the locally installed version of the package, and you should then see the latest beta or RC being used.

Go ahead and play with it!

Enabling Ivy compiler

There’s another flag you have to add when creating projects in order to use the Ivy compiler, which is --experimental-ivy. The command to create a new project becomes:

Some Ivy compiler guides suggest that you need to activate Ivy compilation by adding angularCompilerOptions object to your tsconfig.json file, with a enableIvy property set to true or "ngtsc" or "tsc" , but I didn’t seem to need to do any that.

To be impressed by Ivy, run:

And notice how the main .js file is only 32KB!

Upgrading Existing Projects

If you already have an Angular CLI project, using the latest stable version of Angular CLI and Angular itself, you can use ng update to try out the upcoming bits.

It would look something like:

And if you use Angular material, also add:

Note that these commands are pure Angular CLI schematics magic not NPM as most of the other stuff mentioned here.

Conclusion

That’s all you need to start playing with the newest bits, so go on and hack along!

Cheers,

My Experience Running Jest In A Real Angular CLI Project On Windows

Jest is an alternative test runner by Facebook. It’s popular in React world. I was wondering how it’ll be like in an Angular CLI app. I knew a new semi-empty app won’t be a good enough test, so, I checked it in a real private project I’m working on, so see if it has any benefits for the project and the team.

While I cannot share the project codes, I can still share how the experiment went, as I talked about it yesterday at the ng-sydney Angular usergroup April gathering, also, as I logged it in a related Angular CLI github issue by a friend ng-sydney attendee.

Introduction

For the record, I tried Jest with instructions from @thymikee‘s post (which uses jest-preset-angular), and it worked just fine.

Let me share my findings:

Result Summary

  • It works!
  • It took some small changes.
  • It seemed slower in my case.
  • It caught more errors than Webpack/Karma/Jasmine, which I was very grateful for.
  • The experience is quite different though that I won’t make it the default my team yet.

Required Changes

  • I started with all the steps in the post above.

  • For some libraries I had to follow this github guidance, which made the jest property in my package.json look like:

    The transformIgnorePatterns is the most interesting here. I used \\ because I’m on Windows, and I used ^<rootDir>\\ to try to speed things, although it didn’t make a big difference. There’s also "allowJs": true in "compilerOptions" in src/tsconfig.spec.json.

  • I also had to change the tests. The post mentions all the changes needed (mostly only changing jasmine. to expect. in a few places).

    But there’s another change I had to do, which is removing any expectationFailOutput, which is when you give a custom error message for when a matcher fails to match. Seems Jest does not support that.

Gains

  • Jest seems to run tests in more isolation than the current Webpack/Karma/Jasmine combo, which showed me some errors in my tests that somehow didn’t show before.

  • Jest is reporting which tests are taking too long, the slowness warnings were useful smells to identify not-greatly-written tests.

  • The watch mode is very nice, even though it seems to work off git changes not file watching, which can be confusing at first when you see slightly more files than expected, but it’s still very useful.

Issues

  • As mentioned in Required Changes above, now I cannot use custom error messages in my test matchers (that said, it’s true that default matcher errors are very beautiful and obvious, but still).

  • At the moment, it seems the jest-preset-angular initialization code needs optimization. It doesn’t call polyfills.ts and instead calls its own set, even though it’s optimized for Angular CLI (for example, it uses src/tsconfig.spec.json).

    More importantly, it imports the entire rxjs library, which might hide errors when you forget to import some operators.

  • It’s surprisingly slower than the Webpack/Karma/Jasmine combo!

    For my 196 tests, the Angular CLI v1.0.0 default test runner (with Angular 4) takes ~ 55 seconds, while Jest takes ~100 seconds.

    Update: That conclusion might not be accurate. The time I quoted for each test runner is what the test runner reported. This might for example not include Webpack compilation and browser opening in Karma and might be total time in Jest. If so, then the total time would be the same.
    Thanks @hugoccampos for bringing this to my attention.

  • No browser tests debugging apparently (It might be my ignorance here). A bit harder maybe for those starting testing.

    The Angular CLI does a great job at making testing easy for those not used to it.

  • When Jest itself fails to run, for example if I put a badly formatted regex for transformIgnorePatterns shown above, or mess up something in my src/tsconfig.spec.json file, the errors it shows are very cryptic and tell you nothing that can lead to the real issue (unlike matching errors in tests, which are very nice).

Angular 4.0 Final Is … Here! And Angular CLI 1.0 Is Final Too!!

Update (March 24)

Angular 4 Final Is Out Already

Check out the official announcement, and github changelog.
After that, check the updated documentation for Angular 4 at angular.io.
If you need access to Angular 2 docs, check the black-and-white official docs archive at v2.angular.io.

Update 2

And, on the same day, just as mentioned earlier in the post below…

Angular CLI 1.0 Final IS Out Too

Checkout the changelog, README / Docs.
And if you ever used Angular CLI before v1.0 final, check the official upgrade guide.

Hello, This is Meligy from GuruStop.NET.
Good news, we are expecting Angular 4 final any hour now!

How Do We Know?

During the ng-sydney Angular meetup gathering last Wednesday, Stephen Fluin from the Angular team repeated a couple of times that Angular 4 final is expected this week.

A quick look into the latest Angular team meeting notes also confirms that Angular 4 is due on Thursday, March 22 (although they mentioned there are a couple blocking issues, so, it might be on Friday or so).

Angular CLI, the best tool to create, develop, and test Angular applications, is also going to be released as 1.0.0 final alongside Angular 4.

P.S.
If you prefer to add server-side rendering, you might check Angular Universal fork of the CLI fork for Node, and `dotnet new Angular` for ASP .NET Core. If you need to build an Ionic app, check Ionic CLI 3 beta. They all would come with Angular 2 support by default only though, while the official Angular CLI supports generating Angular 4 projects by running `ng new app-name –ng4`.

[Video] Angular 4 And The Angular CLI

If you want to learn more about Angular 4 and the Angular CLI, see Stephen Fluin`s video here:

[Video Playlist] More Recent Talks, NG-NL

If you are interested in more free up-to-date Angular videos, the NG-NL Angular Netherlands conference also took place last week, and many session videos are available now in this YouTube playlist:

https://www.youtube.com/playlist?list=PLQi8NNYCH8TDFnOhjrIsjZGMD6Ks8SQid

Angular 4? (Not 3!!)

Just for those who don’t know, the reason there is no Angular 3 is that the Angular router for Angular 2 has been rewritten 3 times, and the NPM package for Angular router is now 3.x, while all other Angular packages are 2.x.

To make all the packages the same version again, the Angular team skipped version 3 entirely, and jumped directly to version 4.

It’s worth reminding though that Angular 4 is mostly backwards compatible with Angular 2. You should expect most if not all your applications to continue to work with it.

And a final reminder, it’s “Angular”, for Angular 2+, and “AngularJS” for Angular 1.x. These are the names that the Angular team prefers, and that’s what you’ll see me use more often going forward.

What’s Next?

Once Angular 4 final is out, I’ll send you a follow up email, with a very customized writeup of what I personally find most exciting about Angular 4, and can’t wait to use in all my production projects.

I’ll also share some awesome resources for RxJS and TypeScript.

Stay tuned!

Cheers,

– –

Meligy

ng-sydney | Usergroup Founder & Organizer

Use Yarn Package Manager In Your Angular CLI Projects

Yarn is an awesome tool to reduce the time it takes to install large NPM packages like the Angular CLI. And the Angular CLI is the best tool to kickstart and manage your Angular 2+ projects.

You can use them together, and it’s very easy.

Initial Setup

First, you install Yarn. If you have it installed already, ensure that you have version 0.19.x at least to avoid issues with global packages. You check your Yarn version by running:

yarn --version

Then you need to ensure that the folder where Yarn writes the global packages executable files.

On Windows, the MSI installer should do it for you. For Mac, check the “Path Setup” part in the installation page.

Once done, ensure to open a new terminal after the installation, and test it.

To find what folder to look for:

yarn global bin

Then run echo $PATH (Mac) or echo %PATH% (Windows command prompt) to get the PATH variable and check it.

Installing Angular CLI

OK, so yarn is installed, and it’s installed correctly. Let’s get Angular CLI:

yarn global add @angular/cli

That’s it!

Adding To A New Angular CLI Project

Starting from beta 31, Angular CLI added native Yarn support.

When you create a new project, the CLI goes and runs npm install for you by default. You can tell it not to by passing a --skip-install flag (-si for short) like:

ng new test-project --skip-install

Note: The option was called --skip-npm / -sn before beta 31.

But then you’ll have to go run Yarn yourself

cd test-project
yarn

Running yarn by itself is similar to npm install. It’ll read your package.json file and add the packages to node_modules as needed.

Or… you can just tell the CLI to use Yarn instead of NPM!

ng set --global packageManager=yarn

This way, you don’t need to do anything special when creating new projects. Just go with ng new test-project with no special flags, and the CLI will use Yarn to install the project packages, unless you specify --skip-install.

This is a user-level setting. It does not affect the generated project in any destructive way. It still has a package.json file (because Yarn works just fine with that), and anyone who doesn’t have Yarn can just run npm install.

More on that below. Before that, let’s ensure that everything worked correctly by running npm start or ng serve etc.

All good? Awesome!

Bonus: A Note About Git

When the Angular CLI creates the project, it initializes it as a git repository and git adds all the files it generated. After the Yarn install, you’ll find another file yarn.lock that’s not yet added.

Yarn team recommends adding the file to git, so, you can do just that, and then commit the result as the new project.

git add yarn.lock
git commit -m "initialize new project with Yarn and Angular CLI"

When you push your repository to a remote server, and someone else pulls it, they can run yarn, or simply npm install (because the package.json file is still there and updated), and get going with the project.

Conclusion

Hopefully that was as simple as you expected it to be. If you have any questions, you can just drop me a comment here, or use any alternative way mentioned in the video.

Don’t forget to sign up for my newsletter so that I can share with you all the resources I use to learn this stuff and more.

Cheers,