Before I learned a little bit of how TypeScript modules work if I wanted to use a js library like jQuery I would simply add a script tag referencing that library, but now that I'm using TypeScript I often find examples like this :
import * as $ from 'jquery'
But jQuery is not TypeScript module, so how does this work? How should I add a external non-typescript library to my modules?
tsconfig.json
Explicitly telling typescript to use the AMD format (I chose this one over commonjs because I read that since AMD loads modules asynchronously, it is more appropriate for web applications)
{
"compilerOptions": {
"sourceMap": false,
"target": "es5",
"module": "amd",
"outDir": "Scripts"
},
"exclude": [
"node_modules",
"wwwroot"
]
}
To install the type definitions I use typings
typings install dt~jquery --global --save
Having mentioned what I'm actually using, what I don't understand is how RequireJs is able to find third-party libraries when I'm only specifying which file to load (in this case app.js) after require.js loads
<script data-main="Scripts/app/app" src="Scripts/require.js"></script>
I tried adding a script tag for the jquery.js file before and after the script tag for require.js but it didn't work. So how am I suppose to tell require.js "look I need this x file, go and load it for me"?
I'm asking this because if I understood correctly the purpose of type definitions, they only exist to give us type checking and nothing more, we still need to add the actual library we want to use.
So in the end this is what I ended up doing:
I) According to this page http://requirejs.org/docs/api.html#data-main, data-main is only intended for use when the page just has one main entry point and it will fail when you require other js files, so the following configuration should be used instead:
<script src="~/Scripts/require.js"></script>
<script>
require.config({
paths: {
"lodash": "Scripts/lodash"
}
});
require(["Scripts/app/js/app"]);
</script>
Here I'm explicitly telling require.js where to find the source code for the library that I want to use, in this case lodash.js. Only once all the path mapping is done, I instruct require to load app.js
II) app.ts
/// <reference path="../../typings/index.d.ts" />
import * as _ from "lodash";
console.log('Using Lodash: ' + _.snakeCase("For Whom the Bells Toll");
For the type definition to work properly you have to include a reference tag
And that's it.
To test if everything is working, all I have to use is to check the console and see that everything works as expected:

One thing that is still not very clear to me is how all the magic works behind the scenes, but taking a look at the js code that is generated for app.js, I guess that the third dependence "lodash" is looked for among all the paths specified in require.config
define(["require", "exports", "lodash"], function (require, exports, _) {
"use strict";
console.log('Using Lodash: ' + _.snakeCase("For Whom the Bells Toll"));
});
Oh, and one last thing, if you don't want to have to include a reference tag in your ts files whenever you need to use a d.ts file, you can add the path to your index.d.ts in the tsconfig.json file like this:
{
"compilerOptions": {
"sourceMap": false,
"target": "es5",
"module": "amd",
"outDir": "js"
},
"include": [
"src/**/*.ts",
"../typings/index.d.ts"
]
}
First, I'll point out that TypeScript doesn't force you to use jQuery as a module. You could technically use it as a global.
You're right that jQuery is not written as a TypeScript module. But there are two things to take away:
.d.ts files). These files tell TypeScript about JavaScript code that already exists, so that you can get better tooling and error detection.(2) applies even if you don't decide to use modules. But with that combination, you can use TypeScript to consume jQuery the way you specified.
First, let's get the declaration files for jQuery:
npm install -S @types/jquery
Off the bat, you should be able to reference jQuery in TypeScript. If not, add "jquery" to the "types" field in your tsconfig.json as follows:
{
"compilerOptions": {
"types": ["jquery"]
}
}
At this point, as long as your file doesn't use any imports/exports, you can use jQuery the same way you've always used it.
If you do this, make sure you still use a <script> tag in your HTML for jQuery.
Now, you can still decide to use modules - in which case, this becomes more involved, and you'll need to choose the module system you want to use.
In general, it is considered best practice to use modules in new JavaScript, but it can feel a little overwhelming. This is not so much a problem with TypeScript as it is with how practices in the ecosystem have surfaced around modules.
If you are using Webpack or Browserify, then add "module": "commonjs" to your compiler options in your tsconfig.json. Then you can just write
npm install -S jquery
And Webpack with ts-loader will take care of the rest. See our guide here for how Webpack can be set up. Note that in the linked setup, you'll still need to use <script> tags for any libraries you decide to add to the externals field.
If you are using Require.js, add "module": "amd" to the compiler options in your tsconfig.json. Require.js requires a bit of configuration to get going, but we have a guide here that uses AMD modules.
You'll have to let Require.js know about where an import to jQuery should be redirected to as so:
This can go in its own .ts file called require-config.ts
declare var require: any;
require.config({
paths: {
"jquery": "Scripts/externals/jquery-3.1.1",
}
});
and then you can add the appropriate script tags to your page:
<script src="./Scripts/externals/require.js"></script>
<script src="./Scripts/app/require-config.js"></script>
<script>
require(["Scripts/app/app"]);
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With