微信小程序開發(fā)者文檔之開發(fā)工程流程化
2017年5月22日,微信小程序推出之時(shí),限制非常多,現(xiàn)在越來越開放。微信小程序開發(fā)者文檔也受到越來越多人的關(guān)注,下面從多個(gè)方面來談?wù)勎⑿判〕绦蜷_發(fā)者文檔的一些內(nèi)容。
伴隨著從2017年1月9日凌晨的夜色,張小龍和他的團(tuán)隊(duì)正式發(fā)布了微信小程序,瞬間刷爆了業(yè)內(nèi)人士的各種信息流,一個(gè)看似『銀彈』的產(chǎn)品形態(tài)被大家所熱捧,一股開發(fā)浪潮也隨之而來。而近期,微信又做成了兩個(gè)很大的突破:微信悖逆蘋果做小程序市場(chǎng)(應(yīng)用內(nèi)搜索已經(jīng)有『市場(chǎng)性質(zhì)』)和允許小程序通過社交傳播(可以通過小程序第三方平臺(tái)朋友圈和聊天傳播,二維碼可以長(zhǎng)按識(shí)別),同時(shí)讓開發(fā)者們看到微信小程序發(fā)展的信心和前景??傊?,不管是『紅利』還是『雞血』,小程序?qū)⒊蔀楫a(chǎn)品布局中重要的一個(gè)組成部分。因此,在公司內(nèi)部,將小程序開發(fā)流程統(tǒng)一化、規(guī)劃化,讓小程序開發(fā)變得優(yōu)雅是相當(dāng)有必要的。
下面,GitChator將以去哪兒網(wǎng)微信小程序?yàn)楸尘埃敿?xì)對(duì)去哪兒網(wǎng)微信小程序工程流程化方案進(jìn)行剖析,同時(shí)與讀者們進(jìn)行交流探討。
小程序開發(fā)問題的轉(zhuǎn)變
讀者們一定很奇怪,為什么先聊到『開發(fā)問題的轉(zhuǎn)變』?因?yàn)樽黾軜?gòu)、做工程流程化的目的是為了降低開發(fā)、測(cè)試、發(fā)布、運(yùn)維等一系列環(huán)節(jié)的成本的同時(shí),解決這些環(huán)節(jié)之間存在的問題和痛點(diǎn)。所以理清開發(fā)小程序的過程中遇到的問題,才能更好的做架構(gòu)、做工程流程化。
那么,小程序開發(fā)急需解決什么問題?而問題又有什么轉(zhuǎn)變呢?
從內(nèi)測(cè)開始到半個(gè)月之前,有一個(gè)數(shù)字非常讓人頭疼 —— 1024 。這個(gè)數(shù)字代表著小程序的總 Size,小程序打包后的總體積不能超過 1024 KB (也就是 1 MB)。在這個(gè)有限的空間內(nèi),放入更多的業(yè)務(wù)邏輯,這才是當(dāng)時(shí)小程序開發(fā)遇到的最大的問題。因此, 壓縮 是當(dāng)時(shí)首當(dāng)其沖的工作。
當(dāng)初,公司準(zhǔn)備將去哪兒酒店、去哪兒門票和去哪兒交通三個(gè)小程序中的五個(gè)業(yè)務(wù)線合并到統(tǒng)一的一個(gè)小程序中。筆者所在的團(tuán)隊(duì)接到了這個(gè)任務(wù),并在業(yè)務(wù)線配合下,在一個(gè)星期的時(shí)間里,完成任務(wù)上線,而后又在剩余的體積內(nèi)塞入了兩個(gè)其他的業(yè)務(wù)。在當(dāng)時(shí)的情況下,每壓縮出 10KB 的體積,都是一件很令人興奮的事。
而現(xiàn)在不同了,微信將小程序的 Size 增加到 2MB ,也就是 2048 KB,足足 翻了一倍 。 由于有之前 1024 的經(jīng)驗(yàn),翻倍后,在相同的壓縮邏輯下,已經(jīng)足夠滿足絕大多數(shù) App 的要求。例如,將去哪兒旅行 App 上的主要業(yè)務(wù)的主要流程都放進(jìn)微信小程序內(nèi),應(yīng)該是沒問題的。
所以,在壓縮問題并不突出明顯后, 如何更好的管制作小程序控小程序的代碼 , 如何做好業(yè)務(wù)隔離 , 如何分配業(yè)務(wù)資源的配比 ,這些問題將會(huì)成為現(xiàn)在以及以后核心要解決的問題。當(dāng)然,壓縮也是工程流程化的一部分,只是優(yōu)先級(jí)降低而已。
最后,提出一個(gè)問題:據(jù)上文所述, 可以將去哪兒旅行 App 上的主要業(yè)務(wù)的主要流程都放進(jìn)微信小程序內(nèi) ,但是在靈活的小程序應(yīng)用場(chǎng)景下,這樣真的好嗎?真的適合小程序的場(chǎng)景嗎?這也是工程流程化要考慮和完善的一個(gè)問題。
小程序的架構(gòu)模式
對(duì)于小程序的架構(gòu),用一句話總結(jié)就是 『類 React Native 的 MVC Web UI 架構(gòu)』。小程序的架構(gòu)思想與 React Native 類似,都是以組件化的方式和 MVC 的模式將 UI 層和 Service 層分離,在保證 UI 層的顯示效率的同時(shí),也保持了 Service 層的一致性;而與 React Native 最大的不同是:React Native 使用的是 Native 的 UI,而微信使用的 Web UI。
相比來說,Native 的 UI 性能更好,但也更依賴系統(tǒng)和 App 本身的 Native,不易維護(hù)和進(jìn)行熱更新;而 Web UI 性能和 Native UI 有一定的差距,但是依賴少,易維護(hù)并且容易實(shí)現(xiàn)熱更新。
小程序的架構(gòu)就先簡(jiǎn)單介紹到這里,大家可以從其他的 GitChat 文章里了解更多。這次GitChat 主要要闡述的是小程序的工程流程化問題,而為了實(shí)現(xiàn)工程流程化,在簡(jiǎn)單了解小程序架構(gòu)的同時(shí),也必須先了解基于這套架構(gòu)的一些技術(shù)細(xì)節(jié),例如代碼結(jié)構(gòu)、構(gòu)建方法、調(diào)試發(fā)布方式等。
下面簡(jiǎn)單列舉一些比較重要的點(diǎn)。
代碼結(jié)構(gòu)
首先,在工程內(nèi)有三個(gè)公共入口文件:
-
app.json
:配置文件,配置路由列表、程序信息等。 -
app.js
:公共入口文件,小程序啟動(dòng)時(shí)的 Init 邏輯。 -
app.wxss
:公共樣式文件,公共樣式用于每個(gè)視圖 View 中。
同樣的,對(duì)于每個(gè)視圖 View 都存在與其對(duì)應(yīng)的入口文件,假設(shè)此 View 為 page
,那么
-
page.json
:此視圖 View 的配置。 -
page.js
: 此視圖的腳本邏輯。 -
page.wxss
: 此視圖的樣式。
其他的,不論是 JavaScript 腳本還是 Wxml 模板和 Wxss 樣式,應(yīng)被入口文件 require/import
使用。
構(gòu)建方法
在小程序開發(fā)者工具的 Sources 面板,查看 JavaScript 腳本,會(huì)發(fā)現(xiàn):項(xiàng)目中所有的 JavaScript 都會(huì)被 同步加載 ,不管是否被 require
。
每個(gè)腳本都會(huì)被套上如下代碼:
define("some.js", function(require, module){ // 原本的代碼 });
這種加載方式類似AMD,但是跟標(biāo)準(zhǔn)的AMD又有些不同,缺少了依賴部分的聲明。
而對(duì)于 Wxml 和 Wxss 文件,則被開發(fā)者工具自動(dòng)轉(zhuǎn)換為 JavaScript 后加載,其中:
-
Wxss :主要處理的是 import 邏輯,然后生成的 Css,通過腳本的形式插入頁(yè)面使用。
-
Wxml :和 React Naitive 的 JSX 類似,被編譯成 createElement 類似的形式。
預(yù)覽發(fā)布方式
預(yù)覽、調(diào)試、打包上傳都集成在微信提供的開發(fā)者工具中,而發(fā)布體驗(yàn)版和發(fā)布線上則在微信小程序的管理后臺(tái)中。打包上傳、發(fā)布的邏輯,都需要人工操作。
關(guān)于開發(fā)者工具的一些細(xì)節(jié)
關(guān)于小程序的打包、預(yù)覽、上傳的流程,都包含在開發(fā)者工具中,所以想要更深入得了解小程序的流程機(jī)制,必須要從開發(fā)者工具入手。
經(jīng)過簡(jiǎn)單研究,發(fā)現(xiàn)開發(fā)者工具是基于 NW.js
構(gòu)建的,基于 Node 和 Webkit 構(gòu)建的應(yīng)用程序。對(duì)于前端來說,這是一件令人感到幸福的事,直接可以通過讀源碼來了解它的邏輯。
代碼在哪里? 在 MacOS 系統(tǒng)中,源碼比較好找:右鍵開發(fā)者工具『Show Contents』(顯示包內(nèi)容),就能在 Resources/app.nw/
下找到相應(yīng)的源碼,完成路徑如下: /Applications/wechatwebdevtools.app/Contents/Resources/app.nw/
。
源碼都是壓縮過后的 JavaScript 腳本,可以使用 js-beautity 進(jìn)行格式化,以便于閱讀。
// 在源碼目錄的 app 目錄下執(zhí)行 find . -type f -name '*.js' -exec js-beautify -r -s 2 -p -f '{}' \;
一些技巧:
-
在資源目錄下:
app/dist/app.js
的第 37 行window.addEventListener("resize", function() {})
之前,加入nw.Window.get().showDevTools();
。之后每次打開微信開發(fā)者工具時(shí),會(huì)自動(dòng)啟動(dòng)針對(duì)『開發(fā)者工具』的開發(fā)者工具,并可以通過它調(diào)試微信的開發(fā)者工具。 -
在打印日志時(shí),不要用
console.log
,請(qǐng)使用global.contentWindow.console.log
。這樣,才能輸出到上面所說的開發(fā)者工具的開發(fā)者工具的控制臺(tái)里。(NW.js 的 Node JS Context 和 Webkit JS Context 是分開的, JavaScript 腳本運(yùn)行在 Node 的 JS Context 中,因此,打印其實(shí)打印在 Node 的輸出中,并不在 Webkit 的開發(fā)者工具的控制臺(tái)中。global.contentWindow
獲取的是 Webkit 的 JS Context 里的 Window)
使用這兩點(diǎn)技巧,讀者們可以優(yōu)雅地去閱讀微信開發(fā)者工具的源碼了。
工程流程化方案
上面,我們簡(jiǎn)單了解了小程序的一些背景知識(shí)和架構(gòu)模式,下面,GitChator 將從 問題 -> 解決方案 的方式,來說明這套工程流程化方案。
Size 問題 -> 壓縮工具
還是從老問題壓縮說起吧。雖然微信對(duì) Size 的限制從 1024 變成了 2048,但是終有一天,代碼會(huì)增長(zhǎng)到超過 2048,而且, Size 的大小會(huì)影響用戶加載的速度,包括下載最新版本代碼的速度和小程序初始化的速度 ,所以壓縮是一直有必要的。
雖然開發(fā)者工具,已經(jīng)支持了代碼壓縮上傳,但是 GitChator 覺得它是個(gè)『假的壓縮選項(xiàng)』。因?yàn)樵陂喿x開發(fā)者工具的源碼邏輯之后,發(fā)現(xiàn)它的壓縮,只是將 JavaScript 用 Uglify 進(jìn)行混淆壓縮。而對(duì) Wxml 、Wxss 沒有進(jìn)行任何壓縮處理。同時(shí),對(duì)資源路徑中的無用文件也沒有做處理。因此,我們要做的有關(guān)壓縮的事情還是很多的。例如:
合并 JavaScript 并壓縮
將所有的 JavaScript 腳本使用合并成一個(gè)文件,這樣會(huì)使 腳本壓縮效率變高 (例如 require
的長(zhǎng)路徑?jīng)]了)、 混淆性越大 (代碼的目錄結(jié)構(gòu)沒了)。雖然 JavaScript 腳本被包裝成類 AMD 的形式,但是使用時(shí)是 同步加載同步執(zhí)行 的,因此將多個(gè) JavaScript 腳本合并成一個(gè)并不影響小程序加載或切換視圖的效率,反而因?yàn)闇p少了 IO 次數(shù),提升了加載效率。(現(xiàn)在 GitChator 暫時(shí)使用的是 WebPack,而使用 Rollup 會(huì)讓代碼更小,執(zhí)行效率更快)可是要如何做呢?
首先是,入口文件選?。赫蛏厦娲a結(jié)構(gòu)所說,小程序有一個(gè)統(tǒng)一的入口是 app.js
,而每個(gè)視圖 View 都有自己的入口 page.js
,將這些所有入口 require
到一個(gè)統(tǒng)一的入口文件中,進(jìn)行打包,這樣會(huì)得到一個(gè)擁有 JavaScript 腳本邏輯的 bundle.js
。
其次,要對(duì)入口文件進(jìn)行一定的修改,讓代碼被合并成一個(gè)文件后,仍能正常運(yùn)行。
對(duì)于視圖 View 的入口,必須存在 Page(PageOption)
,這樣的視圖注冊(cè)邏輯,我們只需通過正則或者 AST 將其改為自定義的注冊(cè)(Register)方法 global.__p('/path/to/page.js', pageIndex, PageOption)
即可。
實(shí)現(xiàn)如下:
global.__p = pageName, index, pageOpt) => { // 其他相關(guān)邏輯 global['p' + index] = () => { Page(pageOpt || {}); }; };
這樣在視圖 View 的入口文件中,只需要 global.pXX()
一段代碼即可。
對(duì)于小程序的入口 app.js
,將原本的內(nèi)容直接改為 require('bundle.js')
即可,因?yàn)樗⒉幌褚晥D入口和代碼路徑有關(guān)。
最終,形式如下:
壓縮其他文件
其他文件主要包括 Wxml 文件、 Wxss 文件和 JSON 文件。平時(shí)前端開發(fā)中,對(duì) HTML 和 CSS 的壓縮,主要是 去除的空白字符、換行 以及 刪除注釋 。
對(duì)于 Wxml 直接兩個(gè)正則即可:
-
/<!--((.|\n|\r)*?)-->/gm
:去除注釋。 -
/\"\n\s*/g
: 去除換行。
對(duì)與 Wxss,直接用 uglifycss
即可;對(duì)于JSON,直接 JSON.stringify(JSON.parse(...))
。
這里,有些讀者會(huì)可能提出兩個(gè)疑問:
-
1、空白字符、換行能有多少,減不了多少吧?
-
2、開發(fā)者工具為什么不做對(duì)這些文件的壓縮?
關(guān)于第一個(gè)問題,一個(gè)約 1000 KB,空白字符和換行大概有 10KB。在有上限的情況之下,10 KB 也是要珍惜的。
關(guān)于第二個(gè)問題,GitChator 認(rèn)為微信開發(fā)者工具的開發(fā)者覺得沒有必要去做。上文中提過,Wxml 和 Wxss 都會(huì)被轉(zhuǎn)義成 JavaScript 腳本,在此過程中,不管 Wxml 和 Wxss 是否被壓縮,它們的轉(zhuǎn)化結(jié)果是相同的。因此,壓縮與否,對(duì)于最終產(chǎn)物是沒有影響的(最終產(chǎn)物指在服務(wù)器二次打包后的結(jié)果,也是用戶真正使用的)。但是,Size 是以本地打包上傳的內(nèi)容進(jìn)行計(jì)算的,不進(jìn)行此步壓縮,會(huì)使微信服務(wù)端判定的 Size 增大。
刪除無用文件
刪除無用的 JavaScript 文件(因?yàn)橐呀?jīng)打包為 bundle.js
了,無需其他非入口文件了),刪除沒被 import
的 Wxss 和 Wxml 文件,刪除空目錄等等。
代碼級(jí)優(yōu)化
除了利用工具進(jìn)行壓縮,在編寫代碼時(shí),也可以通過一些方法來減小體積,在這里簡(jiǎn)單列幾點(diǎn):
-
提煉公共組件、公共 API。
-
使用 ES6 時(shí),盡量不使用依賴
Runtime/Polyfill
的語法,例如import
和class
。 -
圖標(biāo)使用 Iconfont。
-
等等...
多業(yè)務(wù)并行開發(fā)問題 -> 以模塊化的方式進(jìn)行業(yè)務(wù)代碼隔離
隨著小程序的諸多限制放開,越來越多的產(chǎn)品想來分此一杯羹,導(dǎo)致像去哪兒網(wǎng)這樣多業(yè)務(wù)的公司,一個(gè)小程序里承接的業(yè)務(wù)也會(huì)逐漸增多,開發(fā)人員的數(shù)量也會(huì)直線上升(一個(gè)小程序的開發(fā)者最多 30 人)。而此時(shí),如果所有業(yè)務(wù)的開發(fā)者還在同一個(gè)項(xiàng)目里開發(fā)的話,那么這個(gè)項(xiàng)目將會(huì)非常難以管理。因此, 以模塊化的方式進(jìn)行業(yè)務(wù)代碼隔離 勢(shì)在必行。
對(duì)于模塊的劃分,很顯然應(yīng)該 按照業(yè)務(wù)來劃分 ,每個(gè)業(yè)務(wù)自己是單獨(dú)的模塊,并且 相互之間不能存在依賴關(guān)系 , 能并且只能依賴公共模塊 。就如下圖所示。
這樣實(shí)現(xiàn)帶來最大的好處是 可插拔 ,也就是可以隨時(shí)將任意一個(gè)模塊在不影響其他業(yè)務(wù)的情況下進(jìn)行修改或刪除。
上文中提出過一個(gè)問題, 將去哪兒旅行 App 上的主要業(yè)務(wù)的主要流程都放進(jìn)微信小程序內(nèi),真的適合小程序的場(chǎng)景嗎? 。這是問題雖然是一個(gè)純產(chǎn)品上的問題,但是 可插拔 的特性,會(huì)讓這個(gè)問題 變得容易解決 ,產(chǎn)品同學(xué)可以很容易地以業(yè)務(wù)模塊為單位增減業(yè)務(wù)。假設(shè)一個(gè)業(yè)務(wù)取得的收益很小,產(chǎn)品同學(xué)可以立即在不影響其他業(yè)務(wù)的前提下,將這個(gè)業(yè)務(wù)下線,并將其的空間用于接入新業(yè)務(wù)或分配給其他線上業(yè)務(wù)。
同時(shí),業(yè)務(wù)在開發(fā)時(shí),本地只需要存在 Common 模塊就能運(yùn)行,降低了開發(fā)和調(diào)試的成本。
可插拔的模塊化不僅僅可以讓模塊變更的成本降低,同時(shí)也讓 以相同模塊構(gòu)建多個(gè)小程序 的成本降低,增加小程序產(chǎn)品的 靈活性 ,根據(jù)場(chǎng)景構(gòu)建出最適合的 即開即用 的小程序。
諸如上圖所示,用不同的模塊構(gòu)建出不同場(chǎng)景的小程序。
-
去哪兒出行:交通類產(chǎn)品,包括去哪兒所有的交通類業(yè)務(wù)模塊。
-
去哪兒游玩:場(chǎng)景是本地游,因此包括與本地游相關(guān)的業(yè)務(wù)模塊。
當(dāng)然,這只是舉例,具體情況視產(chǎn)品場(chǎng)景而定,但是,這種構(gòu)建方式,GitChator 個(gè)人覺得比較適合小程序這種靈活的場(chǎng)景。而大而全的功能,還是交給 A小程序制作pp 吧。
這里就出現(xiàn)另一個(gè)問題: 如何有效的管理模塊 。
因?yàn)橐粋€(gè)模塊,被多個(gè)小程序項(xiàng)目引用,所以它的版本化是非常重要的,否則有微信小程序appid可能出現(xiàn),為了滿足一個(gè)小程序項(xiàng)目的需求進(jìn)行改動(dòng)后,在另一個(gè)小程序內(nèi)出現(xiàn)問題。
因此,GitChator 基于公司通用的前端開發(fā)工具集 YKit 實(shí)現(xiàn)插件,配合 公司的代碼倉(cāng)庫(kù) GitLab 和 公司的打包平臺(tái) Jenkins,實(shí)現(xiàn)了一套模塊版本的管理邏輯。
本地版本查詢:
本地安裝:
查詢頁(yè)面:
當(dāng)然,也可以用私有 NPM 倉(cāng)庫(kù)實(shí)現(xiàn)模塊管理,GitChator 主要是為了和公司發(fā)布系統(tǒng)打通,才選擇這樣實(shí)現(xiàn)。
在實(shí)現(xiàn)模塊化的過程中,有兩個(gè)地方需要注意:
路由:業(yè)務(wù)模塊已經(jīng)隔離,而路由配置在統(tǒng)一的入口處,這樣會(huì)影響模塊的插拔。因此,在每個(gè)模塊的根目錄下,添加各自的 app.json
配置,用于配置模塊自己的路由,然后在工具打包的時(shí)候,將各模塊的路由進(jìn)行合并 Merge。
App.onLaunch:業(yè)務(wù)模塊有些邏輯,需要在 App 的 onLaunch 時(shí)執(zhí)行。因此,在每個(gè)模塊的根目錄下,添加各自的 app.js
腳本,完善相應(yīng)的,然后在工具打包時(shí),將腳本注入到相應(yīng)的位置。
module.exports = () => { onLaunch: () => { // TODO Something } };
最后,可插拔的模塊化對(duì)于 模塊 Size 的計(jì)算 也是非常重要的。
模塊的 Size = 小程序總 Size - 拔去此模塊時(shí)小程序的 Szie
這樣的計(jì)算方式,是十分可靠的,有利于小程序?qū)γ總€(gè)模塊進(jìn)行配額分配如何制作小程序。
人工發(fā)布問題 -> 自動(dòng)化發(fā)布系統(tǒng)集成
一般比較成熟的公司,都會(huì)有自己的發(fā)布系統(tǒng),用于項(xiàng)目的發(fā)布,在降低人工成本的同時(shí),規(guī)避人工操作的風(fēng)險(xiǎn)。而微信小程序后臺(tái)并沒有提供相應(yīng)的接口 API 進(jìn)行此類操作,因此,需要自己實(shí)現(xiàn)一套上傳發(fā)布邏輯。
這個(gè)邏輯主要有兩點(diǎn): 小程序打包 和 各種掃碼驗(yàn)證 。
對(duì)于小程序打包,直接從微信開發(fā)者工具內(nèi),將小程序打包的邏輯抽離出來即可。
// wxBuild 為開發(fā)者工具資源下 app/dist/weapp/commit/build.js // wxPack 為開發(fā)者工具資源下 app/dist/weapp/commit/pack.js wxBuild({ projectpath: 'path/to/source', // 小程序項(xiàng)目路徑 es6: true, postcss: true, minified: true }, { noCompile: true }, (err, data) => { wxPack(data, 'path/to/result.wx', (err, data) => { // data 為產(chǎn)出物的路徑 }); });
對(duì)于掃碼驗(yàn)證,其實(shí)是模擬用戶的行為。Gitchator 實(shí)現(xiàn)的邏輯是,將二維碼打印在發(fā)布日志的 Job 里,管理員使用微信進(jìn)行掃碼即可。下面是發(fā)布日志的截圖。(主要用到 phantom)。
由于篇幅有限,具體的細(xì)節(jié)可以私下和 GitChator 交流。不過 GitChator 覺得,微信的同學(xué),應(yīng)該會(huì)在今后提供相應(yīng)的上傳發(fā)布接口,自動(dòng)化發(fā)布,其實(shí)是大多數(shù)公司的剛需。
打包發(fā)布完成,發(fā)給項(xiàng)目相關(guān)人,一封統(tǒng)計(jì)性郵件,也是非常有必要的。
總結(jié)
除去上面描述的幾點(diǎn),我們還做了諸如 環(huán)境參數(shù)配置 、 項(xiàng)目參數(shù)注入 、 無埋點(diǎn)統(tǒng)計(jì) 等通用邏輯,來解決并完善開發(fā)中所遇到的問題。
總結(jié)起來,去哪兒的小程序工程流程化主要包括三部分: 本地工具 、 模塊倉(cāng)庫(kù) 以及 發(fā)布系統(tǒng)關(guān)聯(lián) 。
-
本地工具:包括項(xiàng)目初始化、打包壓縮、模塊編譯、環(huán)境參數(shù)配置、項(xiàng)目參數(shù)注入、無埋點(diǎn)統(tǒng)計(jì)等等功能,主要解決開發(fā)過程中所遇到的問題和痛點(diǎn)。
-
模塊倉(cāng)庫(kù):模塊化方案的基礎(chǔ),管理模塊的版本。保證一個(gè)小程序使用多個(gè)模塊和一個(gè)模塊被多個(gè)小程序引用時(shí)的正確性。
-
發(fā)布系統(tǒng)關(guān)聯(lián):避免人工操作的繁瑣和易錯(cuò),自動(dòng)化完成打包、上傳、發(fā)布等流程。
hishop微信小程序可以實(shí)現(xiàn)一鍵開通微信小程序,結(jié)合移動(dòng)云商城,可以實(shí)現(xiàn)七大端口的線上和線下結(jié)合模式。
第二部分:如何開通一個(gè)小商店