概述:
分包速度快登颓,第一版穩(wěn)定性較強,后臺修改較少红氯,需要主包配合一些配置框咙,但后期可能每次都需要主包進行一些配合咕痛。 (速度型,類似sdk)
插件修改內(nèi)容較多喇嘱,開發(fā)速度較慢茉贡,第一版相對不穩(wěn)定,后臺配合修改較多者铜,也需要主包進行一點配置块仆,暫不支持手機號獲取等部分API,但后期操作可能更加獨立王暗,更適合其它小程序?qū)印#ㄩL遠型)
- 注意:2.12.2基礎(chǔ)庫后插件頁就可以調(diào)小程序組件了庄敛,也就是可以實現(xiàn)手機號俗壹、用戶信息獲取功能而無需功能頁,但是只能小程序組件只能在插件頁使用藻烤,不能在插件的組件中使用绷雏。
插件不能使用及處理:
- getApp() ===> getApp()替換成處理vue 的store
- 獲取用戶信息、手機號 ===> 用戶功能頁/2.12.2基礎(chǔ)庫調(diào)小程序組件(僅插件頁)
- 其它Api ===> 可通過小程序提供方法 給插件怖亭,插件回調(diào)小程序方法 間接調(diào)取微信Api (js 中重寫Api方法)
- ext.json ===> 需通過將插件ext.json合并到小程序ext.json中通過插件回調(diào)小程序提供方法方式間接獲取
- 路由 ===> navigateTo url處理涎显,底層磨平使用plugin-private://wxXXXXXXXX+url 跳轉(zhuǎn)
tips: 外部直接跳會員中心小程序頁面:(_plugin_/wxXXXXXXXX+url)
插件改造步驟
嵌套模式開發(fā) : 一套代碼,子目錄為小程序目錄兴猩,外層目錄為插件殼目錄期吓。從而實現(xiàn)一套代碼開發(fā)插件與小程序,小程序從小程序目錄運行倾芝,插件通過外殼編譯后使用微信開發(fā)者工具運行讨勤。
插件判斷:頁面中可以通過方法(getCurrentPages..pop().route中是否包含plugin/Appid )判斷是否是插件
非頁面中不能判斷是否是插件
插件開發(fā)策略:盡量通過全局處理方式進行處理,避免過多的差異開發(fā)
改造流程:
->首先:git新增分支插件+小程序dev作為日后開發(fā)分支晨另。
->分支集成添加vue-cli
->安裝uniapp2wxpack
->將小程序項目配置到src中
->修改插件測試主程序內(nèi)容(pluginActions.js潭千、functionalPages、插件引入借尿、跳轉(zhuǎn)插件鏈接)
(注意:主程序可通過pluginActions.js 提供接口方法刨晴、變量給插件,插件通過plugin.json可提供組件路翻、頁面狈癞、接口js給主程序。)
->插件跳轉(zhuǎn)鏈接:plugin://插件名/插件頁名或 plugin-private://wxXXXXXXXX/+url茂契,一般用第一種亿驾,因為不對外暴露頁面路徑
npm run dev:mp-weixin-pack-plugin (開發(fā)模式) 方便調(diào)試
npm run build:mp-weixin-pack-plugin (生產(chǎn)模式)打出的包小
相關(guān)命令:
-> npx uniapp2wxpack --create (安裝uniapp2wxpack)
-> npm run dev:mp-weixin-pack-plugin (打包)
開發(fā)優(yōu)化:
切換小程序/插件開發(fā)需要在項目src目錄下手動執(zhí)行build.js 重新生成pages.json, 通過pages-gaps.json文件配置小程序與插件在pages.json中的差異點
-> 執(zhí)行 “ node ./build.js app “或“ node ./build.js “生成 小程序 pages.json
-> 執(zhí)行 node ./build.js plugin 生成 插件 pages.json
如果使用全局變量切換項目是否是插件可重寫main.js添加MP_Plugin字段實現(xiàn)
build文件內(nèi)容
/*
處理pages.json內(nèi)容插件/小程序差異
-> cd 到build.js 所在目錄
-> 執(zhí)行 “ node ./build.js app “或“ node ./build.js “生成 小程序 pages.json
-> 執(zhí)行 node ./build.js plugin 生成 插件 pages.json
*/
const fs = require('fs')
var arguments = process.argv.splice(2);
/* pages.json */
// 讀
let pagesJson = fs.readFileSync(__dirname + '/pages.json','utf8')
let gapsJson = fs.readFileSync(__dirname + '/pages-gaps.json','utf8')
// 改
pagesJson = JSON.parse(pagesJson);
gapsJson = JSON.parse(gapsJson);
if(arguments.length>0){
if ((typeof pagesJson) === "object") {
findGaps(pagesJson,arguments[0])
}
}
function findGaps(obj,type){
for(let key in obj){
let item = obj[key];
if ((typeof item) === "object") {
if (item.gaps_key && item.gaps_title) { // 找到差異點
changeGaps(item,type)
}
findGaps(item,type)
}
}
}
function changeGaps(obj,type){
let change = "";
if (type == 'plugin') { // 插件
if(gapsJson.plugin[obj.gaps_key]){
change = gapsJson.plugin[obj.gaps_key]
}
} else { // 小程序
if(gapsJson.app[obj.gaps_key]){
change = gapsJson.app[obj.gaps_key]
}
}
obj[obj.gaps_title] = change;
}
// 寫
fs.writeFile(
__dirname + '/pages.json',
// 我這邊是用兩個空格來縮進 pages.json账嚎,如果喜歡制表符莫瞬,第三個參數(shù)更換你為 \t 即可
JSON.stringify(pagesJson, null, '\t'),
e => e ? console.error(e) : console.log('pages.json 配置文件更新成功')
)
/* main.js */
let mainJs = fs.readFileSync(__dirname + '/main.js','utf8')
if(arguments.length>0){
let strA = "import Vue from 'vue'\nVue.prototype.MP_Plugin = true;\n";
let strB = "import Vue from 'vue'\nVue.prototype.MP_Plugin = false;\n";
if (arguments[0] == 'plugin') { // 插件
changeMP_Plugin(strA, strB);
} else { // 小程序
changeMP_Plugin(strB,strA);
}
}
function changeMP_Plugin(newStr,oldStr){
if(mainJs.indexOf(newStr) > -1){ // 不用修改
return;
}
if(mainJs.indexOf(oldStr) > -1){
var reg= new RegExp(oldStr,"g");
mainJs = mainJs.replace(reg,newStr)
} else {
if(mainJs.indexOf("import Vue from 'vue'") > -1){
var reg= new RegExp("import Vue from 'vue'","g");
mainJs = mainJs.replace(reg,newStr)
}else{
console.log("未找到import Vue from 'vue'")
}
}
}
fs.writeFile(
__dirname + '/main.js',
// 我這邊是用兩個空格來縮進 main.js儡蔓,如果喜歡制表符,第三個參數(shù)更換你為 \t 即可
mainJs,
e => e ? console.error(e) : console.log('main.js 配置文件更新成功')
)
pages-gaps.json文件內(nèi)容:
mini-program-plug-xxx-comp: 插件中使用小程序的組件
{
"http://" : "差異json配置說明: 在pages.json 中有差異地方添加屬性gaps_key和gaps_title( \"gaps_key\": \"gaps_xxx\",\"gaps_title\": \"yyy\" 疼邀,在此文件中寫差異配置喂江,key 為gaps_key定義的值)",
"app" : {
"gaps_home_style":{
"enablePullDownRefresh": true,
"mp-weixin": {
"usingComponents": {
"cell": "plugin://contactPlugin/cell"
}
}
}
},
"plugin" : {
"gaps_home_style":{
"enablePullDownRefresh": true,
"componentGenerics":{
"mini-program-plug-xxx-comp":true
}
}
}
}
總括
src添加文件:
build.js : 用來執(zhí)行生成pages.json ,從插件開發(fā)切換到小程序開發(fā)或從小程序開發(fā)切換到插件開發(fā)時使用,命令node ./build.js plugin
pages-gaps.json: 配置pages.json中插件與小程序差異內(nèi)容文件
plugin-fit.js: 底層磨平插件與小程序差異內(nèi)容(api調(diào)用旁振,方法等)
主程序添加文件:
pluginActions.js : 主程序供插件調(diào)用api方法
ext.json : 插件ext配置文件(合并主程序中)
plug-xxx-comp組件: 外部組件供插件使用(處理插件一些無法調(diào)用的組件)
app.json配置:
"plugins" : {
"xxx" : {
"version" : “1.0.0”,
"provider" : "wxXXXXXXXXXX",
"export" : "pluginActions.js",
"genericsImplementation": {
"xxx-home": {
"mini-program-plug-xxx-comp": "component/plug-xxx-comp/plug-xxx-comp"
}
}
}
},
"functionalPages" : {
"independent" : true
},
"permission": {
"scope.userLocation": {
"desc": "根據(jù)位置進行定位"
}
}
tips:主包使用不了分包的組件获询,分包可以使用主包的組件
底層磨平文件plugin-fit.js內(nèi)容:
/*
插件處理
*/
import Vue from 'vue'
// Api
uni.getExtConfigSync = function() {
return actionApi("getExtConfigSync")
}
uni.authorize = function(params) {
console.log('authorize');
return actionApi("authorize",params)
}
wx.addCard = function(params){
return actionApi("addCard",params);
}
uni.clearStorageSync = function(params) {
return actionApi("clearStorageSync",params)
}
uni.hideKeyboard = function() {
return actionApi("hideKeyboard")
}
uni.saveFile = function(params) {
return actionApi("saveFile",params)
}
uni.getSavedFileList = function(params) {
return actionApi("getSavedFileList",params)
}
uni.checkSession = function(params) {
return actionApi("checkSession",params)
}
uni.login = function(params) {
return actionApi("login",params)
}
uni.getUserInfo = function(params) {
return actionApi("getUserInfo",params)
}
// 插件小程序跳轉(zhuǎn) 如果是本地則直接返回
uni.navigateToMiniProgram = function(params) {
if (params["appId"] == uni.getAccountInfoSync().miniProgram.appId) {
return uni.navigateBack({
delta:1000,
});
}
return actionApi('navigateToMiniProgram', params);
}
uni.getAccountInfoSync = function(){
return actionApi("getAccountInfoSync");
}
// route
const pluginUrlHead = "plugin-private://wxXXXXXXXXXX";
defineRoute ('navigateTo')
defineRoute ('switchTab')
defineRoute ('reLaunch')
defineRoute ('redirectTo')
var unit = require("@/common/unit/unit.js");
function defineRoute(name) {
const originRoute = uni[name];
Object.defineProperty(uni, name, {
configurable: true,
enumerable: true,
writable: true,
value: function (obj) {
if (!Vue.prototype.MP_Plugin) {
return originRoute(obj);
}
if(obj.url.indexOf('/xxxxx')>-1){
let mall_appid = unit.getMallAppid();
let mall_path = unit.getMallAppPath();
console.log(mall_appid)
uni.navigateToMiniProgram({
appId: mall_appid,
path: mall_path,
success(res) {
},
fail(err) {
}
})
return;
}
console.log("url",obj);
var newurl = pluginUrlHead + obj.url;
if(obj.miniProgram_page){
return originRoute({
url:obj.url
});
}else{
return originRoute({
url:newurl
});
}
}
})
}
// Storage 存儲
const getStorageSync = uni.getStorageSync;
uni.getStorageSync = function(key) {
if(Vue.prototype.MP_Plugin && key == 'userInfo'){
return requireMiniProgram().getMemberUserinfo();
}
return getStorageSync(key);
}
/**
* api調(diào)用
* apiName api 名稱
* params 參數(shù)
*/
function actionApi(apiName,params) {
let originApi = null;
// #ifdef MP-WEIXIN
originApi = wx[apiName];
// #endif
// #ifndef MP-WEIXIN
originApi = uni[apiName];
// #endif
if (!Vue.prototype.MP_Plugin) { // 小程序還執(zhí)行原始api
return originApi(params);
}
return requireMiniProgram().xxxPublic(apiName, params);
}
pluginActions.js文件內(nèi)容
module.exports = {
//名稱 需要 xxxPublic
xxxPublic(funName, param) {
return wx[funName](param);
},
getMemberUserinfo(){
return wx.getStorageSync('userInfo');
}
}
========================================================================================================================
小程序使用插件修改內(nèi)容:
1.app.json
"subPackages": [
{
"root": "pages/xxx/",
"pages": [
{
"http://": "授權(quán)頁",
"path": "plugin-auth",
"style": {}
}
],
"plugins": {
"xxx": {
"version": "1.0.0",
"provider": "wxXXXXXXXXXX",
"export": "pluginActions.js",
"genericsImplementation": {
"xxx-home": {
"mini-program-plug-xxx-comp": "component/plug-xxx-comp/plug-xxx-comp"
}
}
},
"contactPlugin": {
"version": "1.3.0",
"provider": "wx104a1a20c3f81ec2"
}
},
"functionalPages": {
"independent": true
},
"permission": {
"scope.userLocation": {
"desc": "根據(jù)位置進行定位"
}
}
}
]
- 單獨文件夾添加 plugin-auth 授權(quán)頁、pluginActions.js拐袜、plug-xxx-comp
3.ext中添加內(nèi)容
"ext": {
"version": "1.0",
"api_url": "https://x x x/", // 插件網(wǎng)絡(luò)請求地址
"mall_appid": "", // 其它小程序id吉嚣,沒有“”即可
"mall_path": "" // 其它小程序path,沒有“”即可
},
4.需要跳轉(zhuǎn)插件的地方直接跳轉(zhuǎn)授權(quán)頁就行蹬铺,授權(quán)頁已授權(quán)會直接跳插件尝哆,未授權(quán)會展示授權(quán)頁內(nèi)容