#6 Step By Step: Typescript
Friday, August 17, 2018
Just like we did in the previous article when we configured webpack to handle scss files instead of css it is now time to add the ability to process typescript files. In addition to this we will also setup tslint to help us make sure our typescript files are as error free and formatted correctly as possible.
I'd rather use typescript than javascript
- WebUi
- package.json
Just like I very rarely use css directly and instead write my styles in scss I also very rarely write javascript directly and instead use typescript. The first thing that we need to do to handle typescript files is to include a typescript loader for webpack (a). As usual the version for the package at the time of the writing of this article is shown in (b).
Terminal
npm install --save-dev ts-loader
package.json
{
...
"devDependencies": {
...
"ts-loader": "^4.2.0",
...
},
...
}
Time to convert to typescript
- WebUi
- Source
- index.js
- index.ts
- webpack.config.js
- Source
The first thing we will do is just change the extension of our
index.js
file from js
to ts
. We will also modify the content slightly just so we
are sure it is being processed (c). With that done we need to update the entry object
of our webpack configuration file and add the ts loader (d).
index.ts
console.log("hello world from typescript");
webpack.config.js
...
const entry = {
"index": ["./Source/index.ts", "./Source/index.scss"]
}
const _module = {
rules: [
...,
{
test: /\.ts$/,
exclude: /node_modules/,
use: [
"ts-loader"
]
}
]
}
...
If we try to build our bundles again we will see the fairly descriptive error shown in (e).
You could as the message says install typescript within your project but also as it says I do have
typescript installed globally so I will use the link command npm link typescript
.
Once again when we try to build our bundles and we will see another error which is shown in
(f). This new error is a little off the mark since our problem is not
an empty list in our tsconfig.json
file. Our problem is that we do not
have a tsconfig.json
file.
No one will accuse us of not having enough configuration files
- WebUi
- tsconfig.json
Time to add our tsconfig.json
file. In our config we will just specify
our target (g).
tsconfig.json
{
"compilerOptions": {
"target": "es5"
}
}
With that done finally when we build our bundles and check the console of our browser we see the message we are expecting (h).
Not required but useful
- WebUi
- tslint.json
Although not strictly required it is good to get as much help as we can to make sure that
our code is as error free and formatted uniformly as possible. One way we can go about that
is by using linters. Relevant to this discussion is tslint which I have installed globally
using the command npm install -g tslint
. Which at the time
of the writing of this article is on version 5.10.0. To use it we get the joy of adding
another configuration file (i).
tslint.json
{
"extends": "tslint:latest"
}
Now that we have our configuration file let us open up our typescript file and take a look. (j).
So I do not forget
- WebUi
- tsconfig.json
- tslint.json
In this article we have created the minimal tsconfig and tslint files as possible. As you might have guessed in regular projects these files usually contain some additional configuration options. Starting with the tsconfig file some of the typical options that I set are shown in (k). You can find a list of all of the options and what they do at www.typescriptlang.org.
tsconfig.json
{
"compileOnSave": false,
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [ "es2017", "dom" ],
"module": "CommonJS",
"moduleResolution": "Node",
"noImplicitAny": true,
"target": "es5"
}
}
And of course we cannot forget our tslint file (l). You can find the documentation for it at https://palantir.github.io/tslint/.
tslint.json
{
"extends": "tslint:latest",
"rules": {
"arrow-parens": [false, "ban-single-arg-parens"],
"max-line-length": [true, 120],
"member-ordering": [true, {
"order": [
"private-static-field",
"private-instance-field",
"public-static-field",
"public-instance-field",
"constructor",
"public-instance-method",
"protected-instance-method",
"private-instance-method"
]
}],
"no-string-literal": false,
"no-implicit-dependencies": false,
"no-submodule-imports": false,
"no-var-requires": false,
"trailing-comma": false,
"variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore"]
}
}