background
At the beginning, my project is based on react. I want to use Typescript in new functions and gradually modify the previous code, so I need to support both (TS|TSX) and (JS|JSX). You may not need to support TS and JS at the same time. This article will give the solution points of both cases.
Method
Typescript is usually converted to Javascript for execution, which is a syntax conversion. Typescript itself has a compiler, which can be compiled according to tsconfig.json. When we use Webpack to package and compile, we need the corresponding loader. The official website of Webpack recommends TS loader. The community also has awesome type script loader, which optimizes the TS loader to separate the type checking into a separate process. In addition, it can integrate Babel directly. Finally, a big killer is offered. Babel itself is a very powerful syntax conversion tool. After Babel 7, it began to support typescript.
To sum up, there are three common ways to convert Typescript:
- Classic TS loader
- awesome-typescript-loader
- @ Babel / preset typescript that has been supported since Babel 7
ts-loader
1. Support JS|JSX|TS|TSX
-
First, we need to configure tsconfig.json. The following is the key configuration (I omitted other configurations):
{ "compilerOptions": { "moduleResolution": "node", "module": "ESNEXT", "target": "es6", "jsx": "preserve", "esModuleInterop": true } }
jsx must be preserve when TS loader cooperates with Babel loader.
-
Then configure the webpack loader
{ test: /\.(js|jsx)$/, exclude: /node-modules/, loader: 'babel-loader', options: { cacheDirectory: true, cacheCompression: false } }, { test: /\.(ts|tsx)$/, exclude: /node-modules/, use: [ 'babel-loader', 'ts-loader' ] }
2. Only TS|TSX is supported
- tsconfig.json key configuration
{ "compilerOptions": { "module": "commonjs", "target": "es5", "jsx": "react", "esModuleInterop": true } }
- Only TS loader needs to be configured in webpack
{ test: /\.(ts|tsx)$/, exclude: /node-modules/, loader: 'ts-loader' }
awsome-typescript-loader
1. Support JS|JSX|TS|TSX
- tsconfig configuration is the same as TS loader.
{ "compilerOptions": { "moduleResolution": "node", "module": "ESNEXT", "target": "es6", "jsx": "preserve", "esModuleInterop": true } }
- babel configuration (only the presets section is shown here)
"presets": [ "@babel/preset-env", "@babel/preset-react" ],
- webpack configuration
{ test: /\.(js|jsx)$/, exclude: /node-modules/, loader: 'babel-loader', options: { cacheDirectory: true, cacheCompression: false } }, { test: /\.(ts|tsx)$/, exclude: /node-modules/, use: [ { loader: 'awesome-typescript-loader', options: { useBabel: true, babelCore: '@babel/core' } } ] }
2. Only TS|TSX is supported
- tsconfig is configured in the same way as TS loader.
{ "compilerOptions": { "module": "commonjs", "target": "es5", "jsx": "react", "esModuleInterop": true } }
- webpack configuration
{ test: /\.(ts|tsx)$/, exclude: /node-modules/, loader: 'awesome-typescript-loader' }
babel-loader
If you are using babel7 +, this solution is generally applicable to JS|JSX|TS|TSX. If you do not need JS|JSX, you can also use this solution without changing the configuration. webpack only needs to run the Babel compiler when it is packaged, and it will not occupy resources with the typescript compiler.
- To modify babel configuration, I use. babelrc here. Only the presets section is shown here. Presets are executed from the bottom up, so the first step will be the conversion of typescript.
"presets": [ "@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript" ]
- webpack configuration
{ test: /\.(js|jsx|ts|tsx)$/, exclude: /node-modules/, loader: 'babel-loader', options: { cacheDirectory: true, cacheCompression: false } },