NodeJS, Web-Express, and TypeScript from scratch
Over the past year I've been spending my time contracting for a
company in Norway. Now that project is completed it is time for me to
start playing again, so I thought I'd pick up an old Node Express
project. This time I intend to use TypeScript instead of Javascript. I'd
also like to write unit tests and dependency injection - both are
something I'm very familiar with in the C# world, but not in Node. I'm
going to use this blog to record what I did; I will undoubtedly revisit
some of these posts and make changes as I learn.
In this first blog I intend to cover how to get up and running with Node, Express, and WebStorm (optional) from a fresh installation of Ubuntu Linux.
The first thing we need to do is use apt-get to install Node.
In this first blog I intend to cover how to get up and running with Node, Express, and WebStorm (optional) from a fresh installation of Ubuntu Linux.
The first thing we need to do is use apt-get to install Node.
sudo apt-get install nodejsI've noticed that some Linux apps will look for a command "node" and others will look for "nodejs", so after installing I want to make an alias so that both commands will work.
cd /usr/binNext we need to install the package manager for Node. This allows us to reference 3rd party libraries (such as the Express web server) in our applications. It also keeps track of which specific versions we have used for different applications we have developed, so it's possible to have different apps running on different library versions and upgrade them independently of each other.
sudo ln -s nodejs node
sudo apt-get install npmWith npm installed we can now get start to import our Node dependencies. These dependencies are used for getting a project up and running very quickly and so need to be installed as global packages, which means they will be available anywhere on your Linux installation by using the npm command. To install an npm package globally we need to use the -g option.
sudo npm install -g gulpGulp and Yo are both task automation applications. Gulp is used to compile (transpile) our TypeScript into JavaScript and then run our test web server, we can also use it to run automated unit tests. Yo is used to create the skeleton app that we will develop further, and generator-express-typescript is the template it will use to create it. So, make a folder, cd into it and type
sudo npm install -g yo
sudo npm install -g generator-express-typescript
yo express-typescriptYo will ask if you wish to use gulp or grunt, choose gulp; when asked if you wish to create a Dockerfile select Yes.
Once the skeleton for our new application has been created type
gulpThe gulp command will look for a file named gulpfile.js - this is where we can create named tasks to run from the command line. If no command is specified, gulp will run the default task in the file, which is named 'default'.
You will see output similar to this
[10:51:12] Using gulpfile ~/source/yourapp/gulpfile.jsYou can now see your skeleton app by navigating to http://localhost:3000
[10:51:12] Starting 'clean'...
[10:51:13] Finished 'clean' after 1.22 s
[10:51:13] Starting 'ts'...
[10:51:16] Finished 'ts' after 2.29 s
[10:51:16] Starting 'server:start'...
[10:51:16] Finished 'server:start' after 19 ms
[10:51:16] Starting 'default'...
[10:51:17] Finished 'default' after 942 ms
[10:51:17] Development server listening. (PID:52108)
Optional - Downloading WebStorm
As this part is optional I won't explain the steps. Downloading and running software should be simple enough.- Download webstorm to your Downloads folder
- cd ~/Downloads
- tar -xvcf WebStorm[the rest of the download's file name]
- sudo mv ./WebStorm-....... /opt/webstorm
- /opt/webstorm/bin/webstorm.sh
Using strongly typed libraries
One of the benefits of using TypeScript instead of JavaScript is that it is strongly typed. The problem is that not all libraries are written in TypeScript and so no type information is provided by default. Thankfully the Definitely Typed project has a huge collection of definition files to help us. They are implemented as a set of interfaces; TypeScript interfaces don't transpile to JavaScript, they are just for type safety checking.By default the Yo express-typescript template adds some of these files, but it uses an out-of-date method of referencing them. So, the next thing we will do is to remove the strongly typed definition files for this project in order to add the newer ones using the new recommended approach.
- Delete the tsd.json file
- Delete the typings folder (type rm -r typings)
- Edit the /app.ts and /routes/index.ts files
sudo npm install -g typingsNow make sure you are in the root of your project and initialise typings for it.
typings initNow instead of downloading Definitely Typed files and putting them somewhere in our project's sources we can search for libraries using the typings search command, and install them using the typings install command.
If you look in one of your project's TS files using an editor like WebStorm you will see that the require keyword is no longer recognised. This is because the typings folder we deleted contained library definitions to give us strongly typed information for Node itself. The first thing we want to do is to correct that. Type in the command
typings search nodeThis will show you all strongly typed definition files that match the search phrase. An important thing to pay attention to is the Source column. When installing one of these libraries we need to prefix its name with the value in that column, separated with a tilde. For example, the "node" entry has a source "dt", so it's fully qualified name for installing is "dt~node".
Whenever we are using the Definitely Typed libraries (source = dt) we need to add the --global option to our command line so typings knows to resort to those legacy files. We also want to include the --save option so that our typings.json file is updated.
typings install --global --save dt~nodeNow if you look back at one of your TS files you should see the require keyword is now recognised!
By looking through dependencies section of the package.json file we can see which libraries Yo has specified are needed for this skeleton site, and install the typings for each of them. To save you some time, just copy/paste the following lines into your terminal window.
typings install --global --save dt~express (fixes Request/Response)Now, some of the packages in the package.json are listed under the devDependencies section. When installing these we need to use --save-dev rather than just --save, this will ensure they go into the development environment's requirement list rather than the runtime list.
typings install --global --save dt~express-serve-static-core
typings install --global --save dt~serve-static
typings install --global --save dt~mimetypings install --global --save dt~q
typings install --global --save dt~underscore
typings install --global --save dt~mongoose
typings install --global --save dt~serve-favicon
typings install --global --save dt~morgan
typings install --global --save dt~cookie-parser
typings install --global --save dt~body-parser
typings install --global --save-dev dt~shouldNote that the final dependency "debug" does not have the --global option specified. This is because when you do a typings search for "debug" you will see there are two entries. Once has a source of npm, and the other has a source of dt (Definitely Typed project). The npm one is newer so we want to use that one, and since npm is the default source we don't need the prefix~ before the name, and we don't need to specify --global to tell typings it needs to look through the Definitely Typed repository.
typings install --global --save-dev dt~superagent
typings install --global --save-dev env~mocha
typings install --save-dev debug
Comments