Configuring Webpack with Typescript

In a previous post, “A Gentle Introduction to Webpack“, we explore how to setup a very basic Webpack build to transpile ES6 code to ES5. In this tutorial we are going to expand on that article to add support for Typescript.

Because any Javascript file (even ES6) is a valid Typescript file, the first step of our improved build system will be to change the extension of the files main.js and person.js to main.ts and person.ts. Given that we are now in the Typescript realm, we can get rid of the exports/require syntax that we used before and implement the cleaner export/import syntax like shown below:

// person.ts

export let person = {
  firstName: 'David',
  lastName: 'Barreto'
};
// main.ts

import { person } from "./person";
console.log(person.firstName + ' ' + person.lastName);

To be able to compile this code into plain old javascript, we need to install the Typescript transpiler.

$ npm install typescript --save-dev

To be able to define some common typescript configuration options for our project, we need to create a special file called “tsconfig.json”. We can do just that with the following Typescript command.

$ tsc --init

This will create a “tsconfig.json” file with some default options.

tsconfig.json

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

In the above example we have used a globally installed tsc binary and not the local one. Creating a tsconfig.json file is something that it’s done only once and the beginning of a project. Defining a script in the package.json file just to do that would be overkill.

Configuring Webpack to Use Typescript

It is now turn to instruct Webpack how to transpile our code from Typescript to ES5 before creating a bundle. That functionality is provided through module loaders and one of the more broadly used one for Typescript is called awesome-typescript-loader. We can install such module loader from npm.

$ npm install awesome-typescript-loader --save-dev

We now have all the dependencies we need to complete our new build system. Our improved package.json file looks like this:

package.json

{
  "name": "webpack-typescript",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "awesome-typescript-loader": "^2.1.1",
    "typescript": "^1.8.10",
    "webpack": "^1.13.1"
  }
}

Finally, we need to go ahead and update the files webpack.config.js to configure our new module loader.

// webpack.config.js

module.exports = {
  entry: './main.ts',
  output: {
    filename: './bundle.js'
  },
  resolve: {
    extensions: ['', '.ts']
  },
  module: {
    loaders: [
      { test: /.ts$/, loader: 'awesome-typescript-loader' }
    ]
  }
};

A couple of things should be noted here. First, on line 2, we have changed our entry point from main.js to main.ts. Second, on line 7, we are defining the extensions that should be resolved by webpack when loading modules. In that array we are obviously defining the .ts extension to be able to  load typescript modules like this:

import { person } from './person';

Notice that we are not directly defining the extension of the module in the import statement. Instead, Webpack is in charge of looking for a file named person with one of the extensions defined in the extensions config option. In this case the file person.ts.

The empty string also defined in the extensions array is instructing Webpack to also resolve dependencies when explicitly defining the extension of a file in an import statement.

import { person } from './person.ts';

On line 11, we are telling webpack that the package awesome-typescript-loader should be used to understand and transpile every file with a .ts extension. In other words, any imported Typescript file in our project.

We have a very basic Typescript build system with Webpack. We can go ahead and build our files.

$ npm run build

This will create a file bundle.js that we can now run with Node.

$ node bundle.js
> David Barreto

We can see that our script was executed successfully. Our mission is complete.

In a next blog post we are going to go further with our build system to be able to load Angular 2.

As always, the source code for this example can be found here.

6 thoughts on “Configuring Webpack with Typescript”

  1. I need to resolve the references to static assets within my typescript code to point to the assets folder in the newly created ‘dev’ or ‘prod’ webpack build folders. I heard I could do it with TsConfigPathsPlugin. But somehow I cannot get it to work

    Could you add that to the sample if possible?

  2. I am getting this error: “Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
    – configuration.resolve.extensions[0] should not be empty.”

  3. this.ts.getAutomaticTypeDirectiveNames is not a function i am getting the error by using
    $ npm run build command

So, what do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.