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

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