注册
web

微信小程序开发大坑盘点

微信小程序开发大坑盘点


起因


前几天心血来潮,想给学校设计个一站式校园小程序,可以查询成绩,考试信息,课表之类的(本来想法里是还想包括一些社交功能的,但这个因为资质问题暂且搁置了)。其实很久以前就有大概了解过微信小程序的一些概念,那个时候试图用 uni-app 做,但是这玩意太难用所以不了了之了。


于是这次打算正经的用微信自己的那套东西做,结果不出意外的是入了深坑......


大坑


微信小程序云函数外部调用异常


微信小程序提供 wx.request 发起 HTTP 请求,由于微信不是浏览器,没有跨域限制,这方便了很多事,但是由于 wx.request 函数只能对 HTTPS 协议的地址发起请求,而我们学校的教务系统又是清一色的 HTTP,因此我需要一个可以用来帮助我发起 HTTP 请求的转发接口。


对于这种简单需求,云函数显然是最好的解决方案,进而我发现微信小程序自带云函数的支持,于是便兴冲冲地写了一段 NodeJS 代码,放上去跑。


结果我发现不知道为什么,请求其他网站都没问题,唯独请求我们教务系统就会原地超时。经过了几个小时的调试,最后以失败告终,转而改用腾讯云的云函数。


代码也十分简单:


const url = require('url')

const express = require('express');
const app = express()
const port = 9000

const rp = require('request-promise')

app.use(express.json());

app.post('/', async (req, res) => {
const jar = rp.jar()

try {
const response = await rp({
...req.body,
resolveWithFullResponse: true,
simple: false,
jar: jar
})
res.json(response)
} catch (e) {
res.json(e)
console.error(e)
}
})

app.listen(port, () => {
console.log("Successfully loaded")
})

其中额外引入了 request-promise 库(express 是默认引入的,腾讯云函数这里做的不错,对 npm 支持很好)。


然后做了一个模仿 wx.request 调用风格的 request 函数,这样我就可以在 wx.request 和我自己的 request 函数中无缝切换(更进阶的是,我自己写的这个还额外支持了以 Promise 风格调用。


export async function request(data) {
try {
const res = await rp({
...data,
uri: data.url,
headers: data.header,
})
let result = {
...res,
data: res.body,
header: res.headers
}
if (result.statusCode != 200) {
throw {
err_msg: "内部错误"
}
}
if (data.dataType === 'json') {
result.body = JSON.parse(result.body)
}
data.success && data.success(result);
data.complete && data.complete({})
return result;
} catch (e) {
data.fail && data.fail(e)
data.complete && data.complete({})
throw e;
}
}

function rp(data) {
return new Promise((resolve, reject) => {
wx.request({
method: 'POST',
url: 'https://service-abcdefg-123456789.gz.apigw.tencentcs.com/release/',
data: data,
success: (res) => {
resolve(res.data)
},
fail: (err) => {
reject(err)
}
})
})
}

ES6 module 和变量作用域支持差


不知道为什么,微信小程序完全不支持 ES6 module,即使它是支持 ES6 语法的。也就是说,你只能使用这种传统的 CommonJS 方式引入:


const module = require('module.js')

而不是 ES6 的 import 语法:


import module from 'module.js'

最离谱的是,微信小程序这个基于 VSCode 的编译器会给你 warn 这段代码,告知你可以转换为使用 import 导入。



于是这又引出了另外一个奇怪的问题:当你在一个界面的逻辑层文件上声明变量时,IDE 会认为这个变量是一个全局变量,因此在其他界面声明同名变量会得到一个 error,即使不会导致任何编译错误。


这导致了,现在我的模块引入必须用一种很奇怪的写法...


const sessionModule = require('../../utils/session');
const tgcModule = require('../../utils/tgc')
const cryptoModule = require('../../miniprogram_npm/crypto-js/index.js')

奇葩的 NPM 支持


在以前,微信小程序是不支持包管理器的,这也就意味着,你得手动把那些库的 JS 复制到你的项目目录里再引用,非常麻烦。但是现在好了,微信可以自动帮你做这件事了。


没错,是自动帮你复制,而不是做了包管理器支持。


怎么说呢...你需要先在你的项目源代码目录中 init 一个 package.jsonadd 你需要的包然后 install,接下来点击 IDE 顶栏的 Tools - Build npm 选项,Weixin Devtools 就会帮你生成一个 miniprogram_npm文件夹,将每个项目各自 combine 到一个 index.js 然后塞到各自名字的文件夹里,然后,你就能通过上面那种方式手动引入使用了。


很奇葩但是... 勉强能用(而且不限制使用的包管理器,比如我用的就是 yarn)。


避免使用双向绑定


微信小程序的 WXML 存在一个有限的双向绑定支持,也是类似 Vue 的那种语法糖:


<input model:value="{{value}}" />

但是这个双向绑定不知道为什么,在某些情况下会认为你没有设置一个 bindinput 事件(但实际上应该是由双向绑定自动设置的),于是不断地在后台刷警告,因此还不如手动实现来的省心。


有限的标准组件支持


如果你觉得微信小程序的开发和前端开发差不多,那就大错特错了。因为微信小程序默认情况下根本不支持任何 HTML 元素,而是套了一层他们自己的元素,比如 view 实际上是 classblock 则和 Vue 的 template 差不多(微信小程序也有 template 元素,只不过那个是给组件用的),不分 h1, h2, span, strong,只有 text 元素等。当然好在 CSS 还是那套,基本都能用。


但是... 微信小程序提供的元素依然太少了,根本没办法满足实际开发需要(比如根本没有表格元素)。于是微信小程序提供了一个 rich-text 元素,可用于渲染 HTML 元素。


但是这个 rich-text 就显得十分鸡肋,他不是通过 slot 传入 HTML 元素,而是通过 string 或者 object。这凭空增加了开发难度,导致我不得不这么写:


<rich-text nodes="{{nodes}}"></rich-text>

this.setData({
nodes: licenses.map(it => {
return `
<div style="margin: 20px 10px;"><strong>${it.projectName}</strong>
is licensed under the <code>${it.licenseName}</code>:</div>
<pre style="overflow: auto; background-color:#F5F6FA;"><code>${it.fullLicense}</code></pre>
${it.sourceRepo?`<div style="margin: 20px 10px;"><span style="color:gray; font-size: 12px;">The source code can be found at: ${it.sourceRepo}</span></div>`:""}
<br/><br/>
`

}).join("")
})

甚至这么写:



完美的回答了知乎有人“为什么不用 JSON 表达页面而是用类似 XML 一样的 HTML”的问题。


最后


虽然吐槽了这么多,但是微信小程序还是有一些不错的点的。除了上面说的宽松的跨域策略以外,微信小程序的 TypeScript 支持很完善,IDE 工具链做的也不错(除了他那个特别容易崩溃的 Simulator),加之微信开放社区的活跃度也不低(问问题一天内就有人回复),也算是能用了。


作者:HikariLan贺兰星辰
来源:juejin.cn/post/7228563544022761509

0 个评论

要回复文章请先登录注册