最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 细嚼慢咽 Typescript + React17 +Eslint + Git hook 工作流

    正文概述 掘金(乘风gg)   2021-02-10   944

    ts-loader 和 babel 混用的时代

    那时候 create-react-app 还没有官方的 ts 版本。 eslint 和 tslint 还没合并在一起。 大部分项目都在用 ts-loader + eslint + tslint + webpack + babel 混用的工作流。

    缺点:

    1. 每次修改了一点代码,都会将 ts 代码传递给 typescript 转换为 js ,然后再将这份 js 代码传递给 Babel 转换为低版本 js 代码,不但慢,而且最终转译出来的代码可能比较冗余。
    2. 需要配置两个编译器,并且每次做了一点更改,都会经过两次转译,代码重新编译会非常慢。

    优点: typescript 会做两个动作转译和类型检查。

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

    因为 typescript 会同时做转译和代码检查,那可不可以只做转译或者代码检查其中一件事情呢? 可以通过 ts-loader 配置关闭掉类型检查

    transpileOnly: true,
    

    然后再使用 fork-ts-checker-webpack-plugin来做类型检查 ,开辟一个单独的进程去执行类型检查的任务,这样就不会影响 webpack 重新编译的速度。

    // 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()]
    };
    

    后来还出现过 awesome-typescript-loader 来解决一些问题,不过这插件有各种各样的小问题,已经成为历史了,大家有空的自己了解。

    缺点:

    1. 每次修改了一点代码,都会将 ts 代码传递给 typescript 转换为 js ,然后再将这份 js 代码传递给 Babel 转换为低版本 js 代码,不但慢,而且最终转译出来的代码可能比较冗余。
    2. 当时需要转译和类型检查等时候速度还是非常慢。

    优点:

    1. 不需要类型检查,只编译等时候,速度比较快

    @babel/preset-typescript 横空出世。

    具体文档和文章在这里。

    • iamturns.com/typescript-…
    • babeljs.io/docs/en/bab…

    你可以理解成 @babel/preset-typescript 和 typescript 的区别就是。

    • typescript 既做代码转换,也做类型检查)。
    • @babel/preset-typescript 只做语法转换,不做类型检查。

    还有在语法转换区别有以下四点:

    1. Namespace语法不推荐(改用标准的 ES6 module(import/export)。
    2. 不支持 x 语法转换类型,(改用x as newtype)。
    3. const 枚举
    4. 历史遗留风格的 import/export 语法。比如:import foo = require(...) 和 export = foo。
    • 第1条和第4条语法新项目基本没人用了。
    • 第2条缺陷改一下语法就好了,这个语法会直接提示语法报错,很好改,问题不大。
    • 第3条 2021 年 02 月亲测可用。

    优点:

    1. 更快的编译速度。
    2. babel 可以根据目标浏览器情况转换部分语法。
    3. 配置简单许多。

    缺点: 如果单单只用 @babel/preset-typescript,当我们在执行 npm run build 的时候,肯定需要把 ts 文件的代码输出成 js 代码,这时候不管代码是否正确,代码都会被打包出来,不能及时发现代码的问题。

    我大概在三年前写过一个 babel + tsx 最简单的 demo (只转译,没做类型检查,会出现上述问题) github.com/Faithree/we…

    下面再介绍一种方式。

    • @babel/preset-typescript 做语法转换
    • typescript 做语法检查。

    package.json

    "scripts": {
        "check-types": "tsc --watch"
    }
    

    tsconfig.json 设置 noEmit 不生成文件,只做类型检查

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

    缺点:

    1. 你要起两个线程,一个是 webpack 的线程,另一个是 typescript 执行代码类型检查的线程,可能会出现报错不同步,还要搭配支持 vscode 编辑器可能才有比较好的体验。
    2. 防止 build 转译代码的时候出现类型错误。如果你改了代码,没运行 check-types 命令,代码也能转译成功,但是可能代码是有类型问题的。

    最佳实践 @babel/preset-typescript+ fork-ts-checker-webpack-plugin

    这种是在上面的基础上,把 typescript 替换成 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,
        }),
      ],
    };
    

    优点:

    1. @babel/preset-typescript 做语法转换,fork-ts-checker-webpack-plugin 做语法检查, 集成在了 webpack 中,只用一个命令就可以启动。
    2. 编译速度快。
    3. 代码转译的时候也能发现类型错误。
    4. 丰富的 babel 插件,根据浏览器版本,输出指定 js 代码。

    React 17

    react 17 源代码不需要再引入 React 了,所以在 babel 和 ts 配置上有一些不同。

    yarn add @babel/preset-react -D
    

    babel.config.js

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

    tsconfig.json

    {
      ...
      "jsx": "react-jsx"
    }
    

    eslint 和 tslint ?

    eslint 其实也经历了很多的变化,从最开始 eslint-loader 到现在的 eslint-webpack-plugin,从 tslint + eslint 混用,到现在 eslint 的统一也经历了非常多年。

    tslint -> eslint 主要是下面这三个库来做兼容。

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

    详情可以看看 github.com/typescript-…

    如何使用

    eslint 具体的规则配置,从来没用过的,我的建议是没必要太纠结具体配置,先用上再说,我推荐 @umijs/fabric,也可以自行选择 airBnb等其他代码书写规则。

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

    eslint-webpack-plugin 详细配置可参考文档 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'], // 使用单引号
        semi: ['error', 'always'], // 结束添加分号
      },
    };
    
    

    你可以运行下面这三个命令,会发现他们的报错信息都一致。

    • yarn start
    • yarn build
    • yarn lint

    git hook

    yarn add yorkie lint-staged -D
    

    package.json

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

    .prettierrc.js

    因为上面 用了 umi 的eslint 规范,这里我推荐直接用他们提供的 prettierrc

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

    参考

    • 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…

    起源地下载网 » 细嚼慢咽 Typescript + React17 +Eslint + Git hook 工作流

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元