Home >Web Front-end >JS Tutorial >About static type checking solution for react project

About static type checking solution for react project

不言
不言Original
2018-07-09 11:02:481718browse

This article mainly introduces the static type checking scheme for react projects, which has certain reference value. Now I share it with you. Friends in need can refer to it

Why type checking is needed

As a weakly typed language, JS has great flexibility, but its advantages are also its disadvantages. It can easily allow us to ignore some obscure logic, syntax errors or data type errors, even at compile time. No errors will appear to be reported during runtime, but various strange and difficult-to-solve bugs may occur.

Like

function getPrice(x) {
  return x * 10;
}
getPrice('a23') // NaN
function getDefaultValue (key, emphasis) {
    let ret;
    if (key === 'name') {
      ret = 'GuangWong';
    } else if(key=== 'gender') {
      ret = 'Man';
    }else if(key ==='age'){
      ret = 18;
    } else {
       throw new Error('Unkown key ');
    }
    if (emphasis) {
      ret = ret.toUpperCase();
    }
    return ret;
  }
  
  getDefaultValue('name'); // GuangWong
  getDefaultValue('gender', true) // MAN
  getDefaultValue('age', true)

This is a simple function, the first parameter key is used to get a default value. The second parameter emphasis is used to emphasize capitalization in certain scenarios. You only need to pass in true to automatically convert the result to uppercase.

But if I accidentally write the value of age as a numeric literal, if I call getDefaultValue('age', true), an error will be reported at runtime. This may occur after the business goes online, directly causing the business to become unavailable

In addition, at work, we often encounter an attribute on an object that changes after being passed between n modules. Became undefined. The above is the issue of code robustness. Another headache at work is the issue of collaboration: How to make a method provided by others produce a document that is clear at a glance? Because a project always involves the collaboration of multiple people: Classmate A wrote function a(), and classmate B had to read the API document when calling function a() to know what parameters a() requires and what parameters it will return. .

Classmate A subsequently changed function a(), but forgot to update the document. At this time, classmate C, who had just taken over the project, looked at the API document and function a() in confusion, and the problem emerged. Surface: In team collaboration, how do the provided interfaces describe themselves?

The issues involved are:

1. How does the interface describe its parameters and return values?
2. The interface parameters and return values ​​have changed many times in countless requirement iterations, and how should the documentation corresponding to this API be updated?
4. How to describe the data format?

In order to solve many of the above pain points, we need to introduce a type checking mechanism. The so-called type checking means to detect bugs (caused by type errors) as early as possible during compilation without affecting the code running (no runtime dynamic checking is required) Type), so that writing js has an experience similar to writing strongly typed languages ​​such as Java. It can:

  • make large projects maintainable

  • Improve efficiency. Errors are reported when writing the code instead of the compilation stage

  • Enhance the readability of the code and make the code the document

  • Enhanced Design

Using Flow

JavaScript static type checking tool produced by Facebook, it can be partially introduced without completely reconstructing the entire project, so for an existing For projects of a certain scale, migration costs are smaller and more feasible

The learning cost of using flow is also relatively low

  1. Globally install the flow command line tool

npm install -g flow-bin
  1. In the project root directory, create a .flowconfig file

  2. Install the babel plug-in

npm install --save-dev babel-plugin-transform-flow-strip-types
  1. Add plugin in .babelrc file

{
  "presets": [ "es2015", "react", "stage-1" ],
  "plugins": [
        "react-flow-props-to-prop-types"
  ]
}
  1. Install extension (⇧⌘X): Flow Language Support

  2. Modify VS Code's default configuration for JavaScript

Code -> Preferences-> User Settings (⌘,)
Search for: javascript. validate.enable
modified to: "javascript.validate.enable": false

  1. Use

in the project when static checking is required The file header introduces flow, such as:

/* @flow */
function getPrice(x: number) {
  return x * 10;
}
getPrice('a23') // vscode 工具提示错误

About static type checking solution for react project

Using typescript

TypeScript is called a superset of JavaScript and is a static code launched by Microsoft. The inspection plan is encapsulated in JavaScript to encapsulate the characteristics of TypeScript. Of course, the final code can be compiled into JavaScript

1. Static type

let num: number;
num = 'likely';
    
[ts] 不能将类型“"likely"”分配给类型“number”。
let num: number

2. Function expression
js writing method

export const fetch = function (url, params, user) {
  // dosomething

  return http(options).then(data => {
    return data
  }).catch(err => {
    return err
  })
}

The above and below are a JavaScript function. Without looking at the writing method within the method, we have no idea what pitfalls this API will have.

export const fetch = function (url: string | object, params?: any, user?: User): Promise<object | Error> {
  // dosomething

  return http(options).then(data => {
    return data
  }).catch(err => {
    return err
  })
}

The above TypeScript contains a lot of information, allowing us to easily know how to call the function

  • url may be of string or object type

  • params does not need to be passed, or any type can be passed

  • user is required to be of User type, of course it does not need to be passed

  • Returns a Promise, the evaluation result of Promise may be object, or it may be Error

3. Component

export interface CouponProps { 
  coupons: CouponItemModel[]; 
}

export interface couponState {
    coupons: CouponItemModel[],
    page: number,
    size: number,
    state: number,  //可用优惠券
    hasMore: boolean,
    isLoading: boolean,
    loadedError: boolean,
}


class CouponContainer extends React.Component<couponprops> {
}</couponprops>

We can clearly know the above components It is clear at a glance which attributes, which methods, which attributes a component has, which attributes are required and which ones are optional. It truly realizes that code is a document

关于typescript还有很多其他特点,如类,接口,泛型等,具体可参考官方文档
https://www.typescriptlang.org/

项目迁移typescript

1.node
(1)使用npm安装:npm install -g typescript,当前项目使用了是v2.8.3
(2)2.2 tsconfig.json

{
  "compilerOptions": {
      "module": "commonjs",
      "target": "es5",
      "noImplicitAny": true,
      "sourceMap": true,
      "lib": ["es6", "dom"],
      "outDir": "dist",
      "baseUrl": ".",
      "jsx": "react",
      "paths": {
          "*": [
              "node_modules/*",
              "src/types/*"
          ]
      }
  },
  "include": [
      "src/**/*"
  ]
}

(3)将.js文件改为.ts
(4)结合 gulp 进行实时编译

var gulp = require('gulp');
var pump = require('pump');
var webpack = require('webpack');

var ts = require('gulp-typescript');
var livereload = require('gulp-livereload');
var tsProject = ts.createProject("tsconfig.json");

gulp.task('compile:tsc:server', function () {
  return gulp.src('src/server/**/*.ts')
      .pipe(tsProject())
      .pipe(gulp.dest('dist/server'));
});
//将任务同步执行
var gulpSequence = require('gulp-sequence');
gulp.task('compile', gulpSequence(
  'compile:tsc:server',
))


gulp.task('watch', ['compile'], function() {
  livereload.listen();

  gulp.watch(['./src/server/**/*.ts'], ['compile:tsc:server']);
})
  1. react

可在 webpack 配置文件添加规则

{ 
    test: /\.tsx?$/, 
    enforce: 'pre',
    use: [
        {
            loader: "ts-loader"
        }
    ]
 },

3.遇到的问题
遇到的问题

  • 动态地为global添加属性

由于js灵活的风格,我们经常动态地为某一对象添加属性,但是typeScript是编译型语言,基本原则是先定义再使用,所以当我们像下面这么引用

global.testName = '哈哈';

便会出现这样的错误

类型“Global”上不存在属性“testName”

解决方法

(1)将global强制转化为any类型

 (<any>global).testName = '哈哈'
    
(2)扩展原有的对象

  global.prototy.testName = '哈哈哈'

(3)使用.d.ts文件</any>
declare namespace NodeJS {
 
  export interface Global {
    testName: string;
  }
}

网上很多方法是直接添加一个.d.ts文件即可,但是亲测无效,需要在引用文件引入该文件,如本项目在app.ts文件中引入了

/// <reference></reference>

Flow 与 TypeScript简单对比

About static type checking solution for react project

总结

Flow或者TypeScript都是静态类型检查的优秀解决方案,能够给有类型检查需求的一定规模的项目带来实际收益。基于现有项目的情况,迁移 TypeScript 时间成本比较大,学习曲线相对陡峭,建议现有项目采用 Flow 方案,对于一些新的项目,可以采用 TypeScript

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

react 官网动画库(react-transition-group)的新写法

React-Reflux的基础介绍

The above is the detailed content of About static type checking solution for react project. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn