Webpack配置React支持Typescript的三种方式

背景

开门见山,我的项目是基于react的,希望在新的功能上使用Typescript,并逐步修改之前的代码,所以我需要同时支持(TS|TSX)和(JS|JSX)。你可能不需要同时支持TS和JS,本文会同时给出两种情况的解决要点。

方法

Typescript通常是要转换成Javascript来执行的,这是一种语法转换。Typescript本身具有编译器,可以根据tsconfig.json来进行编译。当我们使用Webpack进行打包编译的时候,我们需要相应的loader,Webpack官网推荐了ts-loader。而社区也有awesome-typescript-loader,它针对ts-loader做了一些优化,将类型检查和代码生成分离到单独进程中,另外,它还可以直接集成babel。最后祭出大杀器,Babel本身是非常强大的语法转换工具,在babel7之后开始支持typescript。

综上,目前转换Typescript有三种常用的方式:

  1. 经典的ts-loader
  2. awesome-typescript-loader
  3. babel7之后已经支持的@babel/preset-typescript

ts-loader

1. 支持JS|JSX|TS|TSX

  • 首先我们需要配置tsconfig.json,以下是关键配置(我省略掉了其他配置):

    {
      "compilerOptions": {
          "moduleResolution": "node",
          "module": "ESNEXT",
          "target": "es6",
          "jsx": "preserve",
          "esModuleInterop": true
      }
    }
    

    ts-loader配合babel-loader的时候jsx必须是preserve

  • 然后配置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. 仅支持TS|TSX

  • tsconfig.json关键配置
    {
        "compilerOptions": {
            "module": "commonjs",
            "target": "es5",
            "jsx": "react",
            "esModuleInterop": true
        }
    }
    
  • webpack中只需要配置ts-loader即可
    {
        test: /\.(ts|tsx)$/,
        exclude: /node-modules/,
        loader: 'ts-loader'
    }
    

awsome-typescript-loader

1. 支持JS|JSX|TS|TSX

  • tsconfig配置和ts-loader一样。
    {
      "compilerOptions": {
          "moduleResolution": "node",
          "module": "ESNEXT",
          "target": "es6",
          "jsx": "preserve",
          "esModuleInterop": true
      }
    }
    
  • babel配置(这里只展示presets部分)
    "presets": [
        "@babel/preset-env",
        "@babel/preset-react"
    ],
    
  • webpack配置
    {
      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. 仅支持TS|TSX

  • tsconfig的配置和ts-loader的方式一样。
    {
        "compilerOptions": {
            "module": "commonjs",
            "target": "es5",
            "jsx": "react",
            "esModuleInterop": true
        }
    }
    
  • webpack配置
    {
      test: /\.(ts|tsx)$/,
      exclude: /node-modules/,
      loader: 'awesome-typescript-loader'
    }
    

babel-loader

如果你是用的是babel7+,这种方案通用于JS|JSX|TS|TSX,如果你不需要JS|JSX,也可以使用这种方案,无需更改配置。webpack在打包时只需要运行babel编译器即可,不会出现与typescript编译器抢占资源的情况。

  • 修改babel配置,这里我用的是.babelrc,这里只展示presets部分,presets是自下而上执行的,所以第一步就会经过typescript的转换。
    "presets": [
        "@babel/preset-env",
        "@babel/preset-react",
        "@babel/preset-typescript"
    ]
    
  • webpack配置
    {
        test: /\.(js|jsx|ts|tsx)$/,
        exclude: /node-modules/,
        loader: 'babel-loader',
        options: {
            cacheDirectory: true,
            cacheCompression: false
        }
    },
    

你可能感兴趣的:(typescript)