<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cross-Platform on Time Friend</title><link>https://time-friend.com/zh/categories/cross-platform/</link><description>Recent content in Cross-Platform on Time Friend</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Wed, 16 Dec 2020 22:17:36 +0000</lastBuildDate><atom:link href="https://time-friend.com/zh/categories/cross-platform/index.xml" rel="self" type="application/rss+xml"/><item><title>使用Taro开发各端的顺序建议</title><link>https://time-friend.com/zh/archive/recommended-order-for-developing-taro-multi-platform-applications/</link><pubDate>Wed, 16 Dec 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/recommended-order-for-developing-taro-multi-platform-applications/</guid><description>&lt;h2 id="以最小成本开发taro各端"&gt;以最小成本开发Taro各端&lt;/h2&gt;
&lt;p&gt;现在公司里面的所有小程序,快应用,rn等等都在使用Taro在开发.&lt;/p&gt;
&lt;p&gt;如果只兼容一端的话,使用Taro开发,没有任何问题.&lt;/p&gt;
&lt;p&gt;但是又想一次开发,各端正常运行的话,在很多的细节上是要花一点心思的.&lt;/p&gt;
&lt;p&gt;每一端有每一端的难.&lt;/p&gt;
&lt;h2 id="开发难度排序"&gt;开发难度排序&lt;/h2&gt;
&lt;p&gt;华为快应用 &amp;gt; 快应用 &amp;gt; React Native &amp;gt; Swan小程序 &amp;gt; 微信小程序 &amp;gt; H5&lt;/p&gt;
&lt;h3 id="关于快应用"&gt;关于快应用&lt;/h3&gt;
&lt;p&gt;在开发过程中,如果有涉及到快应用的业务,建议优先开发快应用.&lt;/p&gt;
&lt;p&gt;快应用的布局标准跟js容器环境跟其他的小程序或者是H5有一定的差异.&lt;/p&gt;
&lt;p&gt;并且华为快应用与其他快应用有很多莫名其妙的差异.&lt;/p&gt;
&lt;p&gt;如果涉及到快应用,请谨慎对待开发时间.&lt;/p&gt;
&lt;p&gt;目前看来,快应用的对UI布局的支持与小程序有一定的差异.虽然使用Taro的样式区分,快应用与小程序确实可以使用一套同样的代码同时跑在两端上.&lt;/p&gt;
&lt;p&gt;但是在开发过程中,他们之间的差异有太多意想不到(快应用不符合W3C规范)的差异,建议UI布局相关的代码,各端单独布局.业务相关的可以使用一套代码. 就是布局样式独立,行为保持一致.&lt;/p&gt;
&lt;p&gt;不然会花掉太多的布局差异抹平的工作.&lt;/p&gt;
&lt;h3 id="关于react-native"&gt;关于React Native&lt;/h3&gt;
&lt;p&gt;React Native在UI布局上也只是部分支持W3C标准.虽然布局上不能跟小程序H5一样灵活,&lt;/p&gt;
&lt;p&gt;对比起快应用来,并不会多出一个要额外兼容的华为快应用.&lt;/p&gt;
&lt;p&gt;目前Taro封装的React Native的特性与小程序是非常接近的,
如果不过多调用太多冷门的API,基本上还是可以独立开发完成大部分UI编程.&lt;/p&gt;
&lt;p&gt;如果RN想要调用原生APP的组件,在目前开来会带来相当大的沟通成本.&lt;/p&gt;
&lt;p&gt;在开发中本身ios与安卓就有一定的特性差异,放到RN里实现后又会带来其他的差异.&lt;/p&gt;
&lt;p&gt;并且开发人员从一个人变成了三个人.&lt;/p&gt;
&lt;p&gt;如果桥接的组件太过于复杂,开发人员可能会有一种还不如自己独立开发的抱怨.&lt;/p&gt;
&lt;p&gt;这个时候多端一起开发,时间不一定会比独立开发要快.&lt;/p&gt;
&lt;h3 id="关于-swan小程序"&gt;关于 Swan小程序&lt;/h3&gt;
&lt;p&gt;Swan小程序与微信小程序已经非常接近了.&lt;/p&gt;
&lt;p&gt;就我们现有业务来说除了wifi不能实现以外,其他的基本上都跟微信小程序保持了一致.&lt;/p&gt;
&lt;p&gt;目前开发中,IDE的卡顿是Swan小程序最不好的开发体验.&lt;/p&gt;
&lt;p&gt;迭代中,swan小程序的基础库兼容方面也做得不是很好,&lt;/p&gt;
&lt;p&gt;好几次遇到莫名其妙的问题,都是因为基础库兼容不好导致的.&lt;/p&gt;</description></item><item><title>使用Taro开发的快应用如何优化体积</title><link>https://time-friend.com/zh/archive/how-to-optimize-bundle-size-for-quick-apps-developed-with-taro/</link><pubDate>Tue, 15 Dec 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/how-to-optimize-bundle-size-for-quick-apps-developed-with-taro/</guid><description>&lt;h2 id="快应用重复打包问题"&gt;快应用重复打包问题&lt;/h2&gt;
&lt;p&gt;使用Taro开发快应用,有一个问题绝对不能忽视,那就是体积问题.&lt;/p&gt;
&lt;p&gt;因为快应用打包的特性(1080以下)多个页面里,如果重复应用了一个第三方库,那么这个库的代码会一起打到这个页面中,导致一样的代码会存在多个页面中.&lt;/p&gt;
&lt;p&gt;因为目前1080版本的快应用没有全面铺开.如果你贸然升级自己快应用的最低平台版本号为1080.
你将会失去大量低版本的用户.&lt;/p&gt;
&lt;h2 id="官方给出的解决方案-1080以下版本"&gt;官方给出的解决方案 (1080以下版本)&lt;/h2&gt;
&lt;p&gt;当然快应用官方也意识到了这个问题,给出了最早期的解决方案.&lt;/p&gt;
&lt;p&gt;那就是将多个页面会依赖到的代码,全部在快应用初始化的时候挂载到全局变量上面.&lt;/p&gt;
&lt;p&gt;其他页面使用的时候,直接引用全局变量就可以了.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 入口文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;day&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;day&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalRef&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Object.&lt;span style="color:#a6e22e"&gt;getPrototypeOf&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;global&lt;/span&gt;) &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;global&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;globalRef&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;day&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;day&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 页面使用
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalRef&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Object.&lt;span style="color:#a6e22e"&gt;getPrototypeOf&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;global&lt;/span&gt;) &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;global&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;day&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalRef&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;day&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;day&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="分析项目使用了哪些公共代码"&gt;分析项目使用了哪些公共代码&lt;/h2&gt;
&lt;p&gt;重复打包的内容,npm依赖会占大头,也有可能是自己写的公共代码.&lt;/p&gt;
&lt;h3 id="我们的项目用到了哪些npm依赖"&gt;我们的项目用到了哪些npm依赖?&lt;/h3&gt;
&lt;p&gt;Taro打包之后,&lt;code&gt;dist/quickapp&lt;/code&gt; 下的构建产物会单独把所有项目能用到的npm包放到 &lt;code&gt;src/npm/&lt;/code&gt; 目录下.&lt;/p&gt;
&lt;h3 id="公共代码分析"&gt;公共代码分析&lt;/h3&gt;
&lt;p&gt;只要一个js被多个page引用,就必须会造成重复打包的问题.&lt;/p&gt;
&lt;h2 id="使用taro的-alias-特性解决重复打包的问题"&gt;使用Taro的 alias 特性解决重复打包的问题&lt;/h2&gt;
&lt;p&gt;alias 是应用路径别名的特性,他的实现原理很简单,在config文件中制定好路径替换规则.&lt;/p&gt;
&lt;p&gt;在taro打包的时候,直接替换应用路径成为正确的应用路径就可以了.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{ 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;@src&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;src&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;@plugin&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;src/plugin&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;@components&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;src/components&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="如何使用alias解决我们的打包问题"&gt;如何使用alias解决我们的打包问题&lt;/h3&gt;
&lt;p&gt;既然 alias有替换应用路径的问题,再加上我们的第三方库只要挂载到全局变量中就可以让所有页面都可以使用到.&lt;/p&gt;
&lt;p&gt;两个特性结合起来的解决方案就是这样的.&lt;/p&gt;
&lt;h4 id="第一步修改npm的alias"&gt;第一步,修改npm的alias&lt;/h4&gt;
&lt;p&gt;为什么要这样做,看到第二步你就会明白.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;classnames.ex 文件为classnames的映射文件.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;classnames&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;src/replacement/classnames.ex&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;prop-types&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;src/replacement/prop-types.ex&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;mobx&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;src/replacement/mobx.ex&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="第二步-制作替身依赖"&gt;第二步, 制作替身依赖&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;拷贝 &lt;code&gt;dist/quickapp/src/npm&lt;/code&gt; 中的内容到&lt;code&gt;src/replacement/npm&lt;/code&gt;中.&lt;/li&gt;
&lt;li&gt;在&lt;code&gt;src/replacement&lt;/code&gt;下新建一个&lt;code&gt;index.js&lt;/code&gt;文件,大致内容如下&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;crypt&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./npm/crypt/crypt&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;classnames&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./npm/classnames&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;globalRef&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Object.&lt;span style="color:#a6e22e"&gt;getPrototypeOf&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;global&lt;/span&gt;) &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;global&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;globalRef&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;classnames&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;classnames&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;globalRef&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;crypt&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;crypt&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol start="3"&gt;
&lt;li&gt;制作npm依赖映射的文件&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;看到这一步,你应该就会明白为什么alias为什么会将正常的npm依赖路径替换到一个映射文件.&lt;/p&gt;</description></item><item><title>Taro跨端开发之让Taro UI支持React Native</title><link>https://time-friend.com/zh/archive/making-taro-ui-support-react-native/</link><pubDate>Thu, 27 Aug 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/making-taro-ui-support-react-native/</guid><description>&lt;h2 id="taro-ui-不支持rn的窘境"&gt;Taro UI 不支持RN的窘境&lt;/h2&gt;
&lt;p&gt;Taro UI 文档上很早就说明会有可能支持rn了,但是快一年多了,因为taro ui团队人力的问题一直没有兼容到rn.&lt;/p&gt;
&lt;p&gt;业务紧迫,我们等不到那一天了.自己动手丰衣足食.&lt;/p&gt;
&lt;h2 id="taro-传统组件打包在rn上的问题"&gt;Taro 传统组件打包在RN上的问题&lt;/h2&gt;
&lt;p&gt;一般来说,组件库打完包之后 dist/index.js文件会是这样的.&lt;/p&gt;
&lt;p&gt;根据运行时的环境变量区分是否要引入哪一个组件库.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TARO_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;weapp&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./weapp/ui&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TARO_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;h5&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./h5/ui&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./weapp/ui&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;理想模式下,只要加入一个rn的环境判断,就可以做到rn组件库的引入了.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TARO_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;weapp&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./weapp/ui&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TARO_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;h5&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./h5/ui&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TARO_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;rn&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 理想模式,只需要加这一段
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./rn/ui&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./weapp/ui&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可是现实不是这样的,rn如果引入组件库的索引文件,是dist/index.js,他会提前把所有端的代码全部预执行一遍.&lt;/p&gt;
&lt;p&gt;代码还没有真正运行,就因为其他端的代码不兼容,直接报错了. 所以这样硬核的引入方法是不可行的.&lt;/p&gt;
&lt;h2 id="rn组件库代码与其他端代码完全隔离"&gt;rn组件库代码与其他端代码完全隔离&lt;/h2&gt;
&lt;h3 id="uijs文件的改动"&gt;ui.js文件的改动&lt;/h3&gt;
&lt;p&gt;在src下边有一个ui.js文件,大致内容是这样的:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Taro&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;@tarojs/taro&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./style/index.scss&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;as&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AActionSheet&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./components/action-sheet&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;as&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AActionSheetItem&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./components/action-sheet/body/item&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;as&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AText&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./components/text&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;as&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AToast&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./components/toast&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;as&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AButton&lt;/span&gt; } &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./components/button&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 其他组件...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;为了更好的在原来组件库上做rn的兼容,利用taro可以根据文件后缀名区分端的特性就排上用场了.
需要新建一个&lt;code&gt;ui.rn.js&lt;/code&gt;&lt;/p&gt;</description></item><item><title>Taro跨端开发之多业务模块管理 React Native篇(终篇)</title><link>https://time-friend.com/zh/archive/multi-business-module-management-react-native-final/</link><pubDate>Tue, 25 Aug 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/multi-business-module-management-react-native-final/</guid><description>&lt;h2 id="react-native-热更新方案"&gt;React Native 热更新方案&lt;/h2&gt;
&lt;p&gt;rn的业务越来越庞大,同时协同的团队越来越多. rn的动态化就必须提上日程了.
对于rn热更新,首当其冲的问题就是分包.&lt;/p&gt;
&lt;p&gt;rn的基础库很大,再加上我们依赖了很多的三方库.这些代码就必须在分包的时候单独剥离出来.
业务包让他比较纯粹的只有业务代码. 这样就可以保证业务包的体积比较小,保证热更新时候的速度.&lt;/p&gt;
&lt;h3 id="使用metro分包"&gt;使用metro分包&lt;/h3&gt;
&lt;p&gt;React Native 提供的 metro 自带分包功能。metro我们本来就一直在用,只要在metro打包的时候,提供相应的打包规则.
就可以实现rn的分包了.&lt;/p&gt;
&lt;p&gt;示例: ios打包&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;node ./node_modules/react-native/local-cli/cli.js bundle --platform ios --dev false --entry-file rn入口文件.js --bundle-output ./xxx/ --assets-dest ./xxx/ --config /&lt;span style="color:#f92672"&gt;{&lt;/span&gt;你的绝对路径&lt;span style="color:#f92672"&gt;}&lt;/span&gt;/你的metro配置文件.js
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="metro-关键api介绍"&gt;metro 关键api介绍&lt;/h3&gt;
&lt;p&gt;我们分包需要用的选项主要是两个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;createModuleIdFactory：这个函数传入要打包的 module 文件的绝对路径，返回这个 module 在打包的时候生成的 id。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;processModuleFilter：这个函数传入 module 信息，返回一个 boolean 值，false 则表示这个文件不打入当前的包。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="主工程分包"&gt;主工程分包&lt;/h3&gt;
&lt;p&gt;之前我们有提到过我们有一个项目是主工程,里面没有任何的业务代码.只有一些代码运行需要的所有依赖.&lt;/p&gt;
&lt;p&gt;我们需要将所有的依赖全部收集起来,当业务模块打包的时候,发现本地有这个依赖就可以使用 &lt;code&gt;processModuleFilter&lt;/code&gt;方法排除掉.&lt;/p&gt;
&lt;p&gt;因为我们的主工程与业务项目的依赖版本都是高度统一的.
所以我们node_modules下面的依赖包路径都是完全一致的.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://time-friend.com/archive/h8gasmt9u5c/"&gt;Taro跨端开发之依赖管理&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;主工程的metro配置文件示例:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createModuleIdFactory&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt; =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 在这里我们拿到依赖的文件路径,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 我们需要在这个函数块中,将路径以收集并且将这些数据生成文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 部署到我们内网的服务器中
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// 当业务模块需要打包的时候,是否要将代码打进包中,将以这个文件为依据
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;serializer&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;createModuleIdFactory&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;createModuleIdFactory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;主工程入口文件示例:&lt;/p&gt;</description></item><item><title>Taro跨端开发之多业务模块管理 React Native篇(中)</title><link>https://time-friend.com/zh/archive/multi-business-module-management-react-native-part-2/</link><pubDate>Sun, 23 Aug 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/multi-business-module-management-react-native-part-2/</guid><description>&lt;h2 id="实现一个简单的模块管理工具解决npm拉取业务模块慢的问题"&gt;实现一个简单的模块管理工具,解决npm拉取业务模块慢的问题&lt;/h2&gt;
&lt;p&gt;使用npm拉取git仓库,速度其实还是可以接受的.
主要慢的地方在于 &lt;code&gt;postinstall&lt;/code&gt;的时候需要在npm拉取git仓库的时候,需要重新构建项目代码.还有一点就是业务模块也有依赖,npm install的时候也需要重新拉取相同的依赖.&lt;/p&gt;
&lt;p&gt;这两个步骤其实是可以省略的,解决的办法就是可以实现一个简单的模块管理工具来替代npm加载业务模块的处理.&lt;/p&gt;
&lt;h3 id="创建一个配置文件"&gt;创建一个配置文件&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Module1&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;url&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://xxx1.git&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;moduleName&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;模块名称&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;develop&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;taro&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Module2&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;url&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://xxx2.git&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;moduleName&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;模块名称&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;branch&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;develop&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;taro&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;因为每一个项目都会用到这一个文件,把这个文件放到服务器上.
在业务模块初始化的时候,自动拉取解析这个文件.再使用nodejs拉取相应的git仓库.&lt;/p&gt;
&lt;h3 id="拉取git仓库"&gt;拉取git仓库&lt;/h3&gt;
&lt;p&gt;使用&lt;code&gt;download-git-repo&lt;/code&gt;拉取git仓库的代码放到node_modules目录下.
这样在项目中,我就可以引用普通npm一样引入这个仓库的代码了.&lt;/p&gt;
&lt;p&gt;这是&lt;code&gt;download-git-repo&lt;/code&gt;的地址与使用方法
&lt;a href="https://www.npmjs.com/package/download-git-repo"&gt;https://www.npmjs.com/package/download-git-repo&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="模拟npm生命周期"&gt;模拟npm生命周期&lt;/h3&gt;
&lt;p&gt;代码拉下来之后,还需要用postinstall来构建业务代码,
所以需要使用nodejs遍历以下业务模块的目录,读取目录下的每一个packages.json.&lt;/p&gt;
&lt;p&gt;如果有npm钩子的,就执行一下里面的script.&lt;/p&gt;
&lt;p&gt;大致示例代码如下:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 示例代码,仅供参考
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;spawn&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;cross-spawn&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fse&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;fs-extra&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;packageData&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fse&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;readJsonSync&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./packages.json&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;packageData&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;scripts&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;preinstall&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;spawn&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sync&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;npm&amp;#39;&lt;/span&gt;,[&lt;span style="color:#e6db74"&gt;&amp;#39;run&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;preinstall&amp;#39;&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;packageData&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;scripts&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;postinstall&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;spawn&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sync&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;npm&amp;#39;&lt;/span&gt;,[&lt;span style="color:#e6db74"&gt;&amp;#39;run&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;postinstall&amp;#39;&lt;/span&gt;]);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="并发执行业务模块的npm钩子"&gt;并发执行业务模块的npm钩子&lt;/h3&gt;
&lt;p&gt;在npm执行postinstall的时候,并不是全部一股脑的全部执行.&lt;/p&gt;
&lt;p&gt;使用 yarn 安装依赖的时候,同时最多可以4个模块执行(npm install 没有具体研究).
所以构建业务模块的时候,总是会出现一个一个等的情况.&lt;/p&gt;</description></item><item><title>Taro跨端开发之多业务模块管理 React Native篇(上)</title><link>https://time-friend.com/zh/archive/multi-business-module-management-react-native-part-1/</link><pubDate>Fri, 21 Aug 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/multi-business-module-management-react-native-part-1/</guid><description>&lt;h2 id="原生rn项目与taro如何共存"&gt;原生RN项目与Taro如何共存?&lt;/h2&gt;
&lt;p&gt;我们团队一开始就有实践原生React Native的项目,很长一段时间,&lt;/p&gt;
&lt;p&gt;所有的业务模块都是在一个项目里面开发维护,时间久了这个项目就变成了一个巨无霸项目.&lt;/p&gt;
&lt;p&gt;再加上后来引进了基于Taro开发的rn项目,为了保证原生与Taro的RN共存,&lt;/p&gt;
&lt;p&gt;不管是原生rn项目还是taro项目的package.json文件的main对外导出的索引文件格式都是一致的.&lt;/p&gt;
&lt;p&gt;我们使用以下方案来维护我们的代码.&lt;/p&gt;
&lt;h2 id="使用npm来管理我们的业务模块"&gt;使用npm来管理我们的业务模块&lt;/h2&gt;
&lt;h3 id="rn业务的主工程"&gt;RN业务的主工程&lt;/h3&gt;
&lt;p&gt;这是我最初实践的方案,首先我们创建一个项目为RN的主工程.&lt;/p&gt;
&lt;p&gt;里面没有任何的业务代码,只有在根目录下有一个index.js的业务索引文件.&lt;/p&gt;
&lt;p&gt;它大概是这样的:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;AppRegistry&lt;/span&gt;} &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;react-native&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Module1&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Module1&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Module2&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Module2&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Module3&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Module3&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;AppRegistry&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;registerComponent&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Module1&amp;#39;&lt;/span&gt;, () =&amp;gt; &lt;span style="color:#a6e22e"&gt;Module1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;AppRegistry&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;registerComponent&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Module2&amp;#39;&lt;/span&gt;, () =&amp;gt; &lt;span style="color:#a6e22e"&gt;Module2&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;AppRegistry&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;registerComponent&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;Module3&amp;#39;&lt;/span&gt;, () =&amp;gt; &lt;span style="color:#a6e22e"&gt;Module3&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;之前的一篇文章我已经提到,我们所有的模块依赖都是统一的,并且版本锁死.&lt;/p&gt;
&lt;p&gt;有兴趣的可以点击查看:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://time-friend.com/archive/h8gasmt9u5c/"&gt;Taro跨端开发之依赖管理&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;所以我的主工程的依赖与业务模块的依赖是保持一致的.&lt;/p&gt;
&lt;h3 id="使用npm管理业务模块"&gt;使用NPM管理业务模块&lt;/h3&gt;
&lt;p&gt;我们会把所有的业务模块当成npm来管理,因为npm有很多的生命周期钩子使用.&lt;/p&gt;
&lt;p&gt;在统一了npm script 命令之后,很容易统一管理他们.&lt;/p&gt;
&lt;p&gt;当然这些业务模块我们不会把他发布到npm服务器上,因为业务代码会频繁变动,如果每一次提交都要上传到npm服务器,自然会添加开发人员的代码管理成本(发布npm包很烦的)&lt;/p&gt;
&lt;p&gt;所以我们使用 &lt;code&gt;npm + git&lt;/code&gt; 地址来拉取我们的业务模块.&lt;/p&gt;
&lt;p&gt;例如:&lt;/p&gt;
&lt;h4 id="主工程的packagejson"&gt;主工程的package.json&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;base&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;version&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;0.0.6&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;scripts&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;build&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;构建rn的相关操作&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;dependencies&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;公共依赖包&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;1.0.0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;Module1&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;http://xxx.com/webfront/Module1.git&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;Module2&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;http://xxx.com/webfront/Module2.git&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;Module3&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;http://xxx.com/webfront/Module3.git&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="业务模块的packagejson"&gt;业务模块的package.json&lt;/h4&gt;
&lt;p&gt;业务模块添加了postinstall,在使用npm拉取业务模块成功之后,业务模块会在 &lt;code&gt;node_modules&lt;/code&gt; 中构建自己的项目,提供主工程的&lt;code&gt;index.js&lt;/code&gt;使用&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;buz&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;version&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;0.0.1&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;main&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;main.js&amp;#34;&lt;/span&gt;, &lt;span style="color:#75715e"&gt;// main字段要指向rn的索引文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;scripts&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;build&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;构建rn的相关操作&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;postinstall&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;npm run build&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;dependencies&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;#34;公共依赖包&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;1.0.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id="统一对外输出的mainjs文件"&gt;统一对外输出的main.js文件&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;use strict&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 根据端的环境变量判断是否对外输出什么文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TARO_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;weapp&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;process&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;env&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;TARO_ENV&lt;/span&gt; &lt;span style="color:#f92672"&gt;===&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;h5&amp;#39;&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;./dist/index&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;} &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// taro系工程,标准对外输出
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Object.&lt;span style="color:#a6e22e"&gt;defineProperty&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;__esModule&amp;#34;&lt;/span&gt;, {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;function&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_interopRequireDefault&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;) { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;__esModule&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;obj&lt;/span&gt; }; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_app&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_interopRequireDefault&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;./rn_temp/app&amp;#34;&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;APP&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_app&lt;/span&gt;.&lt;span style="color:#66d9ef"&gt;default&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="业务模块之间相互调试"&gt;业务模块之间相互调试&lt;/h3&gt;
&lt;p&gt;业务与业务之间肯定会有相互联调的情况,以上的方案业务模块只能独立运行自己的代码,当我们想要跳转到其他RN页面的时候,那就不行了.&lt;/p&gt;</description></item><item><title>Taro跨端开发之依赖管理问题</title><link>https://time-friend.com/zh/archive/dependency-management-issues/</link><pubDate>Thu, 20 Aug 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/dependency-management-issues/</guid><description>&lt;p&gt;目前我们通过Taro触达的端已经有:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;微信小程序&lt;/li&gt;
&lt;li&gt;QQ小程序&lt;/li&gt;
&lt;li&gt;百度小程序&lt;/li&gt;
&lt;li&gt;React Native&lt;/li&gt;
&lt;li&gt;H5&lt;/li&gt;
&lt;li&gt;快应用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为了快速的让业务可以触达到各端,我们每一个业务模块都是独立的.&lt;/p&gt;
&lt;p&gt;他们根据业务需要,分别兼容到不同的端,等到构建的时候再将其进行组装成为一个完整的项目.&lt;/p&gt;
&lt;p&gt;为了满足以上需要,并且可以灵活开发.所以每一个业务模块都是可以独立开发,独立运行的,可以不依赖主工程.&lt;/p&gt;
&lt;p&gt;目前来说项目之间的关系已经比较类似&lt;code&gt;微前端&lt;/code&gt;了.&lt;/p&gt;
&lt;p&gt;因为大部分端(除了&lt;code&gt;React Native&lt;/code&gt;) 都不能做到热更新,所以相对微前端架构而言小程序们做不到&lt;code&gt;独立部署&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/d6454e7c0d292a7a302dc0d0bc9c8c48256752fc683e3f0e46b6591b201ad7b9.png" alt="图 1"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;关于Taro + React Native部分,后面会有专门的文章跟大家介绍我们是怎么玩的.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;今天就跟大家介绍一下,多业务,多团队,多端的代码管理中我们遇到的第一个问题: &lt;code&gt;依赖管理问题&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="所有项目依赖统一管理"&gt;所有项目依赖统一管理&lt;/h2&gt;
&lt;p&gt;因为业务模块很多,我们项目工程的差异必须保持高度统一,其中包括依赖.&lt;/p&gt;
&lt;h3 id="核心依赖集中管理"&gt;核心依赖集中管理&lt;/h3&gt;
&lt;p&gt;现在我们团队开发的跨端模块已经有几十个.为了方便管理,&lt;/p&gt;
&lt;p&gt;我将所有的依赖封装成了一个&lt;code&gt;npm包&lt;/code&gt;,里面没有任何的业务代码,只有稳定的依赖.&lt;/p&gt;
&lt;p&gt;所有的项目都会引入这个核心的依赖,以保证所有项目可以稳定运行.&lt;/p&gt;
&lt;h3 id="非核心依赖版本管理问题"&gt;非核心依赖版本管理问题&lt;/h3&gt;
&lt;p&gt;如果是非核心依赖,我们将使用我们自研的&lt;code&gt;cli&lt;/code&gt;工具强行修改package.json里面的版本号.&lt;/p&gt;
&lt;p&gt;持续集成的过程中,所有的跨端项目都会通过这个cli工具在&lt;code&gt;npm install&lt;/code&gt;执行之前修改我们的项目配置.其中就包括了我们的依赖.&lt;/p&gt;
&lt;p&gt;我们修改过&lt;code&gt;cli&lt;/code&gt;工具之后,所有的跨端项目都会更新到最新的依赖配置.&lt;/p&gt;
&lt;h3 id="个别项目特殊处理办法"&gt;个别项目特殊处理办法&lt;/h3&gt;
&lt;p&gt;所有项目的依赖全部统一之后,总会有一些特殊原因个别项目的依赖会有一点区别.&lt;/p&gt;
&lt;p&gt;这里就必须要提到&lt;code&gt;package.json&lt;/code&gt;的 &lt;code&gt;resolutions&lt;/code&gt;属性.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;resolutions&lt;/code&gt; 字段用于解析选择性版本，可以通过此功能自定义依赖版本。&lt;/p&gt;
&lt;p&gt;这样npm就会将多版本共存的版本,强行指定某一版本,满足个别项目的特定需求.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://incomparable9527.coding.net/p/imageBed/d/imageBed/git/raw/master/0a9ce7a425c583573c877efd0ce648a9c3992b90d4f272621a3850afa523cfa3.png" alt="图 1"&gt;&lt;/p&gt;
&lt;p&gt;如果我要所有的 &lt;code&gt;B&lt;/code&gt; 强行指定2.0&lt;/p&gt;
&lt;p&gt;使用方法如下:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// package.json 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// 这样B这个依赖库,就被强行指定版本了
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;resolutions&amp;#34;&lt;/span&gt;: {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;B&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;2.0.0&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;resolutions的解释,你可以在这里查看更多:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://classic.yarnpkg.com/zh-Hans/docs/selective-version-resolutions"&gt;https://classic.yarnpkg.com/zh-Hans/docs/selective-version-resolutions&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;当然你也可以使用这个工具,将依赖强制指定版本:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/npm-force-resolutions"&gt;https://www.npmjs.com/package/npm-force-resolutions&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="第三方依赖稳定性问题"&gt;第三方依赖稳定性问题&lt;/h2&gt;
&lt;p&gt;我们在开发周期比较长的前端项目的时候,必然会遇到依赖管理的问题.&lt;/p&gt;
&lt;p&gt;我们在开发项目的时候,我们用了大量的三方库.这些三方的依赖库时不时的会更新自己的代码.&lt;/p&gt;
&lt;p&gt;第三方依赖库的代码更新会很容易造成代码运行的不稳定,&lt;/p&gt;
&lt;p&gt;比如昨天还跑的好好的项目,另一位刚刚接手的同学重新安装依赖之后项目就完全跑不起来了.&lt;/p&gt;
&lt;p&gt;或者自己机器跑的好好的代码,扔到打包机上重新打包之后就完全跑不起来.&lt;/p&gt;
&lt;p&gt;因为三方依赖库用的太多,很多时候并不能很快速的定位到项目为什么跑不起来.&lt;/p&gt;
&lt;p&gt;特别是开发RN项目的时候,一个依赖更新的问题可能会定位一个大半天才能找到罪魁祸首(曾经的我为了这种事情浪费了大量的青春).&lt;/p&gt;</description></item><item><title>Taro跨端开发之跨端开发新时代的思考与举措</title><link>https://time-friend.com/zh/archive/thoughts-and-measures-on-new-era-of-cross-platform-development/</link><pubDate>Tue, 16 Jun 2020 22:17:36 +0000</pubDate><guid>https://time-friend.com/zh/archive/thoughts-and-measures-on-new-era-of-cross-platform-development/</guid><description>&lt;h2 id="新时代"&gt;新时代&lt;/h2&gt;
&lt;p&gt;跨端框架的出现,前端的浏览器兼容过渡到了客户端平台兼容的新时代.&lt;/p&gt;
&lt;p&gt;对于初创公司而言,这种框架可以快速试错与降低人力与时间成本.&lt;/p&gt;
&lt;h2 id="为什么选择taro"&gt;为什么选择Taro&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;并不是说Taro方案有多优秀,就当前时间节点看来目前的所有跨端框架都还处于完善阶段.最完善的端可能就是小程序与H5了.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但是对于有着对跨端开发有着强烈需求的公司来说,这些还远远不够.&lt;/p&gt;
&lt;p&gt;只是第一眼看上去Taro比较适合我们的现有业务.后续各种端的数量增大,如何从容对待.&lt;/p&gt;
&lt;p&gt;目前也还是未知数.就团队而言,前端输出突然猛增,其他配套设施没跟上等于随时翻车.目前我们面临的最大问题就是测试资源的问题.&lt;/p&gt;
&lt;p&gt;对于跨端技术而言,目前相对完善且符合公司业务的技术框架可以选择&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Taro&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;uni-app&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;一个类React, 一个类Vue.&lt;/p&gt;
&lt;p&gt;在框架层面,两种技术框架提供着非常接近的多端兼容方案.&lt;/p&gt;
&lt;p&gt;最大的不同是React 与 Vue的区别.当然,uni-app 提供了小程序容器方案.&lt;/p&gt;
&lt;p&gt;taro这边目前还没有.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;就目前对Taro来看,直接实现Taro to uni小程序理论上是可以实现的.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在Taro next版本中,已经支持对vue语法, 那这样后续是否会出现多端框架to多端框架的局面呢?&lt;/p&gt;
&lt;p&gt;回到问题本身,为什么我们选择Taro呢,&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;团队组建之初使用React技术栈&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我们在RN端有了一定的探索&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Taro支持快应用&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;就历史包袱来看,选择Taro过渡成本是相对较小的.&lt;/p&gt;
&lt;h2 id="目标"&gt;目标&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;一处代码,多端运行.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;减少维护成本&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;多端快速上线&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;如果就快速上线来看,人力成本在短期内看,是非常可观的.但是一旦项目变大,团队变得也越大的时候.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;自动化测试,而项目工程化没有跟上,那就直接天堂变地狱.&lt;/p&gt;
&lt;h2 id="处境与心态"&gt;处境与心态&lt;/h2&gt;
&lt;p&gt;目前使用taro开发单端,基本上没有太大的问题.目前遇到的问题,都有办法可以解决的.&lt;/p&gt;
&lt;p&gt;唯一占用开发工作量的是,如何处理代码在多端中的兼容问题.&lt;/p&gt;
&lt;p&gt;所以处理兼容问题的方法与技巧还有多端开发的意识就尤为重要了.&lt;/p&gt;
&lt;p&gt;还有一个就是开发者的心态问题,因为要开发多端,多端差异还是会有的.&lt;/p&gt;
&lt;p&gt;在开发多端的同时,也要学习多端的开发方式.一来二去的,很容易形态奔溃.&lt;/p&gt;
&lt;p&gt;但是如果跨越了这一时期,了解了各端的特点,后续面对一些问题都会游刃有余了~&lt;/p&gt;
&lt;h2 id="适配最佳路径"&gt;适配最佳路径&lt;/h2&gt;
&lt;p&gt;经过各种实践,我们认为一下开发的兼容路径是相对简单的.&lt;/p&gt;
&lt;p&gt;在适配的过程中,主要还是样式的问题比较多.如果反向适配,会极其痛苦,&lt;/p&gt;
&lt;p&gt;因为你之前写的任意一行代码,都可能是后面的bug.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;可能在后续的发展中,这种类似短板问题会越来越不明显.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但是就现在来看,合适的适配路径,是你必须要关注的重要问题.&lt;/p&gt;
&lt;p&gt;RN &amp;ndash;&amp;gt; 快应用 &amp;ndash;&amp;gt; 小程序 &amp;ndash;&amp;gt; 其他小程序 &amp;ndash;&amp;gt; H5&lt;/p&gt;
&lt;h2 id="脑洞--展望"&gt;脑洞 &amp;amp; 展望&lt;/h2&gt;
&lt;p&gt;就目前跨端框架发展趋势的话会不会发生以下事件?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;一款跨端框架直接兼容另一款框架,直接吃掉所有端?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;开源一款类小程序的容器,直接替代react Native 与 weex?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;多端测试框架(一套测试用例,测试所有端)会不会应运而生?&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="尾巴"&gt;尾巴&lt;/h2&gt;
&lt;p&gt;后续的这段时间,我会把以下问题与团队实践整理出文章供大家思考.&lt;/p&gt;</description></item></channel></rss>