TL.DR
这篇吐槽文是 How it feels to learn JavaScript in 2016 的 RN 版本,并没有作指南的意思。
嗨,我准备搞个 side project,想用 React Native 来做。你是我们这 RN 最专精的老哥,能不能指点一哈?
没问题。
太好了。我刚看了一下 RN 的官网,装个 node 和 watchman 就可以了吧?
你是怎么装的 node?
呃,brew install node。
这可不行,你要先装 nvm。
nvm?
Node Version Manager。node 是前端圈的产物,这帮家伙都是疯子,迭代起来
六亲不认。RN 的开发工具链深度依赖 node,你一个星期前写的 demo,更新 node 以后搞不好就跑不了了。
nvm 允许你安装多个 node 版本,并随需要切换。你可以装一个 lts 版本作为主力版本,再安装最新版本跟踪社区的进度,像这样nvm install lts
有道理。
接下来用 Yarn 装 react-native-cli。
Yarn?
新的 node 包管理器,FB出品,必属精品。完全兼容现有的 npm 包,命令也差不多。
直接用 npm 不就好了?。
Yarn 跑起来更高、更快、更强,你值得拥有。后续用到的其它 npm 包也建议用 Yarn 来管理。
装好了。
编辑器方面,我现在在用 Sublime Text,能找到的插件对 RN 的支持都很初级,你有什么推荐吗?
FB 基于 Atom 做了个 RN 的插件—— Nuclide,RN 官方支持。
好,官方支持,我喜欢。
微软也基于自己的 Visual Studio Code 做了个RN的插件—— vscode-react-native,也很不错,感觉比 FB 的还要稳定一些,微软做开发工具还是很有一套的。而且 VSC 的维护者有开通 微博,吐槽更方便。
喔。。。
说到开发工具,WebStorm 现在也支持 RN 开发了。
喔。。。
还有专门为 RN 制作的 IDE—— Deco,支持可视化编程,也不错。
喔。。。
开源的 react-native-debugger 也做得越来越好了。
给个痛快。
。。。就 VSC 吧。
export default class App extends Component<Props> { //... square(n) { return n * n; } test() { this.square("2") } }
这样没有报错哦。
JS 是弱类型语言,需要类型验证之类的静态分析的话,你需要 Flow。
让我猜猜看,FB 出品,必属精品?
没错!你看看你的工程,里面已经附带了一个 .flowconfig 文件了吧,拉到最下面,可以看到这个工程需求的 flow 版本
[version] ^0.65.0不同版本的 react-native-cli 可能会指定不同版本的 flow,把 flow 作为本地包来装会比较好。当然,要用 Yarn
yarn add flow-bin@0.65.0 --dev装好之后,手动跑一下
yarn run flow就可以了。
每次都要手动执行?
当然不可能那么龊。VSC有个 插件 支持 flow,装好之后设置一下
# Workspace Settings { "javascript.validate.enable": false,"flow.pathToFlow": "./node_modules/.bin/flow" }# package.json "scripts": { "start": "node node_modules/react-native/local-cli/cli.js start","test": "jest","flow": "flow" //加上这行 },用起来就和在 Xcode 里写 OC 差不多了,look
Flow 只是类型检查吗?这样做还是不会报错哦
export default class App extends Component<Props> { //... test() { } test() { } }
嗯。。。被你发现了。
FB出品,必属精品?
这个是 JS 的问题啦, JS支持fucntion有相同的名字。
那有工具能解决吗?
有, TypeScript。
。。。你确定这只是个工具?
编程语言也算工具嘛。
只不过是静态分析,居然要换语言。。。
别担心,没有听起来那么夸张。
大体上,TypeScript 只是为 JS 加上了数据类型等各种强类型语言的特性,语法什么的都差不多的。而且,TypeScript 只是一个开发过程中的概念,实际运行的时候跑的还是 JS 哦。
就像 OC 那样,写的时候是 OC,跑起来实际上是 C++?
对!你真聪明,不愧是想要选用 RN 的人。
(我已经有点后悔了。。。) TypeScript 要怎么弄?
首先你要能在 ts 代码中使用 React 和 React Native 的代码。
呃,为每个库中的每个类型加一个ts中对应的声明吗?
差不多是这样。但不用你亲自动手,社区已经有不少吃螃蟹的人了,你直接用就好。
yarn add --dev react-native-typescript-transformer typescript @types/react @types/react-native
这个 transformer 是做什么的?
它负责把ts代码编译成js,然后交给 React Native Packager 处理。Packager 本身并不能直接处理 ts 代码。
Packager?
顾名思义,它会把你的所有 js 文件打包成一个 bundle 丢给设备使用。在引入 TypeScript 之前,它的主要作用是将你的 js 代码,使用 babel 转换成设备适用的 js 代码。。。
等等,babel?
啊,你知道 js 有不同的版本吧,ES5、ES6 和 ES7/8 等等,不同的设备支持的 js 版本是不同的。但在开发时你总是希望固定用一个版本的 js,所以需要有一个工具将你写的 js 转换成特定版本的 js,然后才能丢给设备使用。babel 就是这样的一个工具。
所以在引入 TypeScript 之后。。。
是的,多了一步。你的 ts 代码要先通过刚才说的 transformer 编译成某个版本的 js 代码,才能交给 React Native Packager 做后续的处理。
整个过程大体来说是这样的,look
真麻烦。。。
做起来很简单的。在工程根目录下新建一个 rn-cli.config.js 文件,它是 Packager 的配置文件。
# rn-cli.config.js module.exports = { getTransformModulePath() { return require.resolve('react-native-typescript-transformer') },getSourceExts() { return ['ts','tsx']; } }
好吧。我试试看
总算有点写代码的感觉了。前端开发者们平时的生活都是这么水深火热的吗。。。
理解万岁,理解万岁。
现在我可以开工了吧?
还没有,你只是设置好了静态环境。如果你现在用 VSC 的 debugger 来尝试调试,你在 ts 代码中设置的断点是无效的哦。
为什么还不行??
你设置的断点是在 ts 代码里,对应到最终生成的 js 代码时,断点的位置也要相应发生变化。
说人话。
你要设置 tsconfig.json,让它把 ts 代码到 js 代码的映射关系记录下来
{ "compilerOptions": { //... "sourceRoot": "src","inlineSourceMap": true },}这样才能让断点正常工作。
好了,环境配好了,你也差不多对整个工具链有所了解了吧。
说出来你可能不信,在你介绍的时候,我已经用 OC 差不多写完了。贵圈太乱了,我还是回去写 OC 吧。跟 RN 比起来,用 Xcode 写 Swift 都显得轻松愉快呢。。。