Introduction to TypeScript modules
Web sites are turning into very complex applications, and the code complexity increases. You need to track the dependencies between JS files and include them in the right order, otherwise the website won't work. Testing is also more complicated as the application grows.
Modules help you segmenting your application. Indeed, modules allow you to create small units of independent and reusable code. Plus, modules know their dependencies, so they can load them when needed in the right order. Let's see how to use modules in TypeScript!
#How to use modules in TypeScript?
In TypeScript, a module is a file containing values, functions, or classes. You can make some of them public, i.e. visible from other modules, by exporting them. Non exported objects are private. Let's create a very simple math module with a single exported function!
First, create a file named math.ts
:
// public because of the export keyword
export function add(a: number, b: number): number {
log(`${a} + ${b}`);
return a + b;
}
// private
function log(message: string): void {
console.log(message);
}
Then, you can consume the math module from another module. The import
keyword allows using the exported functions of a module. In this case, we want to use the add
function from the math
module. Let's create a new file named main.ts
:
// We want to use the add function from the math module
import { add } from "./math";
// Use the add function as if it was in the global context
console.log(add(1, 2));
If you want to use all the exported functions of a module, you can use the *
syntax:
// Import the math module as a *namespace*
import * as math from "./math";
// Use the add function in the namespace math
console.log(math.add(1, 2));
// math.log(""); // error: log is not exported
You'll find the complete syntax in the documentation: https://www.typescriptlang.org/docs/handbook/modules.html
#How to include the JS files in the HTML page?
You now know how to create a module in TypeScript, but how to use them in your html files.
There are many module formats with advantages and disadvantages: AMD
, CommonJS
, UMD
, System
and the native ES6
modules. TypeScript supports all of them, so it's all up to you. The ES6 format is not well supported by the browsers yet, so you should use another format. In this post, I'll use SystemJS
as it is popular.
First, you need to configure TypeScript to output this format. Open the tsconfig.json
file and set the following line:
{
"compilerOptions": {
"module": "system"
}
}
Then, add SystemJS
to your page. You can get it from cdnjs:
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.20.19/system.js" integrity="sha256-HCJlhCZ21EKx0Wo6wCF+rbeBHlVlOSJccd4zTQe2TNw=" crossorigin="anonymous"></script>
Finally, instruct SystemJS to load your main module. By default, when SystemJS needs to download a file, it uses the name of the module (i.e. the name used in the import statement). In our case, the name of the module is not the name of the file. We need to add the suffix .js
to the module name. We can configure SystemJS to do it automatically:
<script>
// Instruct SystemJS to add the js extension to the module name to compute the final file name
System.config({
packages: {
'./': {
defaultExtension: 'js'
}
}
});
// Load the main module
SystemJS.import("main");
</script>
If you open the web page, you should see the following output in the console:
And in the network tab, you should see the main.js
and math.js
are downloaded while they are not directly included in the page. The dependencies are downloaded automatically by SystemJS, so you don't need to manage them anymore:
#Conclusion
It's very simple to start using modules with TypeScript and SystemJS! Modules will help you in releasing cleaner applications, and in understanding the dependencies between the components. While native modules are not well supported yet, you can use modules with SystemJS
or requireJS
now and migrate to native modules once the support will be better.
Do you have a question or a suggestion about this post? Contact me!