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.
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?
Just added a comment because I forgot to click ‘notify me of comments’ 🙂
Thank you: very useful and clear tutorial! 🙂
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.”
Just add this to resolve your issue
extensions : [‘.ts’]
this.ts.getAutomaticTypeDirectiveNames is not a function i am getting the error by using
$ npm run build command