小程序开发踩坑汇总
前言
因为业务功能模块的需求,很多坑基本上都需要踩,比如引入第三方组件 vant, 引入 canvas,以及分包的问题。开发的环境是基于 Taro + Dva,外加魔改的一些配置
正文
真机调试问题
首先是在真机测试的时候,会出现之前的数据还遗留,或者说真机扫码开发者二维码一直在跳转没有进入页面。
这种问题一般是缓存和网络问题。
解决方案:
去真机把小程序从微信上删除,重新开发者工具的扫码入口进入
小程序预览,真机扫描无法正常请求接口,保证两者的 wifi 连接同一个即可。
canvas 引入
一般来说,按照官方文档是不够的,还得看 issue,看了也是不够的。因为还得自己处理引入后引发的问题。
微信版 canvas 官网: https://github.com/ecomfe/echarts-for-weixin
首先引入就是把 ec-canvas 这个文件夹下载过来放到自己的公共组件下
然后自己去官网定制 echarts.js, 记住不要选压缩。
在官网定制时不能勾选代码压缩,下载源文件后去专业的压缩网站压缩代码,再导入工程目录
压缩完成后下载替换文件下的同名文件。
之后要去 config/index.js 加配置
mini: {
...
compile: {
exclude: [
path.resolve(__dirname, '..', 'src/components/ec-canvas/echarts.js')
]
},
}
主要作用就是防止编译的时候再去编译它导致报错。
这时候工作只完成了一半,接下来是如何使用
在组件中引用
import * as echarts from '@components/ec-canvas/echarts';
因为是基于 Taro 开发的,因此还需要在组件配置中加上引用第三方组件的配置
usingComponents: {
'ec-canvas': '../../../../../../components/ec-canvas/ec-canvas'
}
state 里保存一个 ec 变量
this.state = {
ec: {
onInit: initChart
}
};
initChart 作为外部函数这么写
function initChart(canvas, width, height) {
chart = echarts.init(canvas, null, {
width: width,
height: height,
devicePixelRatio: 2 // 设置高清 对高分屏所做的优化,如果不是 2 倍的话显示的效果不会那么清晰
});
canvas.setChart(chart);
const dataAxis = [
];
const data =
];
const yMax = 500;
const dataShadow: any = [];
for (let i = 0; i < data.length; i++) {
dataShadow.push(yMax);
}
const option = {
...
}
chart.setOption(option);
return chart;
}
需要特别注意,默认的 devicePixelRatio 是 1,导致在高清移动屏上看到的效果非常模糊。需要设置为 2.
最终引用
<ec-canvas id="mychart-dom-bar" canvas-id="mychart-bar" ec={this.state.ec}></ec-canvas>
基本上可以跑起来。
引入成功后也会发现一个问题就是微信原生 canvas 层级最高问题,遮挡底部悬浮菜单和弹窗。也就是我们弹个 modal 都会发现被遮挡。
这里有种做法是启用 echart 的保存图片功能,将绘制完成的 canvas 保存成图片。
const ecComponent = this.$scope.selectComponent('#mychart-dom-bar');
if (!ecComponent) {
return;
}
ecComponent.canvasToTempFilePath({
success: res => {
this.setState({ img: res.tempFilePath });
},
fail: res => console.error('canvasToTempFilePath', res)
});
但这种做法会失去交互性。
我采用的做法是全局设置状态,当弹窗等等有遮罩的动作,设置一个标志,如果出现这个标志,就把图表用骨骼组件代替。当然也可生成一张图然后代替。
核心思路就是把 canvas 从组件中暂时隐藏。
当然,当你一旦打算引用了 ecchart, 那么必定会遇到预览 500k 限制的问题。
这个问题只能通过分包来解决。
分包
分包策略基本上官方文档都有
https://developers.weixin.qq.com/miniprogram/dev/framework/subpackages/independent.html
主要原则,分包里别调用主包的内容,然后该提到公共组件库的都题到公共组件库。
简单贴个配置
config: Config = {
pages: ['pages/index/index'],
subPackages: [
{
root: 'packageOrder',
name: 'packageOrder',
pages: ['index', 'confirm/index']
},
{
root: 'packageSetting',
name: 'packageSetting',
pages: ['index', 'myBill/index', 'feedback/index']
}
],
但是即使你分包成功,有时候还是主包过大,不让你用开发者预览功能,这个时候需要自己进行排查。
主包文件过大终极方案
首先该压缩的压缩,该抽公共的抽公共,然后该分包分包。如果还是大,可以参考以下案例。
首先肯定是先利用工具排查一下哪个包有问题
利用分析工具 webpack-bundle-analyzer
有时候主包只有 1.8m 也会报错提醒文件包过大
可能是开启了增强编译
它会导致我们的文件莫名变得更大
通用解决方案:
1、分包
2、云函数
在云函数文件夹里 npm 安装这个包,在云函数里引用你要引用的包,然后使用包的方法,云函数返回处理结果即可最后在云函数文件夹上右键 -> 上传并部署:所有文件
3、利用 webpack 将公共引用提取出去 splitChunks commonChunks
屏蔽引入第三方 UI 库 ts 报错信息
类型“JSX.IntrinsicElements”上不存在属性“van-dropdown-item”
引入的标签不存在
解决方案 就是 在全局的 index.d.ts 加上
declare namespace JSX {
interface IntrinsicElements {
'van-dropdown-menu': any;
'van-dropdown-item': any;
}
}
其他
基本上小问题都可以 Google 到答案,如果 Google 不到,就去官方 GitHub 的 issue 里找,总会有人踩过坑。如果还没有,可以去小程序官方社区
https://developers.weixin.qq.com/community/develop/
提问等等。