使用TypeScript開發ReactNative應用的簡單示例

最近小小嚐試了下 ReactNative + TypeScript 開發APP,爬了無數坑之後總算弄出來個結果,重要的地方記錄下,後面會附上示例代碼:

1、開發工具的選擇
windows 平臺我接觸的開發工具主要三個,
WebStorm,Intellij IDEA 2016.2 版本,https://www.jetbrains.com/
這兩個我都試過,開發完全沒問題的,還有PHPStorm估計也行吧,沒試過。
另外還有一個是VisualStudioCode:https://code.visualstudio.com/b?utm_expid=101350005-27.GqBWbOBuSRqlazQC_nNSRg.1
對與 iOS 平臺應該是不用選的就是 Nuclide 了吧,我是沒用過哈,不知道怎麼用,不過用過 Atom 感覺還是很酷的。
平時習慣用 jetbrains 的 IDE ,每個都絕對神器,VisualCode 感覺實在太難用了,堅持了一段時間還是放棄了。
下面示例都是用的 Intellij IDEA 2016.2
預覽下:
這裏寫圖片描述

經過一番配置後,import 等導入和代碼提示等等都是沒問題的

2、基礎開發環境安裝
這個我就不說了,直接看這個網站就行了上面已經寫得很完善了 http://reactnative.cn/ ,照着文檔安裝配置應該沒什麼問題的,文檔看不懂的話網站的站長博客裏面還有全套的視頻講解非常詳細了,地址:http://reactnative.cn/post/759

3、安裝 TypeScript 開發環境

# 先 cd 到你的項目目錄,如 myproject 目錄下再執行下面命令
npm install -g typescript
npm install typescript
tsc --init

# 未安裝 tsd 則先安裝再進行項目初始化
npm install -g tsd

tsd init && tsd install react-native --save

tsd 初始化安裝後,會生成 tsconfig.json 文件,貌似 react-native 初始化新項目的時候就有這麼個文件來着,忘了,如果tsd初始化之前已存在該文件可直接刪除。

查看 tsconfig.json 文件

{
    "compilerOptions": {
        "target": "es6",
        "allowJs": true,
        "jsx": "react",
        //"outDir": "artifacts",
        //"rootDir": "src",
        "sourceMap": false,
        "noImplicitAny": false
    },
    "filesGlob": [
        "typings/**/*.d.ts",
        "src/**/*.ts",
        "src/**/*.tsx"
    ],
    "exclude": [
        "node_modules"
    ]
}

個人建議是 outDir 參數建議不要設置,使用默認值就行,這樣每次修改 .ts 文件後就會直接在當前目錄下生成同名的 es6語法編譯後 .js 文件,當 index.android.js 入口文件加載項目文件時則很方便,如下圖:

這裏寫圖片描述

以上配置完成就可以開始使用 TypeScript 開發了。

簡單做了個 List 加載文章列表的功能,實現起來很簡單方便,和原生Android開發比起來簡直快了太多太多。

這裏寫圖片描述

不過一開始遇到了很多坑,主要還是由於對 TypeScript 不太熟悉

如 style 的設置,總是提示類型錯誤:

Error:(20, 15) TS2322:Type '{ flex: number; flexDirection: string; }' is not assignable to type 'ViewStyle'.
  Types of property 'flexDirection' are incompatible.
    Type 'string' is not assignable to type '"row" | "column" | "row-reverse" | "column-reverse"'.
      Type 'string' is not assignable to type '"column-reverse"'.

這裏寫圖片描述

類似上面這種錯誤,很是莫名其妙,搞了好半天才明白原來樣式參數配置是需要進行類型轉換,這也是 TypeScript很特色的地方啦

如下面這樣:

這裏寫圖片描述

4、TypeScript 跟 ReactNative 開發的關係
最後說一下這兩者是如何發生關係的,可能還有跟我一樣的小白還沒弄清楚,我就按照自己的理解來說啦,
你用 TypeScript 語法寫的 .ts .tsx 等後綴的程序是不能直接運行的,而是會被 tsconfig.json 配置中的 “target”: “es6”, 這項配置轉換爲 es6 語法的 .js 文件。
TypeScript 中的 import 只會加載 .ts .tsx 後綴的文件,而 Javascript 中的 import 只能加載 .js 等後綴的文件,
所以,當 ReactNative 啓動時,首先加載入口文件,如 index.android.js ,代碼如下:

import { AppRegistry } from 'react-native';
import IndexNavigator from './application/src/controller/navigator/IndexNavigator';
AppRegistry.registerComponent('mogudan', () => IndexNavigator);

其中 import IndexNavigator from … 這一行加載的不是 IndexNavigator.ts 而是編譯後生成的 IndexNavigator.js 文件,下面對比兩個文件的差異:

IndexNavigator.ts

/**
 * Created by ZHOUZ on 2016-08-26.
 */
import * as React from 'react';
import {Navigator}  from 'react-native';

import IndexPage from '../page/IndexPage'

export default class IndexNavigator extends React.Component<any, any> {
    render() {
        let defaultName = 'IndexPage3311113';
        let defaultComponent = IndexPage;
        return (
            <Navigator
                initialRoute={{ name: defaultName, component: defaultComponent }}
                configureScene={(route) => Navigator.SceneConfigs.VerticalDownSwipeJump }
                renderScene={(route: any, navigator) => {
                    let Component = route.component;
                    return <Component {...route.params} navigator={navigator} />
                }}
            />
        );
    }
}

IndexNavigator.js
爲自動編譯後生成的es6語法的 javascript 代碼

"use strict";
var __assign = (this && this.__assign) || Object.assign || function(t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
        s = arguments[i];
        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
            t[p] = s[p];
    }
    return t;
};
/**
 * Created by ZHOUZ on 2016-08-26.
 */
const React = require('react');
const react_native_1 = require('react-native');
const IndexPage_1 = require('../page/IndexPage');
class IndexNavigator extends React.Component {
    render() {
        let defaultName = 'IndexPage3311113';
        let defaultComponent = IndexPage_1.default;
        return (React.createElement(react_native_1.Navigator, {initialRoute: { name: defaultName, component: defaultComponent }, configureScene: (route) => react_native_1.Navigator.SceneConfigs.VerticalDownSwipeJump, renderScene: (route, navigator) => {
            let Component = route.component;
            return React.createElement(Component, __assign({}, route.params, {navigator: navigator}));
        }}));
    }
}
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = IndexNavigator;

大概就是這樣了,最最後放上我做的示例代碼,只包含 application 目錄下的文件,android,ios 目錄都是 react-native 自動生成的大家都一樣的。

文件下載地址: http://download.csdn.net/detail/zsjangel/9618350

補充一個問題,開發時使用 fetch 會遇到提示找不到的解決辦法,
http://blog.csdn.net/zhouzme/article/details/52390197

發佈了202 篇原創文章 · 獲贊 132 · 訪問量 132萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章