loading...

Incrementally migrate your webpack project to TypeScript

bartw profile image Bart Wijnants Originally published at Medium on ・2 min read

TL;DR

If you want to migrate to TypeScript but don’t want to migrate all your code at the same time you can configure webpack to bundle both TypeScript and JavaScript code.

You can find a demo project here.

How to?

To add TypeScript to a webpack project you can follow these steps:

Install the needed dev-dependencies:

npm install --save-dev @types/jest awesome-typescript-loader typescript @types/lodash

Create a tsconfig.json file to specify that you want to transpile to ES6:

{
  "compilerOptions": {
    "target": "es6"
  }
}

Add awesome-typescript-loader to your webpack config file and load your TypeScript first through the TypeScript transpiler and then through Babel:

module: {
  rules: [
    { test: /\.jsx?$/, exclude: /node_modules/, use: "babel-loader" },
    { 
      test: /\.tsx?$/, 
      exclude: /node_modules/, 
      use: ["babel-loader", "awesome-typescript-loader" }
  ]
}

To stop Babel from transforming ES6 module syntax to commonjs you need to update the .babelrc file:

{
  "presets": [["es2015", { "modules": false }], "react"],
  "plugins": ["transform-class-properties"]
}

Now comes the tricky part: keeping the Jest tests running.

Some extra configuration is necessary to tell Jest to transpile TypeScript and to have the normal JavaScript run through Babel-Jest.

In your package.json add the following Jest config:

"jest": {
  "moduleFileExtensions": ["ts", "tsx", "js", "jsx"],
  "transform": {
    "^.+\\.(ts|tsx)$": "<rootDir>/preprocessor.js",
    "^.+\\.(js|jsx)$": "babel-jest"
  },
  "testRegex": "(/ __tests__ /.*|\\.(test|spec))\\.(ts|tsx|js|jsx)$"
}

Create a preprocessor.js file to transpile TypeScript tests:

const tsc = require("typescript");

module.exports = {
  process(src, path) {
    if (path.endsWith(".ts") || path.endsWith(".tsx")) {
      return tsc.transpile(src, {}, path, []);
    }
    return src;
  }
};

In .babelrc you need to add a separate configuration for the test environment to play nice with Jest:

{
  "presets": [["es2015", { "modules": false }], "react"],
  "plugins": ["transform-class-properties"],
  "env": {
    "test": {
      "presets": ["es2015", "react"],
      "plugins": ["transform-class-properties"]
    }
  }
}

Now you should be able to start migrating files one by one to TypeScript without breaking tests or builds.

Posted on by:

bartw profile

Bart Wijnants

@bartw

As Mick Jagger sang it in Sympathy For The Devil: Please allow me to introduce myself. I'm a man of wealth and taste. Well maybe just the first sentence. I'm not quite wealthy and a lot of people will strongly advice against my taste. I'm Bart, father of 2 boys, developer by trade, retired ice hockey player and knowledge sponge. I try to live by the KISS principle but sometimes I keep it more stupid than simple. Peace out.

Discussion

markdown guide