目前小程序分包大小有以下限制:
整个小程序所有分包大小不超过 8M
单个分包/主包大小不能超过 2M
所以说8M的限制是要分包至少4个包,单个分包上限其实还是2M
解决这个问题一种是分包
官方给出的分包官网文档
另一种是减少包中的图片
其实造成包体积过大的因素,很大原因是因为包里有图片,那体积就会变得很大。那我们可以将图片上传到CDN上,变成网络链接,这样的话就不会把图片打包进去了。但是这样又有一个不足,比如说我们一开始开发项目的时候,UI同学给了我们设计图,那我们要将图片一张张的上传到CDN上去吗?如果后期UI走查的时候要换图片呢?而且万一CDN上的图片被人误删了或者服务到期了呢(当然这种可能性很小,但也可以考虑进去),这时候我们的原图都会找不到,只能干着急。。。
那么最好的方式就是将图片放在项目中,本地开发的时候引用的就是本地的,增删改找起来也方便,但是打包构建的时候将图片压缩并上传CDN,同时将项目中的图片引用路径改成网络链接,然后删除dist中的所有图片。那么接下来我们就写个脚本实现一下。
直接上代码吧
先写上传方法,用于打包完上传,先压缩再上传到阿里oss
// config/upload.js
const OSS = require("ali-oss");
const fs = require("fs");
const path = require("path");
const rimraf = require("rimraf");
const imagemin = require('imagemin')
const imageminJpegtran = require('imagemin-jpegtran')
const imageminPngquant = require('imagemin-pngquant')
const imageminSvgo = require('imagemin-svgo')
const imageminGifsicle = require('imagemin-gifsicle')
const client = new OSS({
region: "",
endpoint: "",
accessKeyId: "",
accessKeySecret: "",
bucket: ""
});
async function compress() {
const files = await imagemin(['../dist/**/*.{jpg,jpeg,png,svg,gif}'], {
destination: '../dist/assets',
plugins: [
imageminJpegtran({
progressive: true,
quality: 80,
}),
imageminPngquant({
quality: [0.6, 0.8],
}),
imageminSvgo({
plugins: [{ removeViewBox: false }],
}),
imageminGifsicle(),
],
})
console.log('compress all images success!'.info)
return files
}
const putOSS = async function(src, dist) {
try {
let result = await client.put(dist, src);
console.log("oss上传成功: " + result.name);
} catch (e) {
console.log(e);
}
};
const workList = [];
/**
*
* @param {string} src 需要上传的文件夹
* @param {string} dist oss文件夹
*/
const addFileToOSSSync = function(src, dist) {
try {
await compress()
var docs = fs.readdirSync(src);
} catch (error) {
console.log(src + "不存在");
return;
}
docs.forEach(function(doc) {
const _src = src + "/" + doc;
const _dist = dist + "/" + doc;
const st = fs.statSync(_src);
// 判断是否为文件
if (st.isFile() && doc !== ".DS_Store") {
workList.push(putOSS(_src, _dist));
// console.log(_src + '是文件', _dist);
} else if (st.isDirectory()) {
addFileToOSSSync(_src, _dist);
}
});
};
addFileToOSSSync("dist/assets", "weixin/gongyi/sdg/images");
Promise.all(workList).then(res => {
rimraf(path.join(__dirname, "../dist/assets"), error => {
if (error) {
throw error;
}
console.log("done!");
});
});
上传方法写完了,什么时候调用呢,应该在构建完之后调用,因为上传完要删除包中dist下的图片,那么我们应该package.json中更改命令
// package.json
"build:weapp": "NODE_ENV=online taro build --type weapp && node config/upload.js"
还有设置一个全局变量
// Taro打包入口处
const ossPath = '你的cdn域名'
let projectPublicPath = '/'
if (process.env.NODE_ENV !== 'development') {
// 你上传的cdn路径
projectPublicPath = `${ossPath}/1v1mp/${process.env.TARO_ENV}/${process.env.NODE_ENV}`
}
let assetsPre =
process.env.TARO_ENV === 'weapp'
? process.env.NODE_ENV === 'development'
? ''
: projectPublicPath
: ''
var config = {
// ...其他配置正常写,主要是注意这两项
alias: {
'@': path.resolve(__dirname, '..', 'src'),
},
defineConstants: {
assetsPre: `"${assetsPre}"`,
},
}
最后使用需要注意:
-
所有图片文件放入
src/assets
目录下,可以在assets
目录下创建各模块目录 -
使用
import
引入后在src
处使用${assetsPre}${pic}
的方式使用,assetsPre
是全局定义好的常量,可以直接使用。例如:
import pic from '@/assets/defualt.jpg' export default function Index() { // do some logic return <Image src={`${assetsPre}${pic}`} /> }
tip: 有一点要说一下,虽然import引入了,但其实是个pic是个路径,webpack5以前会把它通过loader转为路径,webpack5通过内置Asset Modules转为路径。具体文档可见:加载images图像