Typescript 转换工具 babel-loader 和 ts-loader

2024-11-07
webpack
119

ts-loader

ts-loader 是一个 Webpack 加载器,用于将 TypeScript 代码编译成 JavaScript 代码,以便浏览器能够理解和运行。ts-loader 使用 tsc 将 TypeScript 转换为 JavaScript,并能处理相关的类型检查和源映射。它常与 Webpack 一起使用,是 TypeScript 项目中进行模块打包和编译的工具之一。

  1. 安装 **ts-loader** **typescript**

首先,您需要安装 ts-loadertypescript 作为项目的依赖项:

npm install -D ts-loader typescript
  1. 配置 Webpack

在 Webpack 的配置文件 webpack.config.js 中,使用 ts-loader 来处理 .ts.tsx 文件。以下是一个基本的配置示例:

const path = require('path');

module.exports = {
  entry: './src/index.ts',  // 入口文件
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js'],  // 解析这些扩展名的文件
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,  // 匹配 .ts 或 .tsx 文件
        use: 'ts-loader',  // 使用 ts-loader 进行编译
        exclude: /node_modules/,  // 排除 node_modules 文件夹
      },
    ],
  },
};
  1. 配置 TypeScript

你还需要配置 TypeScript 编译器,通常通过一个 tsconfig.json 文件。这个文件告诉 TypeScript 编译器如何编译代码。使用 ts-loader 必须要配置 tsconfig.json 文件。

示例 tsconfig.json 文件:

{
  "compilerOptions": {
    "target": "es5",
    "module": "es6",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "outDir": "./dist"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

这个配置文件指定了编译选项,例如目标 JavaScript 版本、模块系统等,并指定了要编译的文件和排除的文件。

  1. 目标代码 src/index.ts
// 类型定义
const test: number = 1

// 特殊符号
const a = {b: 2}
console.log(a?.b);

// 箭头函数
const say = () => {
  console.log("hello world");
};
say();

// 高版本语法
const d = [1, 2, 3]
console.log(d.includes(4))

// 枚举值
enum Color {
  Red
}
console.log(Color.Red)
  1. 编译结果
!function () {
  "use strict";
  var o, l = {b: 2};
  console.log(null == l ? void 0 : l.b),
  console.log("hello world"),
  console.log([1, 2, 3].includes(4)),
  function (o) {
    o[o.Red = 0] = "Red"
  }(o || (o = {})), console.log(o.Red)
}();

可以总结一下 ts-loader 做了如下工作

image

  1. 编译耗时

ts-loader 编译耗时

平均在 600ms+

babel-loader

同样的工程,使用 babel-loader 编译需要做如下修改

  1. webpack 配置
{
  module: {
    rules: [
      {
        test: /\.js$|\.tsx?$/,  // 匹配 .js .ts 或 .tsx 文件
        use: 'babel-loader',  // 使用 babel-loader 进行编译
        exclude: /node_modules/,  // 排除 node_modules 文件夹
      },
    ],
  },
};
  1. .babelrc
{
  "presets": [
    ["@babel/preset-env", {
      "useBuiltIns": "usage",
      "corejs": 3
    }],
    "@babel/preset-typescript"
  ]
}

babel 编译 ts 文件,需要用到 @babel/preset-typescript,babel/preset-typescript 不需要 tsconfig.json

再补充说一下 @babel/plugin-transform-typescript

@babel/preset-typescript 包含 @babel/plugin-transform-typescript

@babel/plugin-transform-typescript 无法处理,可选链接 (?.), 空合并(??)和类属性(this.#x)等语法。如果您想转译这些功能,我们建议使用preset-env和preset-typescript。

  1. 编译结果
var n = {b: 2};
console.log(null == n ? void 0 : n.b), 
console.log("hello world"), 
console.log([1, 2, 3].includes(4));
var o = function (t) {
    return t[t.Red = 0] = "Red", t
  }(o || {});
console.log(o.Red)

可以总结一下

image

babel-loader 和 ts-loader 的编译结果无差别,并且加入了 pollyfill。但是babel-loader 只负责编译,不负责类型检查。所以类型错误不会报错。

比如 上面的代码 加一句 console.log(c) 。ts-laoder 会报错,babel-loader 则不会。

  1. 编译耗时

babel-loader编译耗时

babel-loader 的编译耗时在 500ms+,比 ts-loader 快 10% ~ 20%。

对比

通过两张图能明显看出来,ts-loader 的优势在于编译过程中进行语法检测,问题能提前暴露。

babel-loader 的优势在于可以按需添加polyfill,编译不进行语法检测,同时,打包速度比 ts-laoder 快

ts-loader 如果如果需要添加 polyfill,也可以和 babel-loader 同时使用

 {
        test: /\.tsx?$/,
        use: [
          'babel-loader',
          'ts-loader',
        ],
        exclude: /node_modules/,
      },

先用 ts-loader 编译一遍,再用 babel-loader 处理 pollyfill。但是这样编译耗时将成倍提升。得不偿失。

总结

整体来看,使用 babel-loader 替代 ts-loader 效率更高,功能更强。而类型检查可以交给编辑器来检查,或者在git commit 钩子处做检查。