Fork me on GitHub

TypeScript 开发 React-Native 项目

最近,项目组准备用 TypeScript (以下简称 TS)开发 ReactNative (以下简称 RN)组件库

参考微软的 TS 项目 TypeScript-React-Native-Starter,实践了一把。

1. 初始化一个 RN 项目

可以参考下 RN 的官方文档

1
2
3
npm install -g yarn react-native-cli
react-native init MyAwesomeProject
cd MyAwesomeProject

2. 添加 TS

接下来就是引入 TS,步骤如下:

  • 安装 TS
  • 安装 React Native TypeScript Transformer
  • 初始化一个空的 TS 配置文件,接下来将配置它
  • 添加一个空的 React Native TypeScript Transformer 配置文件,接下来将配置它
  • 添加 RN 和 React 的 typings
1
2
3
4
5
yarn add --dev typescript
yarn add --dev react-native-typescript-transformer
yarn tsc --init --pretty --jsx react
touch rn-cli.config.js
yarn add --dev @types/react @types/react-native

该 tsconfig.json 文件包含 TS 编译的所有设置。上面的命令创建的默认值大多很好。打开文件并取消注释以下行:

1
2
3
4
5
{
...
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
...
}

rn-cli.config.js 文件包含 React Native TypeScript Transformer 的设置。打开它并添加以下内容:

1
2
3
4
5
6
7
8
module.exports = {
getTransformModulePath() {
return require.resolve("react-native-typescript-transformer");
},
getSourceExts() {
return ["ts", "tsx"];
}
};

3. 将代码迁移到 TS

将生成的 App.js 和 tests/App.js 文件重命名为 App.tsx 。index.js 需要使用 .js 扩展名。所有新文件都应使用 .tsx 扩展名(或者 .ts,前提是该文件不包含任何 JSX)。

接下来,打开 App.tsx 并修改文件顶部的导入:

1
2
3
-import React, { Component } from 'react';
+import React from 'react'
+import { Component } from 'react';

现在应该能够运行 RN 应用程序。

4. 添加 TS 项目测试架构

选用 Jest,添加 ts-jest 到 devDependencies。

1
yarn add --dev ts-jest

然后,打开 package.json 并用 jest 以下内容替换该字段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"transform": {
"^.+\\.(js)$": "<rootDir>/node_modules/babel-jest",
"\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"testPathIgnorePatterns": [
"\\.snap$",
"<rootDir>/node_modules/"
],
"cacheDirectory": ".jest/cache"
}

ts-jest 将配置 Jest 运行 .ts 和 .tsx 文件。

5. 安装类型声明依赖项

需要 Jest,React 和 React Native 以及 React Test Renderer 的类型。将这些声明文件包保存到 dev 依赖项中,因为我们不会将此包作为库发布到 npm 。如果我们是,我们可能必须将其中一些添加为常规依赖项。

1
yarn add --dev @types/jest @types/react @types/react-native @types/react-test-renderer

可以查看更多关于 .d.ts 文件.

6. 忽略更多文件

在 .gitignore 文件添加以下内容:

1
2
3
# Jest
#
.jest/

7. 添加 RN 组件

继续创建一个 Hello.tsx 组件。创建 components 目录并添加以下示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// components/Hello.tsx
import React from "react"
import { Button, StyleSheet, Text, View } from "react-native"

export interface Props {
name: string
enthusiasmLevel?: number
onIncrement?: () => void
onDecrement?: () => void
}

interface State {
enthusiasmLevel: number
}

export class Hello extends React.Component<Props, State> {
constructor(props: Props) {
super(props)

if ((props.enthusiasmLevel || 0) <= 0) {
throw new Error("You could be a little more enthusiastic. :D")
}

this.state = {
enthusiasmLevel: props.enthusiasmLevel || 1
}
}

onIncrement = () => this.setState({ enthusiasmLevel: this.state.enthusiasmLevel + 1 });
onDecrement = () => this.setState({ enthusiasmLevel: this.state.enthusiasmLevel - 1 });
getExclamationMarks = (numChars: number) => Array(numChars + 1).join("!")

render() {
return (
<View style={styles.root}>
<Text style={styles.greeting}>
Hello {this.props.name + this.getExclamationMarks(this.state.enthusiasmLevel)}
</Text>

<View style={styles.buttons}>
<View style={styles.button}>
<Button
title="-"
onPress={this.onDecrement}
accessibilityLabel="decrement"
color="red"
/>
</View>

<View style={styles.button}>
<Button
title="+"
onPress={this.onIncrement}
accessibilityLabel="increment"
color="blue"
/>
</View>
</View>
</View>
)
}
}

// styles
const styles = StyleSheet.create({
root: {
alignItems: "center",
alignSelf: "center"
},
buttons: {
flexDirection: "row",
minHeight: 70,
alignItems: "stretch",
alignSelf: "center",
borderWidth: 5
},
button: {
flex: 1,
paddingVertical: 0
},
greeting: {
color: "#999",
fontWeight: "bold"
}
})

8. 添加组件测试

安装 react-addons-test-utils

1
yarn add --dev react-addons-test-utils

现在在 tests 的 components 目录中创建一个文件夹并添加一个测试 Hello.tsx:

1
2
3
4
5
6
7
8
9
10
// components/__tests__/Hello.tsx
import React from 'react'
import renderer from 'react-test-renderer'

import { Hello } from "../Hello"

it("renders correctly with defaults", () => {
const button = renderer.create(<Hello name="World" enthusiasmLevel={1} />).toJSON()
expect(button).toMatchSnapshot()
})

第一次运行测试时,它将创建渲染组件的快照并将其存储在 components/tests/snapshots/Hello.tsx.snap 文件中。修改组件时,您需要更新快照并查看更新以进行无意的更改。

您可以在 此处阅读 有关测试 RN 组件的更多信息。

-------------本文结束感谢您的阅读-------------