基于taro搭建小程序多項目框架
前言
為什么需要這樣一個框架,以及這個框架帶來的好處是什么?
從字面意思上理解:該框架可以用來同時管理多個小程序,并且可以抽離公用組件或業務邏輯供各個小程序使用。當你工作中面臨這種同時維護多個小程序的業務場景時,可以考慮使用這種模式。靈感來自webpack的多項目打包構建
起步
首先你得先安裝好taro腳手架,然后基于該腳手架生成一個taro項目
初始化taro項目
taro init miniApp
這是我選擇的初始化配置,你當然也可以選擇其它模版,只要編譯工具選擇webpack就可以,下面的步驟基本相同
打開項目安裝依賴
pnpm install
這樣一個基本的taro項目就生成好了,但這樣只是生成了一個小程序,那我們如果有許多個小程序是不是還要按上面這些步驟繼續生成,當然不需要,這樣不僅費時間,而且難以維護。
下面我們就來把這個框架改造成支持同時管理多個小程序。
改造(支持多小程序)
此時的項目結構是這樣的:
- config下面是一些小程序以及webpack的配置
- src下面是我們小程序的項目代碼
- project.config.json是當前小程序配置文件
- ...
改造目錄
在src目錄下新增目錄:apps、common
- apps:小程序目錄,存放各個小程序的代碼
- common:公用目錄,存放公用組件及業務邏輯代碼
apps
這里每個小程序對應一個文件夾,里面存放對應小程序的代碼
這里需要把根目錄下的project.config.json放到小程序目錄下,因為每個小程序都需要自己的配置文件
比如:nanjiu、nanjiu_notebook兩個小程序
common
這里主要是存放公用代碼:組件、業務、請求
修改配置
config/index.js
import path from 'path'
const app = process.env.APP
const config = {
projectName: 'mini_app',
date: '2024-1-21',
designWidth: 750,
deviceRatio: {
640: 2.34 / 2,
750: 1,
828: 1.81 / 2
},
sourceRoot: `src/apps/${app}`, // 項目源碼目錄
outputRoot: `${app.toUpperCase()}APP`, // 打包產物目錄
alias: {
'@/common': path.resolve(__dirname, '..', 'src/common'), // 別名配置
},
// ....
module.exports = function (merge) {
if (process.env.NODE_ENV === 'development') {
return merge({}, config, require('./dev'))
}
return merge({}, config, require('./prod'))
}
這里需要注意的是sourceRoot,因為要支持多小程序,那么這里就不能固定寫死了,我們可以在啟動時通過傳參來區分當前啟動或打包哪個小程序。
自定義構建腳本
在項目根目錄新建文件夾build存放構建腳本
// cli.js
const shell = require('shelljs')
const fs = require('fs')
const path = require('path')
const inquirer = require('inquirer')
const action = process.argv[2]
let app = process.argv[3]
const runType = action == 'dev' ? '啟動': '打包'
function start() {
// 處理配置文件
process.env.APP = app
console.log(`????????????正在${runType}小程序:${app}`)
let cmd = ''
if(action == 'dev') {
cmd = `taro build --type weapp --watch --app ${app}`
} else {
cmd = `taro build --type weapp --app ${app}`
}
const child = shell.exec(cmd, {async:true})
child.stdout.on('data', function() {
// console.log(data)
})
}
// ...
start()
配置腳本命令
//package.json
// ...
"scripts": {
"start": "node build/cli.js dev",
"build": "node build/cli.js build",
}
驗證
所有工作完成后,可以來看看這個框架能不能滿足我們的需求
命令執行成功,項目根目錄下會生成對應的小程序代碼
再把該產物使用小程序開發者工具看是否能跑起來
這邊能夠跑起來,就說明打包沒有問題了,同樣可以驗證其它的小程序
優化構建腳本
多小程序架構搭建完,有同事反饋啟動報錯,我心想:不能吧,我自己都驗證過了,從報錯信息上看他應該是啟動時沒輸入需要啟動的小程序,直接pnpm start了,這樣的話就不知道應該啟動哪個小程序了。其實啟動命令已經在項目文檔上寫了,可能是沒注意看。
那就只能優化優化,盡量避免這種情況,這里主要的邏輯是如果沒有輸入指定的的小程序,通過inquirer開啟交互式命令,讓他選擇要啟動哪個小程序。
// cli.js
const shell = require('shelljs')
const fs = require('fs')
const path = require('path')
const inquirer = require('inquirer')
const action = process.argv[2]
let app = process.argv[3]
const runType = action == 'dev' ? '啟動': '打包'
if(!app) {
openInquirer()
return
}
// 未輸入項目名稱則開啟交互命令行
function openInquirer() {
const projectList = fs.readdirSync(path.resolve(__dirname, '../src/apps'))
// 過濾隱藏文件
projectList.forEach((item, index) => {
if(item.indexOf('.') == 0) {
projectList.splice(index, 1)
}
})
const promptList = [
{
type: 'list',
message: '??請選擇啟動的小程序:',
name: 'pro',
choices: [...projectList],
},
]
inquirer.prompt(promptList).then((answers) => {
app = answers.pro
start()
})
}
function start() {
// 處理配置文件
process.env.APP = app
console.log(`????????????正在${runType}小程序:${app}`)
let cmd = ''
if(action == 'dev') {
cmd = `taro build --type weapp --watch --app ${app}`
} else {
cmd = `taro build --type weapp --app ${app}`
}
const child = shell.exec(cmd, {async:true})
child.stdout.on('data', function() {
// console.log(data)
})
}
start()
這樣就大功告成了!!!