知識(shí)
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營銷的便利,運(yùn)營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!
您當(dāng)前位置>首頁 » 新聞資訊 » 小程序相關(guān) >
【babel+小程序】上
發(fā)表時(shí)間:2021-3-31
發(fā)布人:葵宇科技
瀏覽次數(shù):71
話不多說先上圖,簡要說明一下干了些什么事。圖可能太模糊,可以點(diǎn) svg 看看
背景
最近公司開展了小程序的業(yè)務(wù),派我去負(fù)責(zé)這一塊的業(yè)務(wù),其中需要處理的一個(gè)問題是接入我們web開發(fā)的傳統(tǒng)架構(gòu)-- 模塊化開發(fā) 。
我們來詳細(xì)說一下模塊化開發(fā)具體是怎么樣的。
我們的git工作流采用的是 git flow 。一個(gè)項(xiàng)目會(huì)拆分成幾個(gè)模塊,然后一人負(fù)責(zé)一個(gè)模塊(對(duì)應(yīng)git flow的一個(gè)feature)獨(dú)立開發(fā)。模塊開發(fā)并與后端聯(lián)通后再合并至develop進(jìn)行集成測(cè)試,后續(xù)經(jīng)過一系列測(cè)試再發(fā)布版本。
目錄結(jié)構(gòu)大體如圖所示,一個(gè)模塊包含了他自己的pages / components / assets / model / mixins / apis / routes / scss等等。
這種開發(fā)模式的好處不言而喻,每個(gè)人都可以并行開發(fā),大大提升開發(fā)速度。這次就是要移植這種開發(fā)模式到小程序中。
目標(biāo)
背景說完了,那么來明確一下我們的目標(biāo)。
我采用的是 wepy 框架,類vue語法的開發(fā),開發(fā)體驗(yàn)非常棒。在vue中,一個(gè)組件就是單文件,包含了js、html、css。wepy采用vue的語法,但由與vue稍稍有點(diǎn)區(qū)別,wepy的組件分為三種--wepy.app類,wepy.page類,wepy.component類。
對(duì)應(yīng)到我們的目錄結(jié)構(gòu)中,每個(gè)模塊實(shí)際上就是一系列的page組件。要組合這一系列的模塊,那么很簡單,我們要做的就是把這一系列page的路由掃描成一個(gè)路由表,然后 插入到小程序的入口--app.json中 。對(duì)應(yīng)wepy框架那即是app.wpy中的pages字段。
export default class extends wepy.app {
config = {
pages: 'modules/home/pages/index',//here!!!!
window: {
backgroundTextStyle: 'light',
navigationBarBackgroundColor: '#fff',
navigationBarTitleText: '大家好我是渣渣輝',
navigationBarTextStyle: 'black'
}
}
//...
}
掃描路由表
第一步!先得到所有pages的路由并綜合成一個(gè) 路由表 !
我的方案是,在每個(gè)模塊中新建一份routes文件,相當(dāng)于注冊(cè)每個(gè)需要插入到入口的page的路由,不需要接入業(yè)務(wù)的page就不用注冊(cè)啦。是不是很熟悉呢,對(duì)的,就是參考vue-router的注冊(cè)語法。
//routes.js
module.exports = [
{
name: 'home-detail',//TODO: name先占位,后續(xù)再嘗試通過讀name跳轉(zhuǎn)某頁
page: 'detail',//需要接入入口的page的文件名。例如這里是index.wpy。相對(duì)于src/的路徑就是`modules/${moduleName}/pages/index`。
},
{
name: 'home-index',
page: 'index',
meta: {
weight: 100//這里加了一個(gè)小功能,因?yàn)樾〕绦蛑付╬ages數(shù)組的第一項(xiàng)為首頁,后續(xù)我會(huì)通過這個(gè)權(quán)重字段來給pages路由排序。權(quán)重越高位置越前。
}
}
]
而掃描各個(gè)模塊并合并路由表的腳本非常簡單,讀寫文件就ok了。
const fs = require('fs')
const path = require('path')
const routeDest = path.join(__dirname, '../src/config/routes.js')
const modulesPath = path.join(__dirname, '../src/modules')
let routes = []
fs.readdirSync(modulesPath).forEach(module => {
if(module.indexOf('.DS_Store') > -1) return
const route = require(`${modulesPath}/${module}/route`)
route.forEach(item => {
item.page = `modules/${module}/pages/${item.page.match(/\/?(.*)/)[1]}`
})
routes = routes.concat(route)
})
fs.writeFileSync(routeDest,`module.exports = ${JSON.stringify(routes)}`, e => {
console.log(e)
})
路由排序策略
const strategies = {
sortByWeight(routes) {
routes.sort((a, b) => {
a.meta = a.meta || {}
b.meta = b.meta || {}
const weightA = a.meta.weight || 0
const weightB = b.meta.weight || 0
return weightB - weightA
})
return routes
}
}
最后得出路由表
const Strategies = require('../src/lib/routes-model')
const routes = Strategies.sortByWeight(require('../src/config/routes'))
const pages = routes.map(item => item.page)
console.log(pages)//['modules/home/pages/index', 'modules/home/pages/detail']
替換路由數(shù)組
So far so good...問題來了,如何替換入口文件中的路由數(shù)組。我如下做了幾步嘗試。
直接引入
我第一感覺就是,這不很簡單嗎?在wepy編譯之前,先跑腳本得出路由表,再import這份路由表就得了。
import routes from './routes'
export default class extends wepy.app {
config = {
pages: routes,//['modules/home/pages/index']
window: {
backgroundTextStyle: 'light',
navigationBarBackgroundColor: '#fff',
navigationBarTitleText: '大家好我是渣渣輝',
navigationBarTextStyle: 'black'
}
}
//...
}
然而這樣小程序肯定會(huì)炸啦,pages字段的值必須是靜態(tài)的,在小程序運(yùn)行之前就配置好,動(dòng)態(tài)引入是不行的!不信的話諸君可以試試。那么就是說,劃重點(diǎn)--- 我們必須在wepy編譯之前再預(yù)編譯一次 ---事先替換掉pages字段的值!
正則匹配替換
既然要事先替換,那就是要精準(zhǔn)定位pages字段的值,然后再替換掉。難點(diǎn)在于如果精準(zhǔn)定位pages字段的值呢?
最撈然而最快的方法:正則匹配。
事先定好編碼規(guī)范,在pages字段的值的前后添加 /* __ROUTES__ */
的注釋
腳本如下:
const fs = require('fs')
const path = require('path')
import routes from './routes'
function replace(source, arr) {
const matchResult = source.match(/\/\* __ROUTE__ \*\/([\s\S]*)\/\* __ROUTE__ \*\//)
if(!matchResult) {
throw new Error('必須包含/* __ROUTE__ */標(biāo)記注釋')
}
const str = arr.reduce((pre, next, index, curArr) => {
return pre += `'${curArr[index]}', `
}, '')
return source.replace(matchResult[1], str)
}
const entryFile = path.join(__dirname, '../src/app.wpy')
let entry = fs.readFileSync(entryFile, {encoding: 'UTF-8'})
entry = replace(entry, routes)
fs.writeFileSync(entryFile, entry)
app.wpy的變化如下:
//before
export default class extends wepy.app {
config = {
pages: [
/* __ROUTE__ */
/* __ROUTE__ */
],
window: {
backgroundTextStyle: 'light',
navigationBarBackgroundColor: '#fff',
navigationBarTitleText: '大家好我是渣渣輝',
navigationBarTextStyle: 'black'
}
}
//...
}
//after
export default class extends wepy.app {
config = {
pages: [
/* __ROUTE__ */'modules/home/pages/index', /* __ROUTE__ */
],
window: {
backgroundTextStyle: 'light',
navigationBarBackgroundColor: '#fff',
navigationBarTitleText: '大家好我是渣渣輝',
navigationBarTextStyle: 'black'
}
}
//...
}
行吧,也總算跑通了。因?yàn)轫?xiàng)目很趕,所以先用這個(gè)方案開發(fā)了一個(gè)半星期。開發(fā)完之后總覺得這種方案太難受,于是密謀著換另一種各精準(zhǔn)的自動(dòng)的方案。。。
相關(guān)案例查看更多
相關(guān)閱讀
- 報(bào)廢車拆解回收管理系統(tǒng)
- 云南網(wǎng)站設(shè)計(jì)
- 用戶登錄
- 做小程序被騙
- 云南花農(nóng)小程序
- 云南網(wǎng)站建設(shè)高手
- 網(wǎng)絡(luò)公司
- 網(wǎng)站排名
- 報(bào)廢車回收
- 云南軟件定制公司
- 小程序生成海報(bào)
- 網(wǎng)站建設(shè)公司地址
- 正規(guī)網(wǎng)站建設(shè)公司
- 云南手機(jī)網(wǎng)站建設(shè)
- 國內(nèi)知名網(wǎng)站建設(shè)公司排名
- web開發(fā)技術(shù)
- 云南網(wǎng)站建設(shè)優(yōu)化
- 小程序開發(fā)聯(lián)系方式
- 網(wǎng)站建設(shè)價(jià)格
- 云南建設(shè)廳網(wǎng)站首頁
- 昆明軟件定制公司
- 退款
- 楚雄小程序開發(fā)
- SEO
- 云南小程序開發(fā)費(fèi)用
- 云南網(wǎng)站建設(shè)報(bào)價(jià)
- 昆明網(wǎng)站開發(fā)
- 紅河小程序開發(fā)
- APP
- 小程序模板開發(fā)公司