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
        }
    },
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章