Friday 22 July 2016

Creating a TypeScript Workflow with Gulp

TypeScript provides a lot of great functionality that lets you leverage many of the features available in ES6 today but how do you get started using it in your favorite editor? If you’re using Visual Studio or WebStorm then TypeScript support can be used directly and everything happens magically without much work on your part. But, if you’re using Sublime Text, Brackets, Atom, or another editor you’ll have to find a plugin to compile .ts files to JavaScript or create your own custom workflow.

While several plugins exist to compile TypeScript and even provide code help as you’re writing TypeScript code in different editors, I generally prefer to use my own custom workflow. There are multiple benefits associated with going with this approach including the ability to standardize and share tasks across team members as well as being able to tie the workflow into a custom build process used in continuous integration scenarios. In this post I’ll walk through the process of creating a custom TypeScript workflow using Gulp (a JavaScript task manager). It’s a workflow setup that my friend Andrew Connell and I created when we recently converted anapplication to TypeScript. Throughout the post you’ll learn how to setup a file named gulpfile.js to compile TypeScript to JavaScript and also see how you can “lint” your TypeScript code to make sure it’s as clean and tidy as possible.

Getting Started Creating a Custom TypeScript Workflow

I talked about using Gulp to automate the process of transpiling ES6 to ES5 in a previous post. The general process shown there is going to be used here as well although I’ll be providing additional details related to TypeScript. If you’re new to Gulp, it’s a JavaScript task manager that can be used to compile .ts files to .js files, lint your TypeScript, minify and concatenate scripts, and much more. You can find additional details athttp://gulpjs.com.
Here’s a step-by-step walk-through that shows how to get started creating a TypeScript workflow with Gulp. Although there are several steps to perform, it’s a one-time setup that can be re-used across projects. If you’d prefer to use a starter project rather than walking through the steps that are provided in this post then see the project at https://github.com/DanWahlin/AngularIn20TypeScript or download the project associated with the exact steps shown in this post here

Creating the Application Folders and Files

  1. Create a new folder where your project code will live. You can name it anything you’d like but I’ll call ittypescriptDemo in this post.
  2. Create the following folders inside of typescriptDemo:
    • src
    • src/app
    • src/js
  3. Open a command-prompt in the root of the typescriptDemo folder and run the following npm command (you’ll need to have Node.js installed) to create a file named package.json
  4. npm init
  5. Answer the questions that are asked. For this example you can go with all of the defaults it provides. After completing the wizard a new file named package.json will be added to the root of the folder.
  6. Create the following files in the typescriptDemo folder:
    • gulpfile.js
    • gulpfile.config.js
    • tslint.json


Installing Gulp, Gulp Modules and TSDimage

  1. Now let’s get Gulp installed globally on your machine. Open a command-prompt and run the following command:
  2. npm install gulp –g
  3. Open package.json and add the following devDependencies property into it. The location of the property in the file doesn’t really matter but I normally put it at the bottom. A sample package.json file with the dependencies already in it can be found at https://github.com/DanWahlin/AngularIn20TypeScript

    Note: The module versions shown here will certainly change over time. You can visit http://npmjs.org to find the latest version of a given module. 
  4. "devDependencies": { 
        "gulp": "^3.8.11", 
        "gulp-debug": "^2.0.1", 
        "gulp-inject": "^1.2.0", 
        "gulp-sourcemaps": "^1.5.1", 
        "gulp-tslint": "^1.4.4", 
        "gulp-typescript": "^2.5.0", 
        "gulp-rimraf": "^0.1.1" 
    }
    
  5. Ensure that your command window path is at the root of the typescriptDemo folder and run the following command to install the dependencies:

    npm install
  6. The http://definitelytyped.org site provides a Node.js module named tsd that can be used to install TypeScript type definition files that are used to provide enhanced code help in various editors. Install thetsd module globally by running the following command:

    npm install tsd@next -g
  7. Run the following command:

    tsd init
  8. Open the tsd.json file that is generated in the root of typescriptDemo and change the following properties to include “tools” in the path as shown next:

    "path": "tools/typings","bundle": "tools/typings/tsd.d.ts"
  9. Let’s use tsd to install a TypeScript definition file for Angular (an angular.d.ts file) and update the tsd.jsonfile with the Angular file details as well. Run the following command:
  10. tsd install angular --save 
    Note: You can install additional type definition files for other JavaScript libraries/frameworks by running the same command but changing the name from “angular” to the appropriate library/framework. Seehttp://definitelytyped.org/tsd for a list of the type definition files that are available.
  11. Let’s now install the jQuery type definition as well since the Angular type definition file has a dependency on it:

    tsd install jquery --save
  12. If you look in the typescriptDemo folder you’ll see a new folder is created named tools. Inside of this folder you’ll find a file named typings that has an angular/angular.d.ts type definition file and ajquery/jquery.d.ts file in it. You’ll also see a file named tsd.json.
  13. Create a file named typescriptApp.d.ts in the typescriptDemo/tools/typings folder. This file will track all of the TypeScript files within the application to simplify the process of resolving dependencies and compiling TypeScript to JavaScript.
  14. Add the following into the typescriptApp.d.ts file and save it (the comments are required for one of the Gulp tasks to work properly):
//{
//}


Creating Gulp Tasks

  1. Open https://github.com/DanWahlin/AngularIn20TypeScript/blob/master/gulpfile.config.js in your browser and copy the contents of the file into your empty gulpfile.config.js file. This file sets up paths that will be used when performing various tasks such as compiling TypeScript to JavaScript.
  2. Open https://github.com/DanWahlin/AngularIn20TypeScript/blob/master/gulpfile.js in your browser and copy the contents of the file into your empty gulpfile.js file. This creates the following Gulp tasks:

    gen-ts-refs: Adds all of your TypeScript file paths into a file named typescriptApp.d.ts. This file will be used to support code help in some editors as well as aid with compilation of TypeScript files.
  3. ts-lint: Runs a “linting” task to ensure that your code follows specific guidelines defined in the tsline.js file.
    compile-ts: Compiles TypeScript to JavaScript and generates source map files used for debugging TypeScript code in browsers such as Chrome.
    clean-ts: Used to remove all generated JavaScript files and source map files.
    watch: Watches the folder where your TypeScript code lives and triggers the ts-lint, compile-ts, and gen-ts-refs tasks as files changes are detected.
    default: The default Grunt task that will trigger the other tasks to run. This task can be run by typing gulpat the command-line when you’re within the typescriptDemo folder.
  4. Open https://github.com/DanWahlin/AngularIn20TypeScript/blob/master/tslint.json in your browser and copy the contents of the file into your empty tslint.js file. This has the “linting” guidelines that will be applied to your code. You’ll more than likely want to tweak some of the settings in the file depending on your coding style.

Compiling TypeScript to JavaScript

  1. Now that the necessary files are in place (whew!), let’s add a test TypeScript file into the application folder and try to compile it to JavaScript. Create a file named customer.ts in the typescriptDemo/src/appfolder.
  2. Add the following code into the customer.ts file:

    class Customer {
        name: string;
    
        constructor(name: string) {
            this.name = name;
        }
    
        getName() {
            return this.name;
        }
    }
    
  3. Run the following command in your command window (run it from the root of the typescriptDemofolder):

    gulp
  4. You should see output that shows that the tasks have successfully completed. 
  5. Open the src/js folder and you should that two new files named customer.js and customer.js.map are now there.
  6. Go back to customer.ts and change the case of the Customer class to customer. Save the file and notice that the gulp tasks have run in the command window. You should see a tslint error saying that the case of the class is wrong.
  7. Your Gulp/TypeScript workflow is now ready to go. 

Conclusion

In this post you’ve seen the steps required to create a custom TypeScript workflow using the Gulp JavaScript task runner. Although you may certainly want to tweak some of the settings and tasks, the steps shown here should help get you started using TypeScript in your applications.

In case you missed it earlier in the post, a project that has all of the steps already completed can be found athttps://github.com/DanWahlin/AngularIn20TypeScript. You can also find the exact setup discussed in this posthere (just run npm install to get the required modules for the project).

Saturday 16 July 2016

Angular2 TypeScript Gulp and ExpressJS


Let’s get started. You’ll need NodeJS for this project. Make sure you have npm installed as well.
You’ll need some global tools too. You might need to run these as sudo or “Run As Administrator” if you’re using windows.
  • typescript is our global typescript compiler
  • gulp is a build tool that’s crazy popular now and will help us create beautiful expressive build commands
  • tsd is a package manager for downloading TypeScript definition files. We’ll primarily use this for expressjs

Base Project Setup

Create a new directory and install some dependencies.
Now in your package.json file copy the following dependencies in:
And also these:
Let’s get all the packages that that we need by running:
We’ll have 2 different folders inside out project one for front-end stuff and one for backend stuff. In addition let’s create a file called “gulpfile.js“. This will be our build file.
Our directory will look something like this:

Server Setup

Inside the server folder we’re going to create a tsconfig.json file. This tells our typescript compiler some information about how to compile our .ts extension files. You can read more about tsconfig.json files here.
Let’s create the tsconfig.json in “/server” with the following contents.
In our server directory. We’ll need to start a typescript definition file.
Now we’ll install express’s typescript definition with:
Your server folder should look something like this:
The typings folder should have all the definition files that express needs.
Now let’s create our server.ts file. This a basic ExpressJS server in TypeScript.
  • This server will run on port 3000 unless given an environment variable about the port. This is great if you’re deploying to Heroku or Azure websites
  • All routes render the “index.html” file that we will put in the client folder.
  • I’ve used path.resolve here for all you windows developers.
  • I’ve exposed a folder called “/app” and “/libs” as static public directories. “/app” will house all of our built Angular2 code. “/libs” will house all of the dependencies that we should include before our app starts. These folders don’t exist yet but don’t worry since we will take care of them when we get to building the project.
That’s all it takes to setup the back-end server. You can extend whatever you’d like with your standard Express app like API end-points.

Moving on to the Front-End

In the “/client” folder, create an “index.html” file and put the following contents in it:
The file is the basic entry HTML file for our angular app. As you notice, we’ve included the scripts in the “libs” folder. This is the same folder that we’ve made public in the server setup section. We’ll include some important scripts that we’ll need to get Angular2 working like Angular-Polyfills, SystemJS, Router etc…
The second part is that we have setup “SystemJS”. To keep this tutorial small and easy to digest, I’ll avoid a large overview of what it does. SystemJS allows us to load module-based scripts in the browser.  We configure SystemJS to note that our Angular2 app (which is placed the “app” folder”) is a package that has a default extension. Then when the package is loaded, we tell SystemJS to start our Angular2 application in the “import” method.  SystemJS is a large topic for another day, so if you’d like to know more then please visit: https://github.com/systemjs/systemjs
When developing an Angular2 App in TypeScript, you should include it’s own specifictsconfig.json seperate from your server tsconfig.json.
In the client folder you should create another tsconfig.json file with the following contents:

Finally some Angular2 code

Our Angular2 code will all be in client/app folder. Let’s create the bootstrap.ts file that SystemJS will call to get our Angular2 app up and running.
So there are a lot of things happening here:
We are importing some key functions and classes into our bootstrap.ts file. These are all inputs for angular2’s bootstrap function.
In our gulpfile.js which is in the root of the project let’s add some build code.
First let’s include our packages.
Next let’s create a task called buildServer.
This task takes our tsconfig.json and assumes that the server folder is a TypeScript project. Then it tells it to build all the files in that folder using that tsconfig.json and then dump the built js files into the same folder. Server files don’t need concatenation so it’s totally okay not to concatenate them.
You can run this task by navigating to the root directory and running
Then you should see some files in the buildServer directory:

Front-End setup

Now that we’re done with the backbone of the project, we need to start on the client.
Go to the client folder and create an index.html and a tsconfig.json
The tsconfig.json is exactly the same as before:
Now in the index.html
There’s a lot of information going on here.
First we need to give Angular2 a good base href to grab on to. This is important for routing. I set the base to the current root of the URL with:
We exposed our node_modules folder publically and proceed to tell the browser to pull the angular framework into the head. We’ll need SystemJS as well:
SystemJS is a tool to help us modularize JavaScript code. The Angular team looks like they heavily prefer using SystemJS, so let’s start early while we can. Angular2 heavily uses RxJS v5 and you’ll more than likely import it into your files. I’ve taken the liberty to show you how SystemJS can map a specific import to a module.
Finally, we’ll need to import our app.js file. (We’ll create this soon) At this point you can test to see if the server is working by calling the server code we just built.
You can now open your browser to “http://localhost:3000” and you should see a “loading” text.

Angular2 code

Inside the client folder, create another folder called “app”. This will house all of our Angular2 application code.
Inside app, create an app.ts file:
The first part we import our modules and the objects and classes that we want. Notice that TypeScript supports ES6 module loading. We import Component, which allows us to annotate our classes with angular2 information. It gives the Angular2 runtime a lot of information about which directives to use, which selector to attach to and the inner-html inside the component.
Next we have to tell the Component about the application class. We make it available to other modules by dictating it with the “export” identifier.
Next, we call the angular2 bootstrap method which tells Angular2 to initialize our app with some dependencies.
The bootstrap method also allows us to specify how we want Angular2 to handle routing. I prefer routes not to have the “#” navigation system and opt in for HTML5 routing.
In our server code, we told express that we want to route all uncaught routes to our index.html file. Recall:
Thus, this will tell our Angular2 runtime to handle all the routing.

Creating our components.

We’ll create 2 stub components. They’ll have minimal information but they’ll get the point across. The two components will be home and about.
In our app folder. Create a folder called “components”. And inside that create 2 directories “home” and “about”. Then create 2 files for each component: HomeComponent.ts and AboutComponent.ts
The files should be here.
In HomeComponent.ts
We’ll create a basic component:
As you can see we’re demonstrating some simple mechanisms of Angular2 by passing some code data to our HTML by manipulating the property “titleName”.
In LoginComponent.ts, we’ll do pretty much the same thing:
Now let’s hook the two Components up by routing
Back in the app.ts file let’s configure the routes:
This should give us our proper routing!

Angular Tutorial (Update to Angular 7)

As Angular 7 has just been released a few days ago. This tutorial is updated to show you how to create an Angular 7 project and the new fe...