How do I use namespaces with TypeScript external modules?

382down voteaccepted

Candy Cup Analogy

Version 1: A cup for every candy

Let’s say you wrote some code like this:

Mod1.ts

export namespace A {
    export class Twix { ... }
}

Mod2.ts

export namespace A {
    export class PeanutButterCup { ... }
}

Mod3.ts

export namespace A {
     export class KitKat { ... }
}

You’ve created this setup: enter image description here

Each module (sheet of paper) gets its own cup named A. This is useless – you’re not actually organizing your candy here, you’re just adding an additional step (taking it out of the cup) between you and the treats.


Version 2: One cup in the global scope

If you weren’t using modules, you might write code like this (note the lack of export declarations):

global1.ts

namespace A {
    export class Twix { ... }
}

global2.ts

namespace A {
    export class PeanutButterCup { ... }
}

global3.ts

namespace A {
     export class KitKat { ... }
}

This code creates a merged namespace A in the global scope:

enter image description here

This setup is useful, but doesn’t apply in the case of modules (because modules don’t pollute the global scope).


Version 3: Going cupless

Going back to the original example, the cups AA, and A aren’t doing you any favors. Instead, you could write the code as:

Mod1.ts

export class Twix { ... }

Mod2.ts

export class PeanutButterCup { ... }

Mod3.ts

export class KitKat { ... }

to create a picture that looks like this:

enter image description here

Much better!

Now, if you’re still thinking about how much you really want to use namespace with your modules, read on…


These Aren’t the Concepts You’re Looking For

We need to go back to the origins of why namespaces exist in the first place and examine whether those reasons make sense for external modules.

Organization: Namespaces are handy for grouping together logically-related objects and types. For example, in C#, you’re going to find all the collection types in System.Collections. By organizing our types into hierarchical namespaces, we provide a good “discovery” experience for users of those types.

Name Conflicts: Namespaces are important to avoid naming collisions. For example, you might have My.Application.Customer.AddForm and My.Application.Order.AddForm — two types with the same name, but a different namespace. In a language where all identifiers exist in the same root scope and all assemblies load all types, it’s critical to have everything be in a namespace.

Do those reasons make sense in external modules?

Organization: External modules are already present in a file system, necessarily. We have to resolve them by path and filename, so there’s a logical organization scheme for us to use. We can have a /collections/generic/ folder with a list module in it.

Name Conflicts: This doesn’t apply at all in external modules. Within a module, there’s no plausible reason to have two objects with the same name. From the consumption side, the consumer of any given module gets to pick the name that they will use to refer to the module, so accidental naming conflicts are impossible.


Even if you don’t believe that those reasons are adequately addressed by how modules work, the “solution” of trying to use namespaces in external modules doesn’t even work.

Boxes in Boxes in Boxes

A story:

Your friend Bob calls you up. “I have a great new organization scheme in my house”, he says, “come check it out!”. Neat, let’s go see what Bob has come up with.

You start in the kitchen and open up the pantry. There are 60 different boxes, each labelled “Pantry”. You pick a box at random and open it. Inside is a single box labelled “Grains”. You open up the “Grains” box and find a single box labelled “Pasta”. You open the “Pasta” box and find a single box labelled “Penne”. You open this box and find, as you expect, a bag of penne pasta.

Slightly confused, you pick up an adjacent box, also labelled “Pantry”. Inside is a single box, again labelled “Grains”. You open up the “Grains” box and, again, find a single box labelled “Pasta”. You open the “Pasta” box and find a single box, this one is labelled “Rigatoni”. You open this box and find… a bag of rigatoni pasta.

“It’s great!” says Bob. “Everything is in a namespace!”.

“But Bob…” you reply. “Your organization scheme is useless. You have to open up a bunch of boxes to get to anything, and it’s not actually any more convenient to find anything than if you had just put everything in one box instead of three. In fact, since your pantry is already sorted shelf-by-shelf, you don’t need the boxes at all. Why not just set the pasta on the shelf and pick it up when you need it?”

“You don’t understand — I need to make sure that no one else puts something that doesn’t belong in the ‘Pantry’ namespace. And I’ve safely organized all my pasta into the Pantry.Grains.Pasta namespace so I can easily find it”

Bob is a very confused man.

Modules are Their Own Box

You’ve probably had something similar happen in real life: You order a few things on Amazon, and each item shows up in its own box, with a smaller box inside, with your item wrapped in its own packaging. Even if the interior boxes are similar, the shipments are not usefully “combined”.

Going with the box analogy, the key observation is that external modules are their own box. It might be a very complex item with lots of functionality, but any given external module is its own box.


Guidance for External Modules

Now that we’ve figured out that we don’t need to use ‘namespaces’, how should we organize our modules? Some guiding principles and examples follow.

Export as close to top-level as possible

  • If you’re only exporting a single class or function, use export default:

MyClass.ts

export default class SomeType {
  constructor() { ... }
}

MyFunc.ts

function getThing() { return 'thing'; }
export default getThing;

Consumption

import t from './MyClass';
import f from './MyFunc';
var x = new t();
console.log(f());

This is optimal for consumers. They can name your type whatever they want (t in this case) and don’t have to do any extraneous dotting to find your objects.

  • If you’re exporting multiple objects, put them all at top-level:

MyThings.ts

export class SomeType { /* ... */ }
export function someFunc() { /* ... */ }

Consumption

import * as m from './MyThings';
var x = new m.SomeType();
var y = m.someFunc();
  • If you’re exporting a large number of things, only then should you use the module/namespacekeyword:

MyLargeModule.ts

export namespace Animals {
  export class Dog { ... }
  export class Cat { ... }
}
export namepsace Plants {
  export class Tree { ... }
}

Consumption

import { Animals, Plants} from './MyLargeModule';
var x = new Animals.Dog();

Red Flags

All of the following are red flags for module structuring. Double-check that you’re not trying to namespace your external modules if any of these apply to your files:

  • A file whose only top-level declaration is export module Foo { ... } (remove Foo and move everything ‘up’ a level)
  • A file that has a single export class or export function that isn’t export default
  • Multiple files that have the same export module Foo { at top-level (don’t think that these are going to combine into one Foo!)
shareimprove this answer
41
This is a non-answer. The premise that you shouldn’t need or want namespaces for external modules is a faulty one. While the file system is a sort of organization scheme you can kinda use for these purposes, it isn’t nearly as nice for the consumer to have n import statements for using n classes or functions from a given project; especially since it also muddies the naming convention when you are down in actual code. – Albinofrenchy Aug 12 ’15 at 15:48
8
No matter how much one might want it, it’s still not possible. – Ryan Cavanaugh Aug 12 ’15 at 17:25
15
I don’t understand, we are not writing pascal anymore. Since when is organizing using the file system the way to go? – David Feb 23 ’16 at 19:54
5
So, using TypeScript modules, there is no way to wrap all the code I’ve written into one namespace, like my name, or my company name, without having one giant module that contains it all. Is that correct? – Josh Mar 13 ’16 at 18:53
4
You can by having a “wrapper” module that imports and re-exports everything of interest to consumers of your library. But again, using a “namespace” there is not going to provide any value other than forcing another level of indirection for anyone using your code. – Ryan Cavanaugh Mar 14 ’16 at 15:28

Nothing wrong with Ryan’s answer, but for people who came here looking for how to maintain a one-class-per-file structure while still using ES6 namespaces correctly please refer to this helpful resource from Microsoft.

One thing that’s unclear to me after reading the doc is: how to import the entire (merged) module with a single import.

Edit Circling back to update this answer. A few approaches to namespacing emerge in TS.

All module classes in one file.

export namespace Shapes {
    export class Triangle {}
    export class Square {}      
}

Import files into namespace, and reassign

import { Triangle as _Triangle } from './triangle';
import { Square as _Square } from './square';

export namespace Shapes {
  export const Triangle = _Triangle;
  export const Square = _Square;
}

Barrels

// ./shapes/index.ts
export { Triangle } from './triangle';
export { Square } from './square';

// in importing file:
import * as Shapes from './shapes/index.ts';
let myTriangle = new Shapes.Triangle();

A final consideration. You could namespace each file

// triangle.js
export namespace Shapes {
    export class Triangle {}
}

But as one imports two classes from the same namespace, TS will complain there’s a duplicate identifier. The only solution as this time is to then alias the namespace.

import { Shapes } from './square';
import { Shapes as _Shapes } from 'triangle';

// ugh
let myTriangle = new _Shapes.Shapes.Triangle();

This aliasing is absolutely abhorrent, so don’t do it. You’re better off with an approach above. Personally, I prefer the ‘barrel’.

shareimprove this answer
I’m also asking myself the same question. Did you find something relevant to this ? – John-Philip May 23 at 11:12
1
@Koresh Updated answer. I hope it helps. – Jefftopia May 23 at 15:42

Try to organize by folder:

baseTypes.ts

export class Animal {
    move() { /* ... */ }
}

export class Plant {
    photosynthesize() { /* ... */ }
}

dog.ts

import b = require('./baseTypes');

export class Dog extends b.Animal {
    woof() { }
}   

tree.ts

import b = require('./baseTypes');

class Tree extends b.Plant {
}

LivingThings.ts

import dog = require('./dog')
import tree = require('./tree')

export = {
    dog: dog,
    tree: tree
}

main.ts

import LivingThings = require('./LivingThings');
console.log(LivingThings.Tree)
console.log(LivingThings.Dog)

The idea is that your module themselves shouldn’t care / know they are participating in a namespace, but this exposes your API to the consumer in a compact, sensible way which is agnostic to which type of module system you are using for the project.

shareimprove this answer
7
LivingThings.dog.Dog is what you have here. – Corey Alix Oct 10 ’15 at 3:59

Small impovement of Albinofrenchy answer:

base.ts

export class Animal {
move() { /* ... */ }
}

export class Plant {
  photosynthesize() { /* ... */ }
}

dog.ts

import * as b from './base';

export class Dog extends b.Animal {
   woof() { }
} 

things.ts

import { Dog } from './dog'

namespace things {
  export const dog = Dog;
}

export = things;

main.ts

import * as things from './things';

console.log(things.dog);
shareimprove this answer
1
Thanks for this! Just wanted to say that changes to an existing answer should preferably not be posted as new answers: they should either be added as a comment to the existing answer, or (better) should be suggested by suggesting an edit to the answer that you wish to improve. – a3nm Aug 23 ’16 at 22:35

dog.ts

import b = require('./baseTypes');

export module Living.Things {
    // Error, can't find name 'Animal', ??
    // Solved: can find, if properly referenced; exporting modules is useless, anyhow
    export class Dog extends b.Living.Things.Animal {
        public woof(): void {
            return;
        }
    }
}

tree.ts

// Error, can't use the same name twice, ??
// Solved: cannot declare let or const variable twice in same scope either: just use a different name
import b = require('./baseTypes');
import d = require('./dog');

module Living.Things {
    // Why do I have to write b.Living.Things.Plant instead of b.Plant??
    class Tree extends b.Living.Things.Plant {
    }
}

Advertisements
Posted in Node Dot JS | Leave a comment

http://brianflove.com/2016/03/29/typescript-express-node-js/

TypeScript + Express + Node.js

 Reading time ~13 minutes

The Express web application framework for Node.js is arguable one of the most popular solutions for creating web apps built on the async Node.js engine.

Getting started with Express is easy. In this tutorial I will walk through setting up Express + Node.js using the node package manager (npm). We’ll wire up a server in JavaScript and then build the app using TypeScript.

TypeScript 2 Update

If you are ready for TypeScript 2 then head over the TypeScript 2 update on this article: TypeScript 2 + Node.js + Express

Why TypeScript?

I believe that TypeScript has been embraced as the choice language for building next generation web application using ECMAScript 6 (ES6) with strong typing. Strong typing doesn’t necessarily improve the JavaScript that your Node.js server will execute, or the JavaScript that your browser might execute. However, it provides the developer more insight into public and 3rd party APIs as well as reducing the bugs (and development cycle to check for bugs) in the software we are developing.

Let’s Get Started

Let’s spin up our first Express + Node.js server using npm + Javascript.

  1. Download and Install Node.js
  2. Create a package.json file
  3. Install Express
$ mkdir myapp
$ cd myapp
$ npm init

After answering the prompts, a package.json file is created in your myapp directory.

Next, let’s add some information to our package.json file:

  1. Specify the node engine
  2. Create a start script
{
  "name": "myapp",
  "description": "Just for fun",
  "version": "1.0.0",
  "private": true,
  "author": "Brian Love",
  "engines": {
    "node": "~5.6"
  },
  "scripts": {
    "start": "node ./bin/www"
  }
}

Note the engines and scripts properties have been added to the configuration. The engines property is not necessary, but is helpful if you are deploying to the Google Cloud platform. The scripts property is a map of scripts that can be executed using npm.

In this example, we have created a script named start that executes node and provides the initial JavaScript file to execute. In this case I have created a directory in my application called bin, with a file named www (notice there is no extension). This www file is the JavaScript file that is executed by node.js, that will in turn start our Express web application.

Installing Express

Next, let’s install the express package into our application. This is super easy using npm:

$ npm install express --save

After running this command you should see a node_modules folder in your application’s root directory (where you are executing this command). This folder contains all of the node modules that express depends on, as well as the express module. As we build our Express + Node.js application this folder will contain all of the 3rd-party modules that we are using.

If you are using Git make sure you add the node_modules folder to your .gitignore file prior to committing.

Setting Up Express + Node.js

To get started with express we will create a bin/www file that the npm start command will execute.

$ mkdir bin
$ cd bin
$ touch www

From there, open Sublime Text or your favorite editor. We’ll just be writing vanilla JavaScript to get our Express + Node.js web application up and running. Then, once we start coding our app we’ll switch over to TypeScript.

Why not use TS for the server startup? Well, I figure that once I write this code, I’m done. Sounds optimistic, I know. But, in theory I’ll spend the rest of my time working on my app.

The most basic form of the server JavaScript code is below.

#!/usr/bin/env node
"use strict";

//module dependencies.
var app = require("../app");
var debug = require("debug")("express:server");
var http = require("http");

//get port from environment and store in Express.
var port = normalizePort(process.env.PORT || 8080);
app.set("port", port);

//create http server
var server = http.createServer(app);

//listen on provided ports
server.listen(port);

//add error handler
server.on("error", onError);

//start listening on port
server.on("listening", onListening);

The first thing that we are doing is requiring the module “../app”. This refers to a file named app.js that will live in our root folder (under myapp in this example). The app.js file will be created from our TypeScript source file. So, for now, don’t worry about creating this. Just keep in mind that we will be creating an app.js file that bootstrap’s our application.

The app.js file is in the myapp directory, while the www file is in the ./bin directory

Also, you might have noticed that I am calling a function called normalizePort(), which accepts the port value that is retrieved from the environment variable named “PORT”. If this is undefined (a falsey), then the port defaults to 8080. You might not need to worry about this now – but it will be helpful when you launch your app into to the wild. The normalizePort() method was provided as part of the Google Cloud developer documentation, so I take no credit for it.

/**
 * Normalize a port into a number, string, or false.
 */
function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

Further, I also have an onError() function that is called when an uncaught exception is thrown. This, again, was provided by the Google Cloud platform sample from Github.

/**
 * Event listener for HTTP server "error" event.
 */
function onError(error) {
  if (error.syscall !== "listen") {
    throw error;
  }

  var bind = typeof port === "string"
    ? "Pipe " + port
    : "Port " + port;

  // handle specific listen errors with friendly messages
  switch (error.code) {
    case "EACCES":
      console.error(bind + " requires elevated privileges");
      process.exit(1);
      break;
    case "EADDRINUSE":
      console.error(bind + " is already in use");
      process.exit(1);
      break;
    default:
      throw error;
  }
}

There is also a callback function called onListening that is executed once the server has successfully started.

**
 * Event listener for HTTP server "listening" event.
 */
function onListening() {
  var addr = server.address();
  var bind = typeof addr === "string"
    ? "pipe " + addr
    : "port " + addr.port;
  debug("Listening on " + bind);
}

Ok, we have the busy work done. W e have express installed as a node module and we have our start script created. Now, let’s start writing our app using TypeScript.

Install TypeScript Compiler & Linter

Ok, let’s get our TypeScript environment configured for our application. The first thing we need to do is install the typescript compiler. We’ll do this using npm.

$ npm install typescript --save

To compile our TypeScript we will be using the Grunt task runner. So, let’s get it installed, again using npm. Then we’ll create the gruntfile.js file.

$ npm install grunt --save
$ npm install grunt-cli --save
$ npm install grunt-ts --save
$ npm install grunt-tslint --save
$ npm install grunt-contrib-watch --save
$ npm install tslint --save
$ touch gruntfile.js

Open up the gruntfile.js that is located in the root of your application (next to package.json). If you’re unfamiliar with Grunt, check out their website to become familiar with it. I’m not going to dive into Grunt as that is beyond the scope of this tutorial.

The gruntfile.js file is located in the application's root directory, in this example in the myadd directory

Let’s add a task for compiling our TypeScript code. I’ll also be adding a task to lint my TS code, as well as a watch task for automatically compiling and linting my TS after changes are saved. Here is the full gruntfile.js contents to get us started.

module.exports = function(grunt) {
  "use strict";

  grunt.initConfig({
    ts: {
      app: {
        files: [{
          src: ["src/\*\*/\*.ts", "!src/.baseDir.ts", "!src/_all.d.ts"],
          dest: "."
        }],
        options: {
          module: "commonjs",
          noLib: true,
          target: "es6",
          sourceMap: false
        }
      }
    },
    tslint: {
      options: {
        configuration: "tslint.json"
      },
      files: {
        src: ["src/\*\*/\*.ts"]
      }
    },
    watch: {
      ts: {
        files: ["js/src/\*\*/\*.ts", "src/\*\*/\*.ts"],
        tasks: ["ts", "tslint"]
      }
    }
  });

  grunt.loadNpmTasks("grunt-contrib-watch");
  grunt.loadNpmTasks("grunt-ts");
  grunt.loadNpmTasks("grunt-tslint");

  grunt.registerTask("default", [
    "ts",
    "tslint"
  ]);

};

The typescript compiler will look for all files with the .ts file extension located in a src/ directory that we will create. We are also ignoring some common files that might appear in our src folder, such as .baseDir and _all.d.ts. The _all.d.ts file references all of the TypeScript declaration files in my project.

We can manually execute this using the node_modules/.bin/tsc binary executable, or we can create a script in our package.json file to do this for us. So, let’s simply add the following script to package.json. Your package.json file should now look like this:

{
  "name": "myapp",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "grunt": "grunt",
    "start": "node ./bin/www"
  },
  ...
}

Ok – we’re almost there. Next, we need to tell tslint what our lint rules are. Here is what my tslint.json file looks like.

{
  "rules": {
    "class-name": true,
    "curly": true,
    "eofline": false,
    "forin": true,
    "indent": false,
    "label-position": true,
    "label-undefined": true,
    "max-line-length": [true, 150],
    "no-arg": true,
    "no-bitwise": true,
    "no-console": false,
    "no-construct": true,
    "no-constructor-vars": false,
    "no-debugger": true,
    "no-duplicate-key": true,
    "no-duplicate-variable": true,
    "no-empty": true,
    "no-eval": true,
    "no-string-literal": true,
    "no-switch-case-fall-through": true,
    "no-trailing-whitespace": true,
    "no-unused-expression": true,
    "no-unused-variable": false,
    "no-unreachable": true,
    "no-use-before-declare": true,
    "no-var-requires": false,
    "one-line": [
      true,
      "check-open-brace",
      "check-catch",
      "check-else",
      "check-whitespace"
    ],
    "quotemark": [true, "double"],
    "semicolon": true,
    "triple-equals": [true, "allow-null-check"],
    "typedef": [true,
      "callSignature",
      "indexSignature",
      "parameter",
      "propertySignature",
      "variableDeclarator",
      "memberVariableDeclarator"],
    "use-strict": false,
    "variable-name": [
        true,
        "allow-leading-underscore"
    ],
    "whitespace": [
      true,
      "check-branch",
      "check-decl",
      "check-operator",
      "check-separator",
      "check-type"
    ]
  }
}

If everything works you should be able to execute the grunt command.

$ npm run grunt

The grunt command should execute successfully

TypeScript Express Web Application

If you made it this far we’re finally ready to start coding up our application using TypeScript + Express + Node.js. In other words, now we can get started with the fun stuff!

To get started, create a src directory for your TypeScript code.

$ mkdir src
$ cd src
$ touch app.ts

Let’s get started with our application. The first thing we want to do is create a Server class.

"use strict";

import * as bodyParser from "body-parser";
import * as express from "express";
import * as path from "path";

/**
 * The server.
 *
 * @class Server
 */
class Server {

  public app: express.Application;

  /**
   * Bootstrap the application.
   *
   * @class Server
   * @method bootstrap
   * @static
   * @return {ng.auto.IInjectorService} Returns the newly created injector for this app.
   */
  public static bootstrap(): Server {
    return new Server();
  }

  /**
   * Constructor.
   *
   * @class Server
   * @constructor
   */
  constructor() {
    //create expressjs application
    this.app = express();

    //configure application
    this.config();
  }
}

Let’s quickly walk through the TypeScript above.

  • First, I am using strict mode for JavaScript.
  • Next, we are importing the necessary modules for the application. We are using the body-parsermodule, the express engine, and the built-in node.js path module.
  • Then I create the Server class.
  • The Server class has a property named app that is of type express.Application. We’ll dig more into this type declaration in a bit. Just hang tight.
  • The Server class has a static method named bootstrap that will create a new instance of our Server class.
  • The Server class also has a constructor method that creates and configures our application.

There are a couple of issues before we move ahead:

  • We have not installed the body-parser module. We will need to do that using npm.
  • The TypeScript compiler doesn’t know anything about the built-in objects, like Array and Boolean.
  • The TypeScript compiler doesn’t know the type definition for express (remember, the type declaration for the app property was set to express.Application).

So, let’s install the body-parser module.

$ npm install body-parser --save

Now, let’s create a new _all.d.ts file that will include references to all of the type definitions for our application.

$ touch _all.d.ts

Open the _all.d.ts file and paste this new line at the top of the file

/// <reference path="../node_modules/typescript/lib/lib.es6.d.ts" />

Then, modify your app.ts file so that you are referencing the _all.d.ts file

/// <reference path="_all.d.ts" />

The TypeScript compiler now knows about the ES6 interfaces (and objects). We’ll also put more references in the _all.d.ts file, including the reference to our main typings file.

Next we’ll look at using typings for obtaining type definition files for common modules that we will be using.

This will allow us to take full advantage of TypeScript’s strong typing when working with open source projects, like Express or Angular. Otherwise we would have to declare all of the appropriate interfaces and typing declarations.

Install Typings

Typings uses the DefinitelyTyped library for retrieving and storing TypeScript definition files for node modules and open source frameworks and libraries (like express or Angular). In case you have been using TypeScript you may have used the tsd command line utility for installing TypeScript definition files from DefinitelyTyped. However, at the time of this writing, tsd has been deprecated in favor of the new typings project.

$ npm install typings --save

Once we have typings installed we can use the command-line interface for searching and installing TypeScript definition files. It is important to note that I will be executing the typings CLI from the application’s root directory.

$ node_modules/.bin/typings install body-parser --ambient --save
$ node_modules/.bin/typings install express --ambient --save
$ node_modules/.bin/typings install node --ambient --save
$ node_modules/.bin/typings install serve-static --ambient --save
$ node_modules/.bin/typings install express-serve-static-core --ambient --save
$ node_modules/.bin/typings install mime --ambient --save

The next step is to reference the typings/main.d.ts file that is generated from typings. The main.d.ts file is similar to our _all.d.ts file in that it contains references to all of the TypeScript definition files that are installed/managed by typings. So, open up the _all.d.ts file and add this line of code below the existing line we just added.

/// <reference path="../typings/main.d.ts" />

Now that we have typings installed and we are referencing the main.d.ts definition file that Typings generates we are ready to build our TypeScript + Express + Node.js application.

$ npm run grunt
$ npm start

If we visit http://localhost:8080 in our browser we should we an error indicating that there is not a GET route specified for the root.

Screenshot of browser showing error message 'cannot GET'

Define Routes

The final step is to define the routes for your web application. I like to configure my routes in separate classes in a Routes module. Here is what my src/routes/index.ts file looks like.

/// <reference path="../_all.d.ts" />
"use strict";

import * as express from "express";

module Route {

  export class Index {

    public index(req: express.Request, res: express.Response, next: express.NextFunction) {
      //render page
      res.render("index");
    }
  }
}

export = Route;

My Index.index() route simply renders the index page. To wire this up, we need to first require the routes/index.ts module in our application app.ts file.

import * as indexRoute from "./routes/index";

Then, I’ll create a new private method named routes(), which is called from the constructor function.

/**
 * Constructor.
 *
 * @class Server
 * @constructor
 */
constructor() {
  //create expressjs application
  this.app = express();

  //configure application
  this.config();

  //configure routes
  this.routes();
}

My routes() method simply wires up the GET request for the web root: /.

/**
 * Configure routes
 *
 * @class Server
 * @method routes
 * @return void
 */
private routes() {
  //get router
  let router: express.Router;
  router = express.Router();

  //create routes
  var index: indexRoute.Index = new indexRoute.Index();

  //home page
  router.get("/", index.index.bind(index.index));

  //use router middleware
  this.app.use(router);
}

In the routes() method I first get access to the Router() in express, then using the module that I imported previously, I instantiate a new instance of the Index class. My Index class has a method named index(I know, a little confusing).

Hello World

Well, we made it. It’s finally time to output the famous “Hello World”. When we configured the application I chose to use the jade template engine. You can choose to use another template engine if you prefer. So, let’s install jade via npm.

$ npm install jade --save

Then, let’s create a views folder and an index.jade file.

$ mkdir views
$ cd views
$ touch index.jade

Open up index.jade in your favorite editor and add the following.

h1 Hello World!
p You did it, congratulations!

Don’t forget to recompile your TypeScript code into JavaScript, or use the grunt watch command:

$ npm run grunt watch

Once your TS is compiled, restart your server.

$ npm start

Now, load http://localhost:8080 in your browser and you should see the following:

Screenshot of browser displaying 'hello world'

Posted in Node Dot JS | Leave a comment

E-commerce plateform

http://laravel.demo.aimeos.org/

Posted in Laravel | Leave a comment

Using Typescript with Node JS

Back to blog home

Using Typescript with Node JS

In this article we will set up an Express application using Typescript.

What you’ll need

In order to follow this tutorial you will need the latest version of Node js, Typescript, and Typings installed. I recommend installing node js via Homebrew if you are on OSX. Once node is installed, both Typings and Typescript can be installed via NPM.

Use the following commands to do so:

npm install -g typescript
npm install -g typings

Optionally you should install Visual Studio Code. This is a code editor from Microsoft that is built using Typescript. It provides an excellent environment for working with Typescript and many other programming languages.

Setting up a Typescript project

Now that the prerequisites are installed we can begin setting up the Typescript project. Open up a terminal, create, and ‘cd’ into a directory called express-ts.

mkdir express-ts
cd express-ts

Now that we are in the created directory we can initialise the Typescript project. To do this we will use the tsc and typings commandline executables. These were installed via Typescript and Typings respectively.

Firstly we want to create a tsconfig.json file. This can be done with tsc.

tsc --init

Running the above command creates the tsconfig.json in the current directory. It also adds some useful boilerplate code to the file. Looking inside the newly-generated tsconfig.json you should see the following:

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": false
    },
    "exclude": [
        "node_modules"
    ]
}

For the purposes of this demo we are going to put the compiled .js files into a build directory. In order to tell the Typescript compiler that this is where the compiled files should go we must add an outDir parameter. Add the following to the compiledOptions object inside the tsconfig.json file:

"outDir": "build"

Now that the tsconfig is correctly set up we will add some Typescript Definition files or .d.ts files via Typings. These files are used to give the compiler knowledge of the application.

Run the following to create a typings.json file:

typings init

As we will be using Express and ES2015 syntax we need to install the es6-shimnode, and express typings. Run the following commands to do so:

typings install dt~node --save --global
typings install dt~es6-shim --save --global
typings install dt~express --save --global
typings install dt~serve-static --save --global
typings install dt~express-serve-static-core --save --global
typings install dt~mime --save --global

The above commands will update the typings.json file which was generated by the typings init command and place the Typings dependencies in the typings folder.

Now we can install the application depencies via NPM. In the application root folder run the following:

npm init -y
npm install --save express

This creates a package.json file and installs Express as a dependency.

Finally let’s create the application files. Make a folder called app and add a server.ts file. The application will be a greeter. So let’s also add a WelcomeController. Inside the app folder create another folder called controllers and a welcomeController.ts and index.ts file.

mkdir app && cd app
touch server.ts
mkdir controllers && cd controllers
touch index.ts welcomeController.ts

The application should now have the following structure:

.
├── app
│   ├── controllers
│   │   ├── index.ts
│   │   └── welcomeController.ts
│   └── server.ts
├── node_modules
├── package.json
├── tsconfig.json
├── typings
└── typings.json

Creating an express app

We will be creating a greeting app which will have one route that takes a name parameter and then greets that name.

Open a text editor inside the application folder. If you are using Visual Studio Code you can open it inside the folder by running the code command with a folder argument.

code .

Firstly, let’s take a look at the welcomeController.ts file. This file will handle the welcome routes. To do this we need it to export an Express router object. I have added code comments to the snippet below which explains how this file should work:

/* app/controllers/welcomeController.ts */

// Import only what we need from express
import { Router, Request, Response } from 'express';

// Assign router to the express.Router() instance
const router: Router = Router();

// The / here corresponds to the route that the WelcomeController
// is mounted on in the server.ts file.
// In this case it's /welcome
router.get('/', (req: Request, res: Response) => {
    // Reply with a hello world when no name param is provided
    res.send('Hello, World!');
});

router.get('/:name', (req: Request, res: Response) => {
    // Extract the name from the request parameters
    let { name } = req.params;

    // Greet the given name
    res.send(`Hello, ${name}`);
});

// Export the express.Router() instance to be used by server.ts
export const WelcomeController: Router = router;

Now that the WelcomeController is ready to be used, let’s export it from the controllers folder. As you may know, index files act as folder entry points. Thanks to this we can access exports from the index.ts file we created in the controllers folder. Add the following to that file:

/* app/controllers/index.ts */
export * from './welcomeController';

Note: as good practice you should never add application logic inside an index file.

Now that the WelcomeController is being correctly exported, let’s make use of it inside the server.ts file.

/* app/server.ts */

// Import everything from express and assign it to the express variable
import * as express from 'express';

// Import WelcomeController from controllers entry point
import {WelcomeController} from './controllers';

// Create a new express application instance
const app: express.Application = express();
// The port the express app will listen on
const port: number = process.env.PORT || 3000;

// Mount the WelcomeController at the /welcome route
app.use('/welcome', WelcomeController);

// Serve the application at the given port
app.listen(port, () => {
    // Success callback
    console.log(`Listening at http://localhost:${port}/`);
});

Now that we have finished writing the application, let’s transpile it to javascript. In the root of the application run the following:

tsc

Alternatively you may run the following to tell the Typescript compiler to run everytime it detects a filesystem change.

tsc --watch

These commands will tell the Typescript compiler to build the application based on the tsconfig.json. If everything has been successfull you will see a newly created build directory. This is where the Typescript compiler has placed the generated .js files based of the optional outDir parameter in the tsconfig.

We can now run the app with the following command:

node build/server.js

Open a browser at the following url: http://localhost:3000/welcome. You should be greeted with a Hello, World! Try visiting http://localhost:3000/welcome/Borris to confirm the WelcomeController is functioning correctly. You should see a Hello, Borris!

Summary

This application, though simple, gives a good basis for creating future Express applications with Typescript.

You have learned how to intialise a Typescript application from the command line. You have also seen how to make use of Typings within a Typescript application. Learning how to use typings is very important when working with Typescript as they give the compiler a better knowledge of the application. The more the compiler knows, the better it can help you out.

You have also learned a bit about structuring an Express application. Many Express tutorials bundle code into one big server.js file. This leads to an application that is very difficult to maintain and is not representative of real world applications.

However we have seen here that it is possible to mount Express Router instances so that applications can be broken down into modular parts. This leads to more maintainable and scalable applications.

Next steps

Posted in Node Dot JS | Leave a comment

es6-controller

es6-controller 

Controller framework for Nodejs supporting ecmascript-6. No more hassling with code in your route. es6-controller automatically set up routing based on your controllers. Typescript definition is also present for strict mode.

Contributors

Nitin Bansal https://github.com/nitinbansal1989

Installation

$ npm install es6-controller

Usage

Just add the routes to router object and add the handler to the express module.

const es = require(es6-controller);
 
//Your express-app 
var app = express();
 
/*
    Add a route to ‘es6-controller’ Router.
*/
var router = es.router;
router.add(Default, /{controller}/{action}/{id}, __dirname + /Controller, defaults, false);
 
// Add es6-controller handler to express 
app.use(es.handler);
 

Route

A Route should be added to router. It should contain a path template for matching. “controller” and “action” keyword are used for matching Class and and function name respectively. Other parameters are added to the req.params object.

A Route has following parameters :-

parameter type description
Name string Name of the router
Route Template string Template path of the router.
Directory Path string Path of the Controller directory
Defaults Map<string, string> Map for specifying the default parameters
includeSubDir boolean Flag for finding the coltroller classes recursively in sub directories

Defaults

Specifies the default request parameters.

var defaults = new Map();
defaults.set(“controller”, “Home”);
defaults.set(“action”, “index”);
defaults.set(“id”, “1”);

Controllers & Paths

The paths will be generated by a convention of naming controllers and functions.

A basic example: HomeController.js

 
use strict;
const es = require(es6-controller);
/*
    Will set Controller Name as “Home”
*/
class Home extends es.Controller {
    /*
        Will be translated to get(“/Home/index”) (HTTP-method is extracted by first item in function name)
    */
    get_index() {
        this.res.send(Returning Get Index request);
    }
    
    /*
        Will be translated to (“/Home/index”) for all methods.
        Note: specified method request will have greater priority
    */
    index() {
        this.res.send(Returning Index request for all methods);
    }
    
    /*
        Will be translated to get(“/Home”) when no action is found.
        Note: specified method with action request will have greater priority
    */
    get() {
        this.res.send(Get Response has been created);
    }
    
    /*
        Will be translated to post(“/Home”) when no action is found.
        Note: specified method with action request will have greater priority
    */
    post() {
        this.res.send(Post Response has been created);
    }
}
exports.Home = Home;
 

Load from File

Routes can also be loaded from a json file. Use the load method of the router to specify the path to the configuration file.

var router = es.router;
router.load(__dirname + “/config.json”, __dirname);

config.json

Specify one Object or an Array of Object. For directory path, you can use “__dirname” global variable as “{dirname}” template in config file.

{
    “name”: “Default”,
    “template”: “/{controller}/{action}”,
    “dir”: “{dirname}/Controller”,
    “includeSubDir”: false,
    “defaults”: {
        “controller”: “Home”,
        “action”: null
    }
}

Please provide suggestions if any.

Posted in Node Dot JS | Leave a comment

Authentication JWT Express Node JS

Continue reading

Posted in Node Dot JS | 1 Comment

Enable GZIP in wamp server

put in .htacces on main root directory

<IfModule mod_deflate.c>
<FilesMatch “\.(ico|jpg|jpeg|png|gif|js|css|html|php|txt|xml)$”>
SetOutputFilter DEFLATE
</FilesMatch>
</IfModule>

Posted in Framework | Leave a comment