learn-typescript

使用 @babel/preset-typescript 来编译 ts(x) 文件

参考自 TypeScript 和 Babel:一场美丽的婚姻

结合 webpack、babel、typescirpt

配置 webpack

  1. 安装依赖

    # 安装webpack
    yarn add -D webpack webpack-cli
    # 安装 babel-loader 处理 .js|.jsx|.ts|.tsx 文件
    yarn add -D babel-loader
    # 可选安装的依赖, 方便查看编译后文件的效果
    yarn add -D webpack-dev-server html-webpack-plugin
    
  2. 创建配置文件
    根目录创建 webpack.config.js 文件,重点见注释部分的代码:

    const path = require('path')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    
    module.exports = {
      mode: 'development',
      entry: './src/index.js',
      output: {
        path: path.join(__dirname, './dist'),
        filename: 'bundle.js'
      },
      devtool: 'cheap-module-eval-source-map',
      plugins: [
        new HtmlWebpackPlugin({
          template: path.join(__dirname, './src/index.html'),
          filename: 'index.html'
        })
      ],
      module: {
        rules: [
          // 添加 rule,指定 js/jsx/ts/tsx 文件使用 babel-loader 处理
          {
            test: /\.(j|t)sx?$/,
            use: 'babel-loader',
            exclude: /node_modules/
          }
        ]
      },
      resolve: {
        // 在默认数组的基础上添加解析 jsx 和 ts, tsx 后缀,
        // 作用是让webpack识别这些后缀名,从而在 import这些后缀名的模块时可以省略后缀名
        extensions: ['.wasm', '.mjs', '.js', '.json', '.jsx', '.ts', '.tsx']
      }
    }
    

配置 Babel 7

  1. 安装 Babel 7 依赖

    # 安装 Babel 开发依赖
    yarn add -D @babel/core @babel/cli @babel/preset-env
    
    # 安装 Babel 项目依赖, Babel7.4已经不再使用 @babel/polyfill
    yarn add core-js regenerator-runtime
    
  2. 添加配置文件
    根目录创建 babel.config.js 文件:

    const presets = [
      [
        '@babel/preset-env',
        {
          useBuiltIns: 'entry',
          corejs: '3.6', // corejs 最好指定到次版本号
        }
      ]
    ]
    const plugins = []
    
    module.exports = {
      presets,
      plugins
    }
    

    然后在入口文件(src/index.js)顶部添加:

    import 'core-js/stable'
    import 'regenerator-runtime/runtime'
    
  3. 添加 babel 对 jsx 和 typescript 的支持
    首先安装依赖:

    # preset-react 支持编译jsx, preset-typescript 支持编译ts文件
    yarn add -D @babel/preset-react @babel/preset-typescript
    
    # 添加 @babel/plugin-proposal-class-properties,以支持typescript常见的类属性写法
    yarn add -D @babel/plugin-proposal-class-properties
    

    更新 babel.config.js 文件:

    const presets = [
      [
        '@babel/preset-env',
        {
          useBuiltIns: 'usage',
          corejs: '3.6',
          targets: {
            ie: 9
          }
        }
      ],
      // 添加preset-typescirpt, 并配置以支持jsx
      [
        '@babel/preset-typescript',
        {
          isTSX: true,
          allExtensions: true
        }
      ],
      '@babel/preset-react' // 添加preset-react
    ]
    const plugins = ['@babel/plugin-proposal-class-properties'] // 添加类属性写法的plugin
    
    module.exports = {
      presets,
      plugins
    }
    

现在就已经完成了 babel 编译 ts(x) 文件的配置,就可以添加 ts、jsx、tsx 文件进行测试了。

安装 typescript 进行类型检查

使用 Babel 来编译 ts 文件,就可以不将 typescript 编译器以 watch 方式运行着,也就不会在每次保存代码时都进行繁琐的类型安全检查了。而在准备好进行代码检查的时候,就可以手动调用 typescript 编译器来进行类型安全检查。(或者,将 typescript 编译器以 watch 方式在另外一个进程中进行类型检查)

  1. 安装 typescript

    yarn add -D typescript
    
  2. 调整配置文件
    使用 npx tsc --init 初始化一个 tsconfig.json 配置文件,开启以下选项:

    {
       "compilerOptions": {
         "target": "ESNEXT",
         "module": "ESNext",
         "jsx": "preserve",  // 开启jsx
         "isolatedModules": true, // 不允许需要多个文件的信息进行的编译
         "strict": true, // 开启所有严格检查
         "moduleResolution": "node",  // 模块解析方式,根据 module的变化而变化,最好手动指定为 node
         "esModuleInterop": true,  // 解决es模块和commonjs模块的 import/export default差异
         "forceConsistentCasingInFileNames": true
       },
       "exclude": ["node_modules", "dist"] // 进行类型检查需要排除掉的文件或目录
     }
    
  3. 添加以下命令到 package.json

    {
      "scripts": {
        "type-check": "tsc --noEmit", // 执行类型检查
        "type-check:watch": "yarn run type-check --watch", //  watch 方式执行类型检查
        "build:types": "tsc --declaration --emitDeclarationOnly --outDir lib", // 需要生成.d.ts声明文件时可以添加
        "lint": "yarn run type-check && echo eslint-task && echo stylelint-check"  // 执行 lint 时,先进行 type-check,然后再做 eslint/stylelint 检查
      }
    }