原生RN項(xiàng)目與Taro如何共存?
我們團(tuán)隊(duì)一開始就有實(shí)踐原生React Native的項(xiàng)目,很長(zhǎng)一段時(shí)間,
所有的業(yè)務(wù)模塊都是在一個(gè)項(xiàng)目里面開發(fā)維護(hù),時(shí)間久了這個(gè)項(xiàng)目就變成了一個(gè)巨無霸項(xiàng)目.
再加上后來引進(jìn)了基于Taro開發(fā)的rn項(xiàng)目,為了保證原生與Taro的RN共存,
不管是原生rn項(xiàng)目還是taro項(xiàng)目的package.json文件的main對(duì)外導(dǎo)出的索引文件格式都是一致的.
我們使用以下方案來維護(hù)我們的代碼.
使用npm來管理我們的業(yè)務(wù)模塊
RN業(yè)務(wù)的主工程
這是我最初實(shí)踐的方案,首先我們創(chuàng)建一個(gè)項(xiàng)目為RN的主工程.
里面沒有任何的業(yè)務(wù)代碼,只有在根目錄下有一個(gè)index.js的業(yè)務(wù)索引文件.
它大概是這樣的:
import { AppRegistry} from 'react-native';
import Module1 from 'Module1';
import Module2 from 'Module2';
import Module3 from 'Module3';
AppRegistry.registerComponent('Module1', () => Module1);
AppRegistry.registerComponent('Module2', () => Module2);
AppRegistry.registerComponent('Module3', () => Module3);
之前的一篇文章我已經(jīng)提到,我們所有的模塊依賴都是統(tǒng)一的,并且版本鎖死.
有興趣的可以點(diǎn)擊查看:
所以我的主工程的依賴與業(yè)務(wù)模塊的依賴是保持一致的.
使用NPM管理業(yè)務(wù)模塊
我們會(huì)把所有的業(yè)務(wù)模塊當(dāng)成npm來管理,因?yàn)閚pm有很多的生命周期鉤子使用.
在統(tǒng)一了npm script 命令之后,很容易統(tǒng)一管理他們.
當(dāng)然這些業(yè)務(wù)模塊我們不會(huì)把他發(fā)布到npm服務(wù)器上,因?yàn)闃I(yè)務(wù)代碼會(huì)頻繁變動(dòng),如果每一次提交都要上傳到npm服務(wù)器,自然會(huì)添加開發(fā)人員的代碼管理成本(發(fā)布npm包很煩的)
所以我們使用 npm + git
地址來拉取我們的業(yè)務(wù)模塊.
例如:
主工程的package.json
{
"name": "base",
"version": "0.0.6",
"scripts": {
"build":"構(gòu)建rn的相關(guān)操作"
},
"dependencies": {
"公共依賴包": "1.0.0",
"Module1": "http://xxx.com/webfront/Module1.git",
"Module2": "http://xxx.com/webfront/Module2.git",
"Module3": "http://xxx.com/webfront/Module3.git",
}
}
業(yè)務(wù)模塊的package.json
業(yè)務(wù)模塊添加了postinstall,在使用npm拉取業(yè)務(wù)模塊成功之后,業(yè)務(wù)模塊會(huì)在 node_modules
中構(gòu)建自己的項(xiàng)目,提供主工程的index.js
使用
{
"name": "buz",
"version": "0.0.1",
"main": "main.js", // main字段要指向rn的索引文件
"scripts": {
"build":"構(gòu)建rn的相關(guān)操作",
"postinstall":"npm run build"
},
"dependencies": {
"公共依賴包": "1.0.0"
}
}
統(tǒng)一對(duì)外輸出的main.js文件
"use strict";
// 根據(jù)端的環(huán)境變量判斷是否對(duì)外輸出什么文件
if (process.env.TARO_ENV === 'weapp' || process.env.TARO_ENV === 'h5') {
module.exports = require('./dist/index');
module.exports.default = module.exports
} else {
// taro系工程,標(biāo)準(zhǔn)對(duì)外輸出
Object.defineProperty(exports, "__esModule", {
value: true
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var _app = _interopRequireDefault(require("./rn_temp/app"));
exports.APP = _app.default;
}
業(yè)務(wù)模塊之間相互調(diào)試
業(yè)務(wù)與業(yè)務(wù)之間肯定會(huì)有相互聯(lián)調(diào)的情況,以上的方案業(yè)務(wù)模塊只能獨(dú)立運(yùn)行自己的代碼,當(dāng)我們想要跳轉(zhuǎn)到其他RN頁面的時(shí)候,那就不行了.
其實(shí)我們可以讓所有的業(yè)務(wù)模塊跟主模塊一樣,在開發(fā)調(diào)試的時(shí)候引入所有的業(yè)務(wù)模塊.
這樣所有的業(yè)務(wù)代碼都可以跑起來了,區(qū)別只在于其他業(yè)務(wù)模塊放在node_modules
中,不能修改代碼.
該方案的優(yōu)劣勢(shì)
該方案建議中型的項(xiàng)目推薦
優(yōu)點(diǎn):
可以原生RN與Taro共存,只要對(duì)外導(dǎo)出的main規(guī)范一致,主工程就可以作為統(tǒng)一模塊注冊(cè)
所有業(yè)務(wù)模塊單獨(dú)維護(hù),避免了項(xiàng)目巨無霸的產(chǎn)生
業(yè)務(wù)與業(yè)務(wù)之間也可以相互跳轉(zhuǎn),單獨(dú)一個(gè)業(yè)務(wù)模塊也可以拉起完整的rn項(xiàng)目
缺點(diǎn):
npm install 項(xiàng)目的時(shí)候會(huì)非常耗時(shí),因?yàn)椴粏我惭b依賴,業(yè)務(wù)模塊也會(huì)在postinstall的時(shí)候構(gòu)建項(xiàng)目.
業(yè)務(wù)模塊更新之后,必須要重新npm install
尾巴
該方案面向中等大小項(xiàng)目的rn項(xiàng)目,要是你跟我一樣幾十個(gè)業(yè)務(wù)模塊在同時(shí)開發(fā).會(huì)帶來更大的挑戰(zhàn).
后續(xù)文章我會(huì)介紹基于Taro的RN端終極管理辦法.
同時(shí)也會(huì)解決以上所有的缺點(diǎn).