⚠️ This lesson is retired and might contain outdated information.

TypeScript - Using Typings and Loading From node_modules

John Lindquist
InstructorJohn Lindquist
Share this video with your friends

Social Share Links

Send Tweet
Published 8 years ago
Updated 5 years ago

Using TypeScript when installing packages from npm often requires you to install related definition files. This lesson shows you how to use typings to install es6-shim then how to configure SystemJS to load from node_modules.

[00:00] There are few projects on NPM that already include the definition files or the typings like RxJS. If I go ahead and just saved that. You've installed RxJS from NPM.

[00:11] Now, I'll switch over to my main, and you'll see if I import RxJS, that it's going to throw some errors here about can't find promise. One way to fix this in the future will be to hop over to our tsconfig, switch over to a target of ES 6. That way, promises and all the ES 6 features will be available.

[00:36] Just to show what I mean, I'll restart the types of compiler. Sometimes, if you change the tsconfig, you usually need to restart the types of compilers, what gets all those changes from your configuration.

[00:48] Then if you switch over to main.js, you can see that use this classes and other ES 6 features, that it wouldn't have used if it would've been ES 5. We'll hit that, and I'll recompile. You can see you run into these promise errors again when we're targeting ES 5, and it's doing classes in the ES 5 way.

[01:09] What we need to do is typings, install ES 6-shim. We'll save it. We're also going to throw in the ambient flag so that goes out the looks for ES 6-shim in all possible locations. I'll find it the different repository than the normal one.

[01:27] We got ES 6-shim. You'll see that in the typings now. If I look into my browser, ambient, there is my ES 6-shim definition file. Then all my errors went away. Now on my main.ts, I can import RxJS just fine.

[01:43] Even though RxJS had its definitions inside of node modules, it relied on some ES 6 features like promises, where you need to go out and get the ES 6-shim, which someday you won't need to do, because you could just target ES 6. For now, it's much safer to target ES 5. I'll go ahead and use my RxJS.

[02:06] Import, let's say, observable, grab observable off of it. Then, I'm also going to want to import RxJS, add observable timer. So, I can do something like observable timer. Every one second, push out a value. We'll subscribe to that. Then just log out the output. Now, when I hit save and this recompiles, I won't get any errors. But when I refresh, I'll run into that same can't find the things that I tried to import.

[02:49] Remember, type script does not do anything to load these for you. It just is going to write these require statements, and you need to configure how to load them yourself. In this case, from node modules, we're going to map RxJS to node modules/RxJS. Make sure I had the comma there. Now, we'll hit save. I'll refresh.

[03:18] You'll see this time a little bit different behavior. Now, it's trying to load add/observable/timer, which is a directory or a file without an extension, meaning that we need to configure another package, this one being RxJS.

[03:33] Just give it the same default extension, so that we know we're loading JavaScript files. I'll hit save again. In this way, it'll append the .js to the end of this when I reload. I'll reload now. You can see, we get true, and then it's going to start logging out the timer. It hit zero.

[03:50] Let's switch that over to interval, import interval as well, switch this to interval, hit save. This will compile for us, so I'll refresh. Now, we get true, zero, one two, It's running this interval.

[04:07] You can see on our main that it's requiring interval and in our network, that it's loading in all the things necessary, each individual file necessary to make those work, because now we've mapped our system JS so that any files it needs, it's going to look in RxJS and load all those individual files.

[04:30] I just want to re-emphasize, no matter what sort of module loader you use, whether it's system JS or anything else, there will be configuration required on how you load it up, because type script is just outputting files and you need to tell these files what it's supposed to do with require.

moti zharfati
moti zharfati
~ 8 years ago

Great Tutorial John! It's seem to me very confusing to make it work, we have to set too much configuration in order to install lodash and rxJs, in the old way everything was easy: "script:src to remote lodash" (on the client, or i can use gulpfile to bundle everything) and that's it! I hope someone will improve it...

Michael Peake
Michael Peake
~ 8 years ago

IMO, it's much easier to get it all working with Webpack, rather than with SystemJS. Just my preference though.

Michael
Michael
~ 8 years ago

Really enjoy yet another great course from you John! Just want to note that npm install rxjs --save will install rxjs@5.0.0-beta.8 and the example with subscribing to the 1s observable interval in this clip won't run. However, revert it back to rxjs@5.0.0-beta.6 will do the trick.

Alexander Esser
Alexander Esser
~ 8 years ago

You could also do "npm install symbol-observable" and adjust the System.config in the index.html. In packages you would need to add: "symbol-observable": { "defaultExtension":"js", "main": 'index.js' } and in map: "symbol-observable": "node_modules/symbol-observable",

Maybe this helpful for someone.

Paul
Paul
~ 8 years ago

When I run the new command "typings install dt~es6-shim --save", I get this error.

typings ERR! message Attempted to compile "es6-shim" as an external module, but it looks like a global module. You'll need to enable the global option to continue.

typings ERR! node -v v6.2.0 typings ERR! typings -v 1.3.0

Any suggestions?

G Inc.
G Inc.
~ 8 years ago

Make sure to run it with the --global flag: typings install dt~es6-shim --save --global

The --global flag replaced the --ambient flag in typings v1.0. It would be good for them to update the alert-warning box with this information.

For reference:

The --global flag tells Typings to accept type definitions that are "global" in nature. Currently, DefinitelyTyped typings are all "global". (src)

G Inc.
G Inc.
~ 8 years ago

IMO, it's much easier to get it all working with Webpack, rather than with SystemJS. Just my preference though.

I second this preference. I understand they were trying to limit the videos to focus on TypeScript, but I suspect that many viewers–particularly people brand new to TypeScript–may have been lost in the weeds of getting everything set up properly.

This is more of an issue with how new TypeScript is and how much of it's ecosystem is still in flux (you'll see that this video series is less than two weeks old yet multiple parts of it are already outdated). For what they had to work with, it's a good starter series.

G Inc.
G Inc.
~ 8 years ago

It looks like symbol-observable is installed with rxjs automatically. However, you are correct in that I did have to add it to the "packages" object as well as "map".

An interesting add-on to this: if you include a "main" file for the "rxjs" package as "Rx.js", in main.ts you are able to say

import * as Rx from "rxjs";

Which allows you to write

Rx.Observable.interval(4000).subscribe(x => console.log(x));

Without having to import anything else from "rxjs".

Sequoia McDowell
Sequoia McDowell
~ 8 years ago
  1. How are RX.js types loaded/accessed from webstorm? Your .tsconfig.json excludes node_modules... what's going on here?
  2. Why are you not getting code-hinting when you use RX types?
Akshar Patel
Akshar Patel
~ 8 years ago

Thanks! This helped me out.

Cristian
Cristian
~ 8 years ago

Thanks!

John Lindquist
John Lindquistinstructor
~ 8 years ago
  1. tsconfig.json excludes is simply telling the TypeScript compiler to not compile files in node_modules
  2. WebStorm has recently updated to support code-hinting based on the RxJS project structure.
John Lindquist
John Lindquistinstructor
~ 8 years ago

Yes, Webpack hides a lot of what is really happening behind whichever loader you're using. So many people never learn (or simply never need to learn) that TypeScript compiles to a module format then you need to set up your own loader. I think it's an important distinction to understand, even if you don't need to deal with it because Webpack handles it so nicely.

Jason
Jason
~ 8 years ago

I ran into an issue where current beta (5 10) of RXJS was causing an error. When I specified beta 6, issue was resolved. See this thread for a similar issue: https://github.com/IgorMinar/new-world-test/issues/13

Yuri Kushch
Yuri Kushch
~ 8 years ago

Take into account that you should also add a global flag in order to install es6-shim
typings install dt~es6-shim --save --global

Alberto
Alberto
~ 8 years ago

I'm having issues working with Typescript. My setup and versions are: package.js - rxjs": "^5.0.0-beta.6" tsconfig.json - "files": ["main.ts"] main.ts - Contains only this two lines: import {Observable} from 'rxjs/Observable'; Observable.fromArray([1, 2]); And complains about not finding module "rxjs/Observable".

What am I missing?

Ningze
Ningze
~ 7 years ago

I got an error when I put "Rx.Observable.timer(1000).subscribe( x => console.log(x) );" in main.ts
The error is : system.src.js:5031 Uncaught (in promise) Error: SyntaxError: Unexpected token < at Object.eval (http://localhost:8080/dist/main.js:3:10) at eval (http://localhost:8080/dist/main.js:16:4) at eval (http://localhost:8080/dist/main.js:17:3) Evaluating http://localhost:8080/node_modules/rxjs Evaluating http://localhost:8080/dist/main.js Error loading http://localhost:8080/dist/main.js

I compare the code line by line, but still cannot make it run. I think there is something wrong with es6-shim , I run "typings install dt~es6-shim --save --global " to install es-shim .

Wenyuan Sun
Wenyuan Sun
~ 7 years ago

I got the same error as you, and I solve it by adding "main": "Rx" to packages configuration, so it's like this: "rxjs": { "defaultExtension": "js", "main": "Rx" }

Stephen James
Stephen James
~ 7 years ago

This one worked for me - thanks.

alex goretoy
alex goretoy
~ 7 years ago

this command worked for me to install es6-shim typings

typings install es6-shim --save --global --source dt
Kevin
Kevin
~ 7 years ago

This should probably be clarified at the very bottom of the video or the instructions edited, IMO; this took me some time to resort to for a close friend in order for them move on with me to support them

Tre' Codez
Tre' Codez
~ 7 years ago

Thanks so much for the typings api info message.

Amit Erandole
Amit Erandole
~ 6 years ago

I got the same error as you, and I solve it by adding "main": "Rx" to packages configuration, so it's like this: "rxjs": { "defaultExtension": "js", "main": "Rx" }

This worked for me at the root level of package.json Also import { Observable } from "rxjs"; started working

shraddha213408
shraddha213408
~ 5 years ago

I get an error on Rx.Observable.interval(1000).subscribe(x => console.log(x)); Error : rc/main.ts(5,15): error TS2339: Property 'interval' does not exist on type 'typeof Observable'. src/main.ts(5,40): error TS7006: Parameter 'x' implicitly has an 'any' type. ../../../../../node_modules/rxjs/internal/types.d.ts(35,84): error TS2304: Cannot findname 'Iterable'. ../../../../../node_modules/rxjs/internal/types.d.ts(39,6): error TS2304: Cannot find name 'Symbol'.

My SystemJS config looks like below: System.config({ packages: { "dist": { "defaultExtension": "js", "main": "main" }, "rxjs": { "defaultExtension": "js", "main": "Rx" } }, map: { "lodash":"https://npmcdn.com/lodash@4.11.1", "rxjs": "node_modules/rxjs" } });

    System.import("dist");
shraddha213408
shraddha213408
~ 5 years ago

However when I use

import * as Rx from 'rxjs';

Rx.timer(1000).subscribe(x => console.log(x));

I get error only about Iterable and Symbol.

Markdown supported.
Become a member to join the discussionEnroll Today