DEV Community

Bart Wijnants
Bart Wijnants

Posted on • Originally published at Medium on

Incrementally migrate your webpack project to TypeScript

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
Enter fullscreen mode Exit fullscreen mode

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

{
  "compilerOptions": {
    "target": "es6"
  }
}
Enter fullscreen mode Exit fullscreen mode

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" }
  ]
}
Enter fullscreen mode Exit fullscreen mode

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"]
}
Enter fullscreen mode Exit fullscreen mode

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)$"
}
Enter fullscreen mode Exit fullscreen mode

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;
  }
};
Enter fullscreen mode Exit fullscreen mode

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"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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

Discussion (0)