什么?你要在mpvue当中加入taro项目,实现两个项目混合打包?
这听起来相当刺激,估计也很少人那样干,但其实原理并不复杂,并且能很好的实现新老框架的交替。
实现方式
我们项目中mpvue是作为主包的,mpvue和taro混合开发的,所以其实taro作为独立的应用,一开始就是作为mpvue的独立分包存在的。
"pages": [
"pages/index/index",
...
],
"subpackages": [
{
"name": "taro",
"root": "taro",
"pages": [
"pages/index/i",
...
],
"independent": true
}
]
以上是打包后的app.json,taro项目的代码都被打包在根目录的taro文件夹下,"independent": true指定了独立分包方式,上传后,taro目录的访问方式是形如taro/pages/index/i, 区别于主包的访问pages/index/index, 那如果要再加入一个分包,方式是一样的
"subpackages": [
{
"name": "taro",
"root": "taro",
"pages": [
"pages/index/i",
...
],
"independent": true
},
{
"name": "taro-event",
"root": "taro-event",
"pages": [
"pages/index/i"
],
"independent": true
}
],
"preloadRule": {
"pages/index/index": {
"network": "all",
"packages": [
"taro"
]
}
}
注意这里我们加了preloadRule,是为了分包预下载,加快访问速度,具体参考[developers.weixin.qq.com/miniprogram…]
原理解析1
首先要了解taro和mpvue的项目的集成方案,大致说下步骤:
- 分别打包taro和mpvue项目
- 将taro打包后的文件拷贝到mpvue的分包目录中
- 将taro的路由和mpvue路由集成到一个文件app.json中
我们看打包命令:
"build:test": "rimraf dist && npm run build:taro && node build/build.test.js -t && npm run transform"
npm run build:taro就是打包taro代码
node build/build.test.js就是打包mpvue代码
npm run transform就是修改app.json以集成路由
那么拷贝目录在哪里呢,其实已经集成到node build/build.test.js中,我们在/build/webpack.prod.conf.test.js文件中可以看到下面这段配置
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.test.assetsSubDirectory,
ignore: ['.*']
},
{
from: path.resolve(__dirname, '../taro/dist/weapp'),
to: "taro",
ignore: ['.*']
}
])
这里就是做了copy操作。
下面重点讲下集成路由npm run transform做了什么事
相关代码在build/taro-transform.js中,其实很简单,就是node的文件流读写,概括一下:
- 文件流操作taro的app.config.js文件,将其pages内容集成到app.json文件中
- 添加preloadRule
- taro中添加app.wxml文件,不然会报错
- 删除taro中的app.json除了pages以外的配置
基本上做了以上操作,项目就可以运行起来了
原理解析2-多个分包集成
我们先看最外层的打包taro的命令
"build:taro": "cd taro && npm run buildtest:weapp && npm run buildtestEvent:weapp"
我们发现,taro被打包了两次,这是为什么呢?其实每个分包都需要单独打包一次,这样才可以作为mpvue的独立分包,下面详细展开。
首先在taro中如何集成两个分包呢?我们看到taro的app.config.js
'subPackages': [
{
'root': 'pages',
'pages': [
'index/i',
...
]
}, {
'root': 'pages-event',
'pages': [
'index/i'
]
}
]
这里添加了第二个分包pages-event,其目录在taro/src/pages-event,taro当中的访问路由方式
/pages-event/index/i, 和第一个分包类似,但是打包需要另外打包,也就是taro需要打包两次,每个分包各一次,这是为了避免chunkid重复, 详见[项目拆分到多个分包]。需要再config/index添加如下代码
webpackChain(chain, webpack) {
chain.merge({
output: {
// 可以配合 npm script 和环境变量来动态修改
jsonpFunction: `webpackJsonp${process.env.JSONP_NAME_SUFFIX}`
}
})
}
这个JSONP_NAME_SUFFIX就是在打包命令中指定的环境变量
"buildtestEvent:weapp": "cross-env SPECIAL_ENV=test JSONP_NAME_SUFFIX=Event taro build --env production --type weapp"
这个命令区别与buildtest:weapp,它会被打包到另一个目录,因为我们在webpack中配置了:
outputRoot: `dist/${process.env.TARO_ENV}${process.env.JSONP_NAME_SUFFIX || ''}`
所以这个命令打包的代码会到dist/weappEvent当中去
现在两个分包打包完毕,需要集成到mpvue当中,需要注意几点:
因为不能和第一个分包放在一个目录下(taro目录),所以需要在dist根目录再建一个与taro同级的子目录,叫taro-event,所有的pages-event相关代码需要拷贝到这个目录下
那么这两个分包其实都是作为独立分包的形式存在在mpvue当中的,相互之间不影响,拷贝的时候需要注意,拷贝第一个分包需要忽略其他分包的代码,拷贝其他分包也是类似的,我们看/build/webpack.prod.conf.test.js
new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.test.assetsSubDirectory, ignore: ['.*']
},
{
from: path.resolve(__dirname, '../taro/dist/weapp'),
to: "taro",
ignore: ['pages-event/**']
},
{
from: path.resolve(__dirname, '../taro/dist/weappEvent'),
to: "taro-event",
ignore: ['pages/**', 'pages-event/**']
},
{
from: path.resolve(__dirname, '../taro/dist/weappEvent/pages-event'),
to: "taro-event/pages"
}
])
其他的操作和第一个分包一致。
那么在mpvue中访问第二个分包的路由就变成了taro-event/pages/index/i, 这个和在taro中访问的不一致,那么就需要一个公共的方法来区分是taro本地环境访问的,还是打包后线上环境访问的,类似如下
function getSubBaseRoute() {
return process.env.NODE_ENV === 'development' ? '/pages-event' : '/taro-event/pages'
}
Taro.navigateTo({ url: `getSubBaseRoute()/index/i` })
注意事项
因为都是独立分包,相互之间不共享store,能通讯的方式只有storage和url params,所以需要注意分包之间跳转时不用用其他分包当中的store