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).

Shared Modules In Angular Apps: Providers Best Practices And What Does `forRoot()` Do?

When you write a shared module for your application, that contains stuff you use in other modules in the same app, you typically want all the services in that module shared only once.

If you just put the services in the providers property of the shared module’s NgModule() decorators, you might get weird cases, especially with lazy loading, when it feels like there’s more than one instance of the service. This is bad if you want to have shared state.

So, there is a better way to write your shared modules:

import {NgModule, ModuleWithProviders} from '@angular/core';
import {CommonModule} from '@angular/common';
// ... other imports

export const providers = [
    // ... your shared services here
];

@NgModule({
    declarations: [...],
    imports: [
        CommonModule, 
        SomeLibraryModule,
        ...],
    exports: [
        SomeLibraryModule.forRoot()
        ...
    ]
})
export class SharedModule {
    static forRoot() : ModuleWithProviders {
        return {
            ngModule: SharedModule,
            providers: [...providers]
        };
    }
}

The forRoot() pattern / convention is very common in libraries, and you’ll see it in things like ng-bootstrap and others. The name isn’t special for the compiler / framework, but it’s a common pattern.

When using these, in the imports section you can just import the module itself (which gives you any declarations needed like directives etc), and in the exports use the forRoot() version of the module so that it’s available for consumers of your shared module.

Then in your other application modules you can add SharedModule to their NgModule‘s imports normally, except for the AppModule.

The AppModule will be the only place where you add SharedModule.forRoot(), like:

Then in your AppModule, import it as:

@NgModule({
    declarations: [...],
    imports: [BrowserModule, SharedModule.forRoot(), ...],
    ...
})
export class AppModule {

}

There is one exception to this though. Your tests.

If you are writing any unit tests where you are importing the SharedModule, you will probably need to import the module with its providers, because there is no AppModule in the test.

Something like:

TestBed.configureTestingModule({
    imports: [ SharedModule.forRoot(), ... ]
})
...

If you haven’t already, have a look at the NgModule official documentation. There’s a main guide, and an FAQ page.

And of course let me know if you have any questions / problems.

Successfully Upgrade Your angular-cli App (Beta 28 & Below) To The Latest @angular/cli Beta


Have you had issues moving from angular-cli beta 28.3 or earlier to the newer versions of the CLI?

Try these steps then!

Global Dependency

This one is as easy as:

npm rm -g angular-cli @angular/cli
npm cache clear
npm i -g @angular/cli

Specific Project

Note: You do NOT need to have the CLI installed globally for this (although it’s a good idea).

First, ensure you have an npm script in your package.json file that looks like:

"scripts": {
    "ng": "ng"
    // ....
}

In this tutorial I’ll replace ng calls with npm run ng -- (note final space ) for those people who may not be able to upgrade their global package.

Now, let’s get to real work.

Commit everything you have in git, then:

npm rm angular-cli @angular/cli
npm cache clear
rm -rf node_modules
npm i -D @angular/cli
npm run ng -- update

Accept all files from update (which used to be called init) other than app module and component, especially (but not limited to) angular-cli.json, polyfills.ts, package.json and main.ts.

Then go to git undo any unwanted change (deleted packages from package.json, missing scripts or files from angular-cli.json, etc). Undo entire app module and component files if you accepted them by accident.

Then

npm install
npm run ng -- build

And you can go roll with npm start / npm run ng -- serve.

All good!

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,

Angular 4 Beta is out 🔥 Everything you want to know!

Hello there,
Have you heard the news? Angular 4 beta is here!

Yes, Angular 4!

Update: December 15, 2016

Angular 4 Betas have started coming out already.

Check out out from here.

This post started on December 12, 2016, and has been actively updated since.
Each update has its date marked.

Have I managed to make you panic yet?
Hopefully not. You might be raising questions already still, like:

What about Angular 3?

There won’t be any Angular 3. Right now the Angular Router version is using the 3.x space already, and is not in sync with the rest of Angular, which is still at 2.x.

So, the easiest way to bring them back in sync is to skip v3, and jump directly to v4.

Angular 4? Another Big Bang Release?

Not really:

Angular 4 will be released in March 2017. The first beta will ship in December (sometime this week as mentioned above). The intention is to release a new major version every 6 months.

Each new version is allowed to mark APIs from the last previous major version as deprecated, but NOT to break them. So:

  • Angular 4 might deprecate APIs from Angular 2, but not break them
  • Angular 5 might only deprecate APIs from Angular 4, but not break them (might break APIs from Angular 2 though)

The team has confirmed that Angular 4 will be a backwards compatible upgrade from Angular 2. You might expect a few deprecations at worst (until now that’s none BTW). But no API change / breakage.

So, what is Angular 2 and Angular 4 called now?

The team says: Just call it “Angular”. This should be more future proof.

Given Angular 4 is a backwards compatible upgrade, people searching for solutions to issues, etc., might find an Angular 2 answer, and that answers should just work with their Angular 4 app.

How about Angular 1?

Someone asked me on Twitter: “How would I avoid Angular 1 results showing up for my search then?”. I think the closest thing is adding “-angularJS” to your search (or “NOT angularJS”, without quotes in both). Angular 1 articles tend to use this way more than Angular 2 ones.

When was that announced?

There was a new Angular conference in Belgium last week. During that, the team made the Angular 4 announcement in the keynote.

Watch the full video from here

The conference team did not announce anything about releasing more videos, but when I asked them they confirmed that they’ll be available soon.

Update: December 12, 2016

The information has also surfaced in the official Angular team meeting for December 4:

Update: December 14, 2016

The team has also created an official blog post about Angular 4:
Ok… let me explain: it’s going to be Angular 4

How about … ?

If you have any more questions, just reply to this email. If I know the answers, I send it to you right away. If I don’t, I’ll do my best ti find it and send it to you.

Until next time!

Cheers,

– –

Meligy

Readify | Senior Software Consultant
ng-sydney | Usergroup Founder & Organizer

Email: eng.meligy@gmail.com
Mobile: +61 451 835006
Twitter | Blog | Linkedin | StackOverflow

 

P.S.

If you are in NSW Australia, the ng-sydney usergroup is holding its December gathering on Wednesday this week:

Check it out from here

If you noticed, it’ll be on December 14. This is the same day to expect Angular 4 beta 0 — how exciting!

Use DIV, TR, or any other tag instead of FORM tag in Angular 2

I got this question in one of my tech Facebook groups today:

In Angular2, Is there anyway for dealing with forms rather than form tag??? As In AngularJS 1.x, there was <form> and <ng-form>.

Is there something like that in Angular2 or we must deal with form tag?!

And the answer is: Yes. It’s possible to create forms without the form tag in Angular 2, with a gotcha…

Here’s how:

Template Driven Forms

If you look for the selector for ngForm directive in Angular2, you’ll find it like that:

form:not([ngNoForm]):not([formGroup])
ngForm
[ngForm]

Note that last one. Any element with ngForm tag <ngForm ...> or attribute <any ngForm ... > should work.

Reference

Reactive Forms (Model Driven)

The selector for formGroup directive is:

[formGroup]

Which also means that any element with formGroup attribute should work.

Reference

Gotcha

There is a relatively-big bug with non-form elements used as forms in Angular 2. The submit events do not work.

The implementation is just not as mature as Angular 1.

I have raised a bug here in March, but it’s probably a low priority:

@angular/angular#7807

You might be able to comment on it stating your scenario to bring it some attention.

Angular 2: Here’s how to use jQuery in an Angular CLI project

Please do not take the post as an endorsement of using jQuery with Angular 2. I do not think it’s a good idea. Most stuff you use jQuery for cam be done directly from Angular 2.

However, there might be legitimate reasons for using jQuery, like using jQuery widgets and plugins that do not have a non-jQuery based equivalent. If you are facing that, try this guide:

If you are using the Angular CLI (my personal recommendation), you can use jQuery with Angular 2 in very few and easy steps as follows:

First: Install jQuery, the actual library


npm install jquery --save

Then: Install jQuery TypeScript autocomplete


npm install @types/jquery --save-dev

Finally: Go to the ./angular-cli.json file at the root of your Angular CLI project folder, and find the scripts: [] property, add this inside it:


"../node_modules/jquery/dist/jquery.min.js"

(or use the slim version if that’s your cup of tea, keep the rest of the path as-is)

After that, jQuery will be available for you as a global variable. You can log jQuery’s version (which is available as jQuery.fn.jquery) to ensure it’s working brilliantly.

AngularConnect Videos & Free Angular 2 Router Book (Only for a few hours)

Hello,
This is Meligy from gurustop.net. I wanted to send you a very quick email to let you know about Angular 2 conference that took place in the last couple of days, Angular Connect.

The videos for the conference are already available on YouTube.

Check them out from here:

https://www.youtube.com/channel/UCzrskTiT_ObAk3xBkVxMz5g

There are videos for each whole-day track of the 2 tracks 2 day conference.
There are also videos for each session starting to come out. Seems all Day 1 is there, and Day 2 coming eventually.

For browsing through the whole-day videos, you can use the schedule page as guide, or just watch the individual session videos as they come out.

The sessions page on the site has all the separate videos that came out, and all the slides that are announced on Twitter, etc.

Another option is wait for the next message from me, as I’ll email you later all the most important summaries from the conference and what I think is must-watch.

Until then!


Meligy
gurustop.net
ng-sydney
Twitter | LinkedIn | StackOverflow

P.S.

This tweet was posted about 12 hours ago:

Victor is from the Angular Router team, and he writes the best Angular tutorials on
vsavkin.com.

Obviously this is only for less than 12 hours now, so get it quick.

Angular 2 final is released, here’s what you need to know

Update

The official release announcement is now out, with notes about future semantic versioning.

P. S. Sorry for spamming today with many emails. It won’t be the usual rate for these emails. I promise.

Hey,
Earlier today I sent you an email, saying that there’s a special Angular 2 event, where I expected the team to tell us when they are going to release Angular 2 final. I thought it would be too optimistic to ask for Angular 2 final today, but at least get a date!

I was wrong!

Watch the event stream, from the time 4:49s:
youtube.com/watch?v=xTIWBXkpvDc&t=4m49s

Yes, Angular 2 final is here. and it’s pretty much RC 7. No breaking changes :)
See the changelog as always.

Well, that’s it really. The NPM packages are updates, you just change the RC versions from 2.0.0-rc.7 to 2.0.0, and voila!

What About Angular1?

It will continue to be supported as long as the team sees a lot of usage (which they judge by how many people check the docs, now over a million people, 3 or 4 times Angular 2).

Most of the new minor features will be to make it more like Angular 2 though, and easier to migrate.

The Future

So, what comes after Angular 2 you ask?

Many small improvements that limit breaking changes, many more frequent releases to come without breaking your stuff.

One thing the team said is that they are not done making Angular faster yet, or smaller. They also said they really want to make the reactive / stream story amazing, and I’m guessing there’s still more work in the router space.

Then every 6 months or so (that’s February next year for the next one), a big release with breaking changes and semantic versioning, the next breaking-changes release, it will be Angular 3.

Most likely we’ll get the automatic project upgrade tool that the Angular team uses for automatic upgrades inside Google as well. The team said it should be by the time Angular 3 is out.

Very exciting, go check the whole special event video yourself!

I’ll be checking for more Angular2+ goodness, and emailing you with my findings as always.

Cheers,


Meligy
gurustop.net
ng-sydney
Twitter | LinkedIn | StackOverflow

Expecting Some Big News From The Angular 2 Team Today

Update 2:

Angular 2 final is here already!
Read my follow-up post here

 

Update 1:

Here’s the direct link to the livestream:
youtube.com/user/angularjs/live

The same YouTube channel will have the recording if you are checking this later.

Hello,
This is Meligy from gurustop.net. I thought I’d drop you a quick note to let you know that the Angular 2 team are having a local meetup in the mountain area in the U.S. later today, and they are saying it’s going to be a very special one.
It’s even titled Special Event!

What’s going to happen? Are they going to release Angular 2 Final?
That’s unlikely. But they might announce the release date!
Will it be in Angular Connect this month, or ng-europe next month?
I can’t wait to know!!

Well, the meetup is going to be streamed anyway. And it’s going to be in very convenient times for those living in the U.S. or Australia especially.

The talk will start at 7 PM PST, which is 12 PM East Australia Time, so you can watch in the evening, or during the lunch break, depending on where you are in the world!

Just check the Angular twitter account 10 minutes or so before the show start.
They should post the livestream link around then.

If you are into twitter, you can send them questions using the hashtag #ashng, but if you aren’t, you can just check the twitter page (no account needed) only for the streaming link.

In other news…

If you haven’t heard already, Angular 2 RC 7 has been released earlier this week.

The changelog shows only RXJS and Zone library upgrades, and a fix for lazy loading in the router when using Webpack.

Lazy loading is an interesting piece when it comes to play with NgModules and AOT compiler. Here are some great slides about what the Angular compiler does. We need to dedicate more time to the topic still.

If you want to take advantage of the fix, it should be a matter of upgrading your packages and nothing else. The team are keeping their promise to limit the breaking changes after RC 5 deprecations, and this is awesome!

Here’s how Angular-CLI upgrade commit looks like for example. Only package.json changes. Nothing else.

Speaking of the CLI, they also released a new version yesterday. You should check it out. The changelog tells you what’s new, but you can also directly check the commit log.

It should be a matter of npm i angular-cli@webpack. There’s now less need to work with the CLI from Github directly, but that’s how I personally tested the release yesterday even before it came out. I’m rewriting my guide on how to do it. Stay tuned!

That’s it!

Watch the meetup either streamed or recorded, or don’t worry about it as I’ll always keep you updated with any big news.

Until next one,

Cheers,


Meligy
gurustop.net
ng-sydney
Twitter | LinkedIn | StackOverflow