在实际开发过程中,经常需要同时运行和修改多个React Native工程,比如运行github上的开源项目以观察某种控件的实际效果。那么此时,各项目下的初始化(npm install)就会非常的痛苦,因为React Native的文件非常大,以0.17.0为例,安装后达到309MB。尽管,我们可以通过阿里npm等镜像站的方式加速下载的过程,但是下载后的进一步编译也非常地耗时。
此外,多React Native工程还带来了React Native自身的冗余,如果创建了十几个工程,那么多占用的空间轻松达到3GB以上,非常地不友好。
npm link原理
我的解决思路是:用npm link替代npm install。npm link [package-name]
命令的原理是,去[prefix]/lib/node_modules/下检索是否已经全局安装了当前的package,如果是,则直接用软链接的方法在本地路径指向全局package。如果没检索到,则会先在全局路径下安装该package,再去建立软链接。npm获取全局路径的命令是:npm config get prefix
。
需要注意的是,有package.json的路径下,不要类比npm install
,就这么执行npm link
。此时npm link会把当前路径作为一个本地package,在全局路径下创建一个软链接。由此可知,npm link并不会像npm install一样,读取package.json中的依赖并自动配置。
配置过程
npm install -g react-native cd [program_path] npm link react-native
简单三步搞定。然后运行react-native run-android
,打个Android包检测一下。
纳尼,报错如下:
Looks like you installed react-native globally,maybe you meant react-native-cli?
To fix the issue,run:
npm uninstall -g react-native
npm install -g react-native-cli
原因很简单,react-native框架其实由两个部分组成:react-native和react-native-cli,前者用于提供编译环境,后者则是封装了react-native开发过程中所要用到的命令,如react-native start
,实质就是封装了sh ./node_modules/react-native/packager/packager.sh
。
官方文档要求全局安装react-native-cli,但是局部安装react-native,这是有原因的。如果你先全局安装了react-native-cli,会在/usr/local/bin下生成一个名为react-native的软链接,其指向为:react-native -> ../lib/node_modules/react-native-cli/index.js*
。而随后再次"全局"安装react-native的时候,又会生成一个名为react-native的软链接,覆盖了react-native-cli安装时生成的软链接,其指向是:../lib/node_modules/react-native/local-cli/wrong-react-native.js
。由此可见,React Native官方已经意识到了这个问题,然而不知何原因并不推荐全局安装React Native。然而笔者从节约硬盘空间和加快初始化的角度,认为还是有必要全局安装React Native,从而快速npm link的,所以有必要研究该报错的原理。
因此,针对这个报错,两种解决方法:
先
npm install -g react-native
,再npm install -g react-native-cli
。然而,如果以后使用过程中又升级了全局React Native,此时需看方案2。cd /usr/local/bin
,ln -s ../lib/node_modules/react-native-cli/index.js react-native
,即可重新创建一个指向react-native-cli的软链接。如果prefix的地址不是默认的,则ln -s prefix/lib/node_modules/react-native-cli/index.js react-native
。
缺陷
当前这个自动添加统一依赖的方法,存在一个问题。所有依赖于全局路径下的React Native都必须是一个版本的,npm link并没有提供多版本号依赖的解决方法。因此,还是建议选择一个常用的React Native版本安装在全局路径,个别需求其他版本号的React Native的项目,使用npm install
来配置局部依赖。
插说一句,npm自身的依赖管理设计还是非常优秀的,然而React Native实在是太大了,而且我们完全有理由相信,他会更大。他其实应该是与Android SDK,Java SDK一般重量级的开发SDK,因此更应该借鉴rvm,设计一个React Native Version Manager。然而却委身于node_modules,因而产生了这种无奈的冗余。
====================================
如果您觉得我的文章对您有所启迪,请点击文末的推荐按钮,您的鼓励将会成为我坚持写作的莫大激励。 by DesGemini