Existing programs

1. awesome-typescript-loader

  • This NPM package has not been updated for a long time and is not recommended because there are omissions in type checking

2. ts-loader + babel-loader + fork-ts-checker-webpack-plugin

  • In this scenario, ts-Loader calls typescript when Webpack compiles (so local projects need typescript installed), and typescript runs to read the local tsconfig.json file.
  • By default, ts-Loader performs translation and type checking. Whenever a file is changed, the translation and type checking will be repeated. If there are too many files, it will be very slow, affecting the development speed. Fork-ts-checker-webpack-plugin is used to create a separate thread to perform type checking without affecting the speed of webpack recompilation.
  • Fork-ts-checker-webpack-plugin This plugin requires a minimum of Node.js 6.11.5, webpack 4, TypeScript 2.1, and optional ESLint 6 (which itself requires a minimum of Node.js 8.10.0).

Webpack configuration method 1

  • With the parallelization of build speed (Thread-loader), the speed increase for WebPack 4+ may not be obvious

webpack.config.js

const cpus = require('os').cpus().length;

const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');



module.exports = {

    module: {

        rules: [

                / / a single process

                / / {

                    // test: /\.tsx? $/,

                    // By default, ts-loader does translation and type checking

                    // Since it is a single process, WebPack can collect error information and send it back to the browser via dev-server

                    // But this also leads to a very slow WebPack build

                    // use:['ts-loader']

                / /},



                / / process

                {

                    test/\.tsx? $/.

                    exclude/node_modules/.

                    use: [

                        {loader'cache-loader'},

                        {

                            loader'thread-loader'.

                            options: {

                                workers: cpus - 1.

                            },

                        },

                        'babel-loader'.

                        {

                            loader'ts-loader'.

                            options: {

                                // Turn off type checking, that is, only translation

                                // Type checking is done by fork-ts-checker-webpack-plugin in another thread

                                // transpileOnly: true,

                                // If happyPackMode is set to true

                                TranspileOnly: true is implicitly set

                                happyPackMode: true

                                // If it is a VUE application, you need to configure this

                                // appendTsSuffixTo: [/\.vue$/]

                            }

                        }

                    ]

                },

                {

                    test/\.(js|jsx)$/.

                    use: ['happypack/loader? id=js'].

                    exclude: [/node_modules/, /(.|_)min\.js$/],

                    // include: [

                    // path.resolve(__dirname, "src")

                    / /,

                }

].

 },

 plugins: [

        // fork a process to check

        new ForkTsCheckerWebpackPlugin({

           // Async is false and synchronously reports an error to Webpack. If an error is reported, webPack will fail to compile

           // Async defaults to true and asynchronously reports error information to Webpack. If an error is reported, webPack compilation will not be affected

           // async: false,

               // eslint: false,

           checkSyntacticErrors: true

        })

  ]

};

Copy the code

tsconfig.json

{

  "compilerOptions": {

    //"module""commonjs".

    "target""es5".

/* In 'react' mode, ts will compile TSX to JSX and JSX to js*/

/* In 'Preserve' mode, TS will compile TSX to JSX, instead of JSX to JS, leaving JSX */

/* To retain JSX, configure babel-loader in front of ts-loader to handle JSX */

/* In other words: set this value */ only if you want to use babel-laoder

    "jsx""preserve".

  },

}

Copy the code

Webpack configuration method 2

  • Compile TS/TSX files without parallel builds (Thread-loader)
const cpus = require('os').cpus().length;

const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');



module.exports = {

    module: {

        rules: [

                {

                    test/\.tsx? $/.

                    exclude/node_modules/.

                    use: [

                       'babel-loader'.

                        {

                            loader'ts-loader'.

                            options: {

                                // Turn off type checking, that is, only translation

                                // Type checking is done by fork-ts-checker-webpack-plugin in another thread

                                transpileOnly: true.

                            }

                        }

                    ]

                },

                {

                    test/\.(js|jsx)$/.

                    use: ['happypack/loader? id=js'].

                    exclude: [/node_modules/, /(.|_)min\.js$/],

                    // include: [

                    // path.resolve(__dirname, "src")

                    / /,

                }

].

 },

 plugins: [

        // fork a process to check

        new ForkTsCheckerWebpackPlugin({

           // Async is false and synchronously reports an error to Webpack. If an error is reported, webPack will fail to compile

           // Async defaults to true and asynchronously reports error information to Webpack. If an error is reported, webPack compilation will not be affected

           // async: false,

               // eslint: false,

           checkSyntacticErrors: true

        })

  ]

};

Copy the code

tsconfig.json

{

  "compilerOptions": {

    //"module""commonjs".

    "target""es5".

/* In 'react' mode, ts will compile TSX to JSX and JSX to js*/

/* In 'Preserve' mode, TS will compile TSX to JSX, instead of JSX to JS, leaving JSX */

/* To retain JSX, configure babel-loader in front of ts-loader to handle JSX */

/* In other words: set this value */ only if you want to use babel-laoder

    "jsx""preserve".

  },

}

Copy the code

3. babel-loader + @babel/preset-typescript

  • In this scenario, when Webpack compiles, babel-loader reads the configuration in.babelrc, doesn’t call typescript (so local projects don’t need to install typescript), and doesn’t check for types
  • Tsconfig. json needs to be configured, however, because idea needs to be prompted with error messages during code development

webpack.config,js

rules: [

        {

          test:/\.(tsx? |jsx?) $/.

          // @babel/core is called by default

          use:'babel-loader'

        }

]

Copy the code

.babelrc

{

    "presets": [

         "@babel/preset-env"

            "@babel/preset-react".

            "@babel/preset-typescript"

    ]

}

Copy the code

Q&A

The main differences between awesome-typescript-loader and TS-loader

  • Awesome-typescript-loader does not require additional plug-ins to be installed and type checking can be performed in a separate process via the built-in CheckerPlugin
  • Compile time comparison:
  • Awesome -typescript-loader is faster if you use the default configuration
  • If type checking is disabled, ts-Loader is relatively fast
  • Awesome -typescript-loader is faster if type checking is disabled and executed in a separate process

Parallel builds are no longer appropriate for new versions of WebPack

It’s possible to parallelise your builds. Historically this was useful from a performance perspective with webpack 2 / 3. With webpack 4+ there appears to be significantly less benefit and perhaps even cost.

But if that’s what you want to do, there’s two ways to achieve this: happypack and thread-loader. Both should be used in combination with fork-ts-checker-webpack-plugin for typechecking.)

  • There are two ways to parallelize builds: happypack and Thread-loader
  • Parallel builds provide a significant performance boost for WebPack 2/3, and with WebPack 4+ the speed gain seems to be much less.

Why Babel when you use TypeScript

  • Most of the existing projects rely on Babel
  • Some requirements/functions need to be implemented by Babel plug-ins (e.g., load on demand)
  • Babel has a very rich set of plugins, and its ecosystem is thriving
  • Before Babel 7: The first two schemes are needed to translate TS
  • After Babel 7: Babel directly removes TS and converts to JS, which makes it fast to compile

Why use babel-loader after ts-loader

  • Ts-loader will not read the configuration in. Babelrc, that is, can not use the Babel series plug-in, so directly use TS-loader to convert TS/TSX to JS, there will be problems that gaskets cannot be loaded on demand, antD cannot be imported on demand. Therefore, we need to use TS-loader to convert TS/TSX into JS/JSX, and then use babel-loader to call Babel series plug-ins to compile into the final JS.

How to choose a translation scheme

  • To use TS in older projects, consider using the TS-loader + fork-ts-checker-webpack-plugin. Consider using @babel/preset-typescript for new projects. The former option has type checking by default.

What if I also want type checking when using babel-loader + @babel/preset-typescript

package.json

{

  "scripts": {

// open another NPM script to automatically check the type

    "type-check""tsc --watch".

  },

    "devDependencies": {

      "@babel/cli""^ 7.4.4." ".

      "@babel/core""^ 7.4.5".

      "@babel/plugin-proposal-class-properties""^ 7.4.4." ".

      "@babel/plugin-proposal-object-rest-spread""^ 7.4.4." ".

      "@babel/preset-env""^ 7.4.5".

      "@babel/preset-typescript""^ 7.3.3." ".

      "typescript""^ 3.5.2." "

    }

}

Copy the code

tsconfig.json

{

  "compilerOptions": {

// Do no file generation, only type checking

         "noEmit"true.

  },

}

Copy the code

Cautions for using @babel/preset-typescript

There are four syntax types that cannot be compiled in Babel

namespace Person{

    const name = 'abc';

}

Copy the code
  • Type assertion: Use as to assert types.
interface Person {

    name: string;

    age: number

}



let p1 = {age: 18} as Person;

console.log(p2.name);



let p2 = <Person>{age: 18};

console.log(p3.name);

Copy the code
  • Constant enumeration
const enum Sex {

    man,

    woman

}

Copy the code
  • Legacy import/export syntax:The import XXX = the require (...).export = xxx.

Why Typescript officially switched to ESLint

  • There are architectural issues with the way TSLint executes rules that affect performance, and fixing these issues would break existing rules;
  • ESLint has better performance and more users

Why ESLint when you use TypeScript

  • TS is mainly used for type checking and language conversions, with a little syntax checking
  • ESLint is primarily used to check for code style and syntax errors

Use ‘NPX create-react-app XXX –typescript’ to quickly create TS projects

Configure Demo for the three schemes

  • webpack-translate-typescript-demo

reference

TypeScript and Babel: A beautiful marriage

Replace awl-typescript-loader and TS-loader with @babel/preset-typescript

build-performance

https://segmentfault.com/q/1010000019545436

Recommended reading

Do you really understand the React lifecycle

React Hooks 【 nearly 1W words 】+ project combat

React SSR: + 2 projects

Implement a simple Webpack from 0 to 1

Cookie, Session, Token, JWT