TypeScript–Surprisingly Simple, Extraordinarily Powerful– Part 5
Modules
Modules help us separate different units of work in an application. It basically allows us to follow the “separation of concerns” concept on the client-side. This separation of concern helps us achieve testability, SOLID principle, and reuse. Each module can be in separate files and have a specific role.
Modules are identified by the keyword “module”. All TypeScript code is inside an implicit module if not defined inside a “module” keyword. The implicit module is a global module that exits at a windows level.
module BusinessLayer {
}
Here we have defined a BusinessLayer module that may contain all the fields and functions required for executing the business part of the application. We can import modules, export features from other modules.
Internal Modules
The module defined above “BusinessLayer” is an internal module i.e. all the fields, functions inside this module will be available only in the business layer module and anyone tries to access outside will not be able to.
Here we see that we are not able to access age and temp outside of the module “hello”.
Export keyword: This keyword allows us to make fields, functions defined inside a module accessible to places outside the module. In the above example, the class test is accessible outside the module because we have marked it with the “export” keyword.
We can extend a module simply by using the same module name in the same or different files. then all the classes, interfaces will be part of one common module.
Referencing modules: Because modules help us separate the code to provide us with better organization, there is a need to access modules in each other depending on the dependencies. How do we do that???
We do this with adding references for the module which we want to have access to but adding ///reference to a file. This way we will have access to module referenced and its members (if they have been decorated with “export” keyword).
Here we see that module child references class Circle and method temp from module shapes and hello respectively. Both these modules lie in chapter.ts file and that reference has been added at top of the page.
The biggest drawback of this approach is that we must be aware of dependencies for each module because the dependencies should be loaded before the module. This means when adding script tags in the HTML file we need to be very careful about the order of the scripts defined there. Now, this can be fine for small projects but as we start creating industrial-scale projects it becomes difficult to manage.
Now we can do this with the ASP.net MVC bundling technique as well on the server-side but the issue of the order will still remain.
External Modules
External modules come in where we are creating large projects which multiple ts/js files and they have dependencies on each other. In these types of projects, we can not keep track of script dependencies by just adding them on an HTML page or in the MVC project in the order that is required. For these scenarios, we have AMD (asynchronous module definition) that allows your modules to be loaded asynchronously on an as-needed basis.
So how do we import external modules,
import ds = require(“chapter6”);
Here we use the “import” keyword and “require” js to load the “chapter6” module in the current module.
NOTE: whenever we see a keyword “import” that means the external module
Below is the full example of implementing AMD in TypeScript. Make sure we have “require.js” added into the project as AMD will use requirejs to defined dependencies
First, we have a file which just contains a class and does not have any dependencies
We see that in JavaScript, it was automatically defined using” require”. This has happened because we have added the keyword “export” for the interface and class.
Now, we will have a TypeScript file that will use the above file and call its functions.
Here we see at top of the page we are using “import” which basically imports the DataService class here. If you see on the JavaScript side, you will be able to make out the dependencies added with the name “ds”.
Once we have imported the required module, we will be able to access all the functions which have been marked with the “export” keyword. In this way, we can create dependencies for each file, just by adding required “import” statements.
All these are then tied using requirejs configuration which helps us overcome the drawback we saw in internal modules i.e. managing the dependencies of scripts in the HTML page. Using require js we just need one script tag of require which will point to the startup script file which in turn will start loading scripts based on their respective dependencies.
This main file is shown below
Here we see the basic configuration that is required for the main file. It just currently has 1 dependency for which it calls a “run” method which kicks off other parts of the application. “run” function is defined in the “chaper6b” module as can been seen in the previous screenshot.
Also, below is the script tag which is just required.
Now, this does make our life very easy.
Next Up: Use TypeScript with Jquery, Knockout and other libraries
Post a Comment