Ts-loader and Babel hybrid era

There was no official TS version of create-React-app at the time. Eslint and TSLint have not been merged yet. Most projects use a mixed workflow of TS-Loader + ESLint + tsLint + webpack + Babel.

Disadvantages:

  1. Every time you change a bit of code, ts code is passed to typescript to be converted to JS, and that JS code is passed to Babel to be converted to a lower version of JS code, which is slow and may end up being rendered redundant.
  2. Two compilers need to be configured, and every time a little change is made, the code is translated twice, and recompiling is very slow.

Pros: typescript does both action translation and type checking.

ts-loader + fork-ts-checker-webpack-plugin

Since typescript does translation and code checking at the same time, is it possible to do either? Type checking can be turned off through the TS-Loader configuration

transpileOnly: true.Copy the code

The fork-ts-checker-webpack-plugin is then used to do type checking, creating a separate process to perform type checking without affecting the speed of webpack recompilation.

// webpack.config.js

const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
module.exports = {
  ...
  module: {
    rules: [{test: /\.tsx? $/,
        loader: 'ts-loader'.exclude: /node_modules/,
        options: {
          // disable type checker - we will use it in fork plugin
          transpileOnly: true}}},plugins: [new ForkTsCheckerWebpackPlugin()]
};
Copy the code

Awesome-typescript-loader has been used to solve some of these problems, but it has all sorts of minor issues that are now history.

Disadvantages:

  1. Every time you change a bit of code, ts code is passed to typescript to be converted to JS, and that JS code is passed to Babel to be converted to a lower version of JS code, which is slow and may end up being rendered redundant.
  2. It was still very slow when it came to translation and type checking and so on.

Advantages:

  1. No type checking, only compilation, etc., faster

@babel/preset-typescript comes out of the blue.

Detailed documentation and articles are available here.

  • Iamturns.com/typescript-…
  • Babeljs. IO/docs/en/bab…

You can think of it as @babel/preset-typescript and typescript.

  • Typescript does both code conversion and type checking.
  • @babel/preset-typescript only does syntax conversion, not type checking.

There are four differences in syntax conversion:

  1. The Namespace syntax is not recommended (use the standard ES6 module (import/export) instead.
  2. X syntax conversion type is not supported (use x as newtype instead).
  3. Const enumeration
  4. Legacy import/export syntax. For example: import foo = require(…) And export = foo.
  • The new items for grammar 1 and 4 are almost unused.
  • This syntax will directly indicate that the syntax error, very easy to change, no problem.
  • Article 3 The test will be available in February 2021.

Advantages:

  1. Faster compilation speed.
  2. Babel can transform parts of the syntax depending on the target browser.
  3. The configuration is much simpler.

Disadvantages: If only @babel/preset-typescript is used, when NPM run build is executed, ts files must be output to JS code, regardless of whether the code is correct or not, the code will be packaged, and problems in the code cannot be found in time.

I wrote a very simple Babel + TSX demo about three years ago (translation only, no type checking, above problems) github.com/Faithree/we…

Here’s another way.

  • @babel/preset-typescript for syntax conversion
  • Typescript does syntax checking.

package.json

"scripts": {
    "check-types": "tsc --watch"
}
Copy the code

Tsconfig. json sets noEmit to do no file generation, only type checking

{
    "compilerOptions": {
        "noEmit": true,
    },
    "include": [
        "src"
    ]
}
Copy the code

Disadvantages:

  1. You need to start two threads, one for webpack and one for typescript to perform code type checking, which can cause errors to be out of sync, and also support the vscode editor to have a better experience.
  2. Prevents type errors during build translation. If you change the code and do not run check-types, the code will still translate, but it may be typed.

Best practice @babel/preset-typescript+ fork-ts-checker-webpack-plugin

This replaces typescript with fork-ts-checker-webpack-plugin.

// webpack.config.js

const path = require('path');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
  mode: 'development'.entry: './src/index'.output: {
    path: path.resolve(__dirname, 'dist'),
    // filename: '[name]-[hash].js'
    filename: 'bundle.js',},resolve: {
    extensions: ['.ts'.'.tsx'.'.js'.'.json'],},devServer: {
    publicPath: '/'.host: '127.0.0.1'.port: 3000.stats: {
      colors: true,}},module: {
    rules: [{test: /\.(ts|js)x? $/,
        exclude: /node_modules/,
        loader: 'babel-loader',}]},plugins: [
    new ForkTsCheckerWebpackPlugin({
      formatter: 'codeframe'.async: true,}).new HtmlWebPackPlugin({
      template: 'public/index.html'.filename: 'index.html'.inject: true,})]};Copy the code

Advantages:

  1. Fork-ts-checker -webpack-plugin fork-ts-checker-webpack-plugin fork-ts-checker-webpack-plugin fork-ts-checker-webpack-plugin fork-ts-checker-webpack-plugin fork-ts-checker-webpack-plugin fork-ts-checker-
  2. Fast compilation speed.
  3. Type errors can also be found when code is translated.
  4. Rich Babel plug-in, according to the browser version, output specified JS code.

React 17

React 17 source code doesn’t need to be introduced anymore, so there are some differences between Babel and TS configuration.

yarn add @babel/preset-react -D
Copy the code

babel.config.js


const presets = [
  ...
  ['@babel/preset-typescript'],
  ["@babel/preset-react", {
    "runtime": "automatic"}]].Copy the code

tsconfig.json

{..."jsx": "react-jsx"
}
Copy the code

Eslint and tslint?

Eslint has gone through a lot of changes, from the beginning of ESLint-Loader to the current ESLint-webpack-plugin, from tsLint + ESLint mixing, to the unification of ESLint.

Tslint -> esLint mainly uses the following three libraries for compatibility.

  • @typescript-eslint/eslint-plugin
  • @typescript-eslint/parser
  • @typescript-eslint/typescript-estree

Details can be found at github.com/typescript-…

How to use

Eslint specific rule configuration, never used before, my advice is don’t bother with the specific configuration, use it first, I recommend @umijs/ Fabric, you can also choose other code writing rules such as airBnb.

yarn add  eslint-webpack-plugin -D
Copy the code
  new ESLintPlugin({
    extensions: ['js'.'mjs'.'jsx'.'ts'.'tsx'].cache: true,}).Copy the code

For detailed configuration of eslint-webpack-plugin, refer to github.com/webpack-con…

.eslint.js

module.exports = {
  parserOptions: {
    tsconfigRootDir: __dirname,
    project: './tsconfig.json'.createDefaultProgram: true,},extends: [require.resolve('@umijs/fabric/dist/eslint')].rules: {
    'no-console': 0.'no-new': 0.'no-case-declarations': 0.'react/jsx-tag-spacing': 0.'react/no-danger': 0.'react-hooks/exhaustive-deps': 'warn'.'no-param-reassign': 0.'react/jsx-uses-react': 0.'react/react-in-jsx-scope': 0.'no-undef':2.quotes: ['error'.'single'].// Use single quotes
    semi: ['error'.'always'].// End Add a semicolon}};Copy the code

Specific demo I put here github.com/Faithree/we…

You can run the following three commands and see that they all return the same error message.

  • yarn start
  • yarn build
  • yarn lint

git hook

yarn add yorkie lint-staged -D
Copy the code

package.json

  "gitHooks": {
    "pre-commit": "lint-staged"
  },
  "lint-staged": {
    "*.{js,jsx}": [
      "eslint"]."*.ts? (x)": [
      "eslint"]},Copy the code

.prettierrc.js

Because UMI’s ESLint specification is used above, I recommend going straight to prettierrc they provide

yarn add @umijs/fabric -D
Copy the code
const fabric = require('@umijs/fabric');
module.exports = { ... fabric.prettier, };Copy the code

reference

  • Github.com/webpack-con…
  • Github.com/typescript-…
  • Iamturns.com/typescript-…
  • Babeljs. IO/docs/en/bab…
  • Github.com/Faithree/we…
  • Github.com/facebook/cr…
  • github.com/umijs/umi
  • Github.com/Faithree/we…