小程序模板網(wǎng)

小程序時代:如何跨多小程序開發(fā)協(xié)作?

發(fā)布時間:2020-05-21 09:53 所屬欄目:小程序開發(fā)教程

導語

小程序端越來越多, 跨平臺開發(fā)框架逐漸成為開發(fā)小程序的主流 , 目前跨平臺開發(fā)有較多的開源解決方案 ,本文介紹一種簡單而有效的方法,解決復雜小程序的跨團隊開發(fā)協(xié)作,希望對你有所幫助。

背景

目前市面上小程序端越來越多,跨平臺開發(fā)框架逐漸成為開發(fā)小程序的主流。目前跨平臺開發(fā)有較多的開源解決方案,比如美團點評的mpvue、滴滴的Chameleon、凹凸實驗室的Taro等,都做得比較好。這些框架幫我們解決了一處開發(fā),多處運行的難點。但是在復雜的業(yè)務場景中,最終落地也存在著許多困難,需要自己解決。以58房產(chǎn)的新房業(yè)務小程序為例,實際的業(yè)務場景中,既需要有獨立承載功能的“58同城新房樓盤精選”小程序,也有依托于其他流量平臺的入口,比如在“58同城”、“安居客買房”等都有相應的新房業(yè)務,同時還有交叉的業(yè)務場景,比如在同經(jīng)紀人業(yè)務結合的“安居客經(jīng)紀人網(wǎng)店”中展示新房樓盤。這其中既有微信小程序,也有百度小程序。

這些業(yè)務有較多的共同點,比如基礎功能邏輯是一致的,但是也存在很多差異性,比如商業(yè)邏輯,頁面皮膚以及一些差異功能點。

新房首頁對比

上圖為三個小程序的首頁對比,可以看到獨立的小程序“58同城新房樓盤精選”集成了賬號、城市、消息,在“58同城”和“安居客買房”這些能力則是依賴主體小程序。另外三個小程序之間還有些細微差別,但是樓盤相關的基礎功能確是相同的。

一處開發(fā)多處運行的難題

作為業(yè)務方,我們希望業(yè)務代碼也可以一處開發(fā),到處運行。方案設計之時,我們的目標便是業(yè)務代碼在同一倉庫管理,同時方案具備較大的靈活性以適配各種環(huán)境。

在上述的背景下,實際開發(fā)中會遇到如下困難:

a) 各個小程序歸屬的開發(fā)團隊不一樣,使用的開發(fā)方案也不一樣,有原生開發(fā)、wepy、Taro、mpvue等,意味著在源碼層面是難以進行協(xié)作開發(fā)的;

b) 業(yè)務方與平臺方之間是跨團隊協(xié)作,需要盡量減少耦合,提高協(xié)作效率,同時避免相互影響;

c) 需要具備在各個小程序環(huán)境中的差異化開發(fā)方案;

d) 所有業(yè)務代碼同一地方管理,意味著會有不必要的代碼,需要有機制保障最終的打包結果大小是最優(yōu)的;

e) 在不同平臺小程序中,會依賴他們各自提供的基礎能力,比如賬戶體系,消息等,這部分在各平臺小程序中也存在著一定差異性;

f) 在不同場景下需要具備不同的接入方案,支持微信插件方式接入平臺小程序,也要支持業(yè)務分包方式接入平臺小程序。

整體架構設計

本方案基于Taro 1.3版本實現(xiàn),其他小程序框架也可使用相同的方法做改造。在現(xiàn)有Taro基礎上,無法支持到一份源碼打包成多個同類型的小程序,因此在現(xiàn)有配置層進行擴展處理,并添加適配層,對于各個小程序不同點進行處理,最終實現(xiàn)直接打包到多個不同的小程序中,整體的架構主要分為四層: 

a) 配置層,用于解決在不同場景下的差異化,包括環(huán)境變量、主題樣式、頁面配置等;

b) 源碼層,為具體的業(yè)務代碼,常見方案,不做具體介紹;

c) 適配層,用于對接不同方案下小程序提供的接口,并牟平不同小程序提供的接口差異,為源碼層提供統(tǒng)一的接口;

d) 打包層,與配置層相結合,用于打包最終交付結果;

以新房為例的架構圖:

1.  配置層處理

1) 打包腳本配置

若要支持多小程序開發(fā),需在package.json中增加scripts,用于區(qū)分環(huán)境。這里我們用的是cross-env這個包來設置,比如在打包58同城小程序時,加入環(huán)境變量WEAPPSOURCE=wbweapp。


{

"build:weapp": "taro build --type weapp",

"build:wbweapp": "cross-env WEAPPSOURCE=wbweapp taro build --type weapp",

"dev:wbweapp": "cross-env WEAPPSOURCE=wbweapp npm run build:weapp -- --watch",

}

然后在`config/index.js`配置defineConstants,用來配置一些編譯時的全局變量供代碼中使用,這里的配置會用于做打包的差異化處理。大部分的差異化配置,我們都放到了編譯時來進行配置,有助于降低代碼打包后的大小。其原理是通過webpack的define-plugin和uglifyjs-webpack-plugin兩個插件配合來刪除掉不可達代碼,保證不使用的代碼不會被打包。


config.defineConstants = {

WEAPPSOURCE: JSON.stringify(process.env.WEAPPSOURCE),

WBWEAPP: '"wbweapp"',

AJKWEAPP: '"ajkweapp"',

}

2) 差異性樣式處理

在現(xiàn)有業(yè)務中,需要同時支持58同城和安居客兩個品牌。二者之間頁面結構是一致的,但各自有些主題色,我們將這部分差異抽取出來,變成Sass變量,然后整合至一個scss文件中,通過編譯時引入不同的scss文件,來達到切換主題的作用。這里主要是配置`config/index.js`中的`config.plugins.sass.resource` 。


const sassConfig = {

wbweapp: '../wbweapp.scss',

ajkweapp: '../ajkweapp.scss'

}

config.plugins.sass.resource = path.resolve(__dirname, sassConfig[process.env.WEAPPSOURCE])

3)差異化頁面處理

源碼層中會包含所有場景下的全量頁面,但每個場景所需的頁面只是其中的一部分,需要做差異化處理。處理方法同上,略有差異點,通過編譯打包時pages的配置不同,在`app.tsx`中的pages是決定引入哪些頁面,我們通過傳入環(huán)境變量找到對應的配置頁面,實現(xiàn)按需配置打包。

`config/index.js`中配置:


const pagesConfig = {

wbweapp: ['pages/a'],

ajkweapp: ['pages/b']

}

config.defineConstants = {

PAGES: JSON.stringify(pagesConfig[process.env.WEAPPSOURCE])

}

`app.tsx`中配置:


class App extends Component {

config: Config = {

pages: PAGES,

}

}

2.  適配層處理

1) 差異化功能處理

功能的差異化處理,使用配置層定義的全局變量來做,偽代碼如下:


import TabBar from '../components/tabbar';

export default class _C extends Component {

render() {

return {(WEAPPSOURCE == WBWEAPP) && <TabBar/>}

}

}

這樣寫的話,當WEAPPSOURCE !== WBWEAPP時,TabBar組件不會被打包到最終代碼中,wxml文件中TabBar的代碼塊也不會有。上面的import是不需要做特殊處理,打包時會分析依賴關系,沒有被最終使用的文件不會被編譯。

2) 接口統(tǒng)一封裝處理

在各個平臺方小程序中,通用功能都應該是統(tǒng)一管理的。比如用戶信息,用戶在58同城小程序內(nèi)進行登錄,各業(yè)務都能拿到統(tǒng)一的用戶信息,而不是進入新房頁面后再做一次新房的登錄。這些功能,由平臺方提供接口,供業(yè)務方調(diào)用。但各個平臺存在差異性,這些差異性就由適配層做統(tǒng)一的封裝,對業(yè)務開發(fā)提供一致的接口。

比如獲取城市信息:


export const getCityInfo = () => {

if (WEAPP_SOURCE == WBWEAPP) {

city_info = WBIndex.WB.getCityInfo()

} else if (WEAPP_SOURCE == AJKWEAPP) {

city_info = AJKIndex.Common.getCityInfo();

}

}

原理解析

通過以上介紹,已經(jīng)解決了我們對差異化開發(fā)的要求,同時適配層將平臺接口差異牟平,業(yè)務開發(fā)也不需要關心所處環(huán)境。大家可能比較好奇,所有的小程序代碼都放在一起管理,最終打包出來的代碼大小是不是最優(yōu)的?主要是以下兩點:

1)  在開發(fā)中注意利用條件編譯來刪除不必要的代碼;

2)  在打包時做依賴分析及打包優(yōu)化,業(yè)務層盡可能做更少的事情;

依賴分析優(yōu)化工作主要是由@tarojs/cli包來完成的,簡化后的流程圖如下:

首先是解析入口文件`app.tsx`,通過兩次語法轉換,一次語法遍歷,得到了依賴的樣式文件、依賴的js文件、app的配置等,以及入口文件app.js。樣式文件編譯成最終的app.css,依賴的js文件,通過拷貝或生成,放到指定的目錄中,app配置生成app.json。

兩次語法轉換是不一樣的,第一次是通用的語法轉換,比如jsx語法的處理。第二次是差異化的轉換,會根據(jù)當前轉換的類型是入口文件、頁面文件或組件文件做一些特殊處理。第二次轉換時使用了babel-plugin-danger-remove-unused-import插件,會刪除不必要的依賴引入。上文提到的TabBar組件,雖然是被引入了,但在不需要的場景下TabBar組件就不會被打包。這里需要注意引入的文件,不應該存在副作用。

解析完入口文件后,會得到app配置的pages列表,頁面文件列表循環(huán)通過同樣的過程,得到頁面的樣式、js、配置等,以及所依賴的組件列表。

組件文件的打包過程跟頁面是基本一致的,區(qū)別點在于組件會依賴其他組件。

理解了整個打包的流程,上面的問題答案就比較清晰了,不在pages配置里的頁面是不會最終打包輸出的,沒有被依賴到的文件也是不會經(jīng)過打包處理的。

與平臺小程序集成

小程序最終的集成發(fā)布有三種方式:獨立發(fā)布、插件集成、分包集成。

多個小程序的不同集成方案

1. 插件集成發(fā)布

如果是通過小程序插件方式集成,平臺小程序可以將接口統(tǒng)一掛載到插件的變量中,二者就橋接上了。

插件的index.js設置(上文WBIndex即為引入的此文件):


module.exports = {

WB: {},

}

平臺小程序接口注入方法:


const plugin = requirePlugin("xinfang");

plugin.WB = {

getCityInfo: function() {}

}

2. 分包集成發(fā)布

如果是分包集成的話,可以考慮將接口直接掛載在App中。

平臺小程序接口注入方法(上文AJKIndex即為getApp()):

getApp().Common.getCityInfo = function() {}

采用分包集成方案的話需要注意,因為雙方是在各自倉庫下分別開發(fā)的,最終需要和到一起進行打包發(fā)布。目前我們采用的方案是配置`config.outputRoot`將結果代碼打包到平臺小程序倉庫中,通過git管理,再由平臺小程序做發(fā)布。

3.獨立小程序發(fā)布

方案跟分包集成發(fā)布是一致的,不過API由自己提供,也掛載在App中,同時扮演了平臺方和業(yè)務方。

實踐經(jīng)驗分享

a) 小程序包依賴的json文件的處理,比如插件需要有插件配置文件`plugin/plugin.json`??赏ㄟ^配置`config.copy.patterns`指定需要拷貝的文件或者目錄來實現(xiàn);

b) 小程序是插件和分包處理,在不同場景下的頁面跳轉路徑是不一樣的,但其實相對的路徑是一致的,在于跳轉前綴不同,可將頁面跳轉統(tǒng)一封裝到適配層,根據(jù)環(huán)境變量適配不同的加上對應的前綴,當需要由插件切換到分包時,跳轉部分僅需修改前綴,無需額外處理;

問題解決

前面提到一處開發(fā)多處運行的難題,得到了一一解決,整理如下:

a) 源碼層面無法進行跨團隊協(xié)作開發(fā)?

團隊間分倉庫開發(fā),最終代碼通過微信插件方式,或者分包方式進行集成。

b) 業(yè)務方與平臺方之間的如何解耦?

通過統(tǒng)一的API,進行橋接,無其他耦合,API根據(jù)集成方式的不同,有不同的掛載方案。

c) 如何進行差異化開發(fā)?

針對樣式差異化,配置差異化,功能差異化均給出了方法。

d) 如何保證打包結果是最優(yōu)的?

盡可能的利用編譯時的條件編譯方法,排除不必要代碼。

e) 平臺方接口的差異性如何牟平?

增加了適配層,對業(yè)務提供一致的輸入輸出接口。

f) 支持不同平臺小程序的多種接入方案?

支持了插件接入與分包接入。

總結與規(guī)劃

本文介紹了在較復雜的小程序業(yè)務場景中,跨多小程序跨團隊的協(xié)作方案,該方案幫助了新房業(yè)務在多小程序中的快速落地及迭代。

在實現(xiàn)了“58同城”小程序中的新房業(yè)務接入后,我們又做了“58同鎮(zhèn)”的新房業(yè)務對接。只需要“58同鎮(zhèn)”小程序提供一致的基礎能力接口,即可輕松接入。

本文內(nèi)容主要為業(yè)務經(jīng)驗積累,整體方案易于實施,帶來的業(yè)務開發(fā)提效卻是顯著的,希望能幫助到大家。實際業(yè)務落地過程中,還有較多的細節(jié)需要處理,無法一一列舉,歡迎提問或咨詢。

文中僅介紹了業(yè)務在微信小程序的實踐情況,實際上在百度小程序以及H5也已有相應落地實踐,具備了一定的通用性,可以放心使用。

隨著業(yè)務覆蓋的范圍越來越廣,適配層會越來越復雜,不利于維護,更有效的方案是把業(yè)務實踐總結為一套通用的接口標準,各個小程序按統(tǒng)一標準來實現(xiàn)API,業(yè)務方可以不關心所處環(huán)境的差異性,進一步提高跨團隊開發(fā)的協(xié)作效率。 

參考文獻

1. https://www.npmjs.com/package/cross-env

2. https://nervjs.github.io/taro/docs/config.html

3. https://webpack.js.org/plugins/define-plugin/

4. https://www.npmjs.com/package/uglifyjs-webpack-plugin

5. https://github.com/mishoo/UglifyJS2#compress-options 


易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://m.u-renovate.com/wxmini/doc/course/25249.html 復制鏈接 如需定制請聯(lián)系易優(yōu)客服咨詢:800182392 點擊咨詢
QQ在線咨詢
AI智能客服 ×