- 使用 webpack 打包小程序
前言 针对目前市面上出现的各种小程序,如百度小程序,支付宝小程序,字节跳动小程序,快手小程序。 小程序原生开发对于开发者的开发体验并不是很友好,那如何解决这个问题呢? 问题点 样式预处理 TypeScript支持 多环境打包支持 可扩展性 如在小程序内支持md文档格式,json格式等 多端支持 问题如何解决 使用webpack 来处理以上一系列问题 webpack 官方介绍就是静态文件的打包器 [图片] 上图所做的工作就是 项目中所有的静态文件 如js wxss wxml png jpg 通过webpack处理,可以输出到特定环境下可以运行的代码,webpack就是导入一些入口文件然后通过编译输出结果 [图片] 回顾小程序 首先小程序由项目入口组成 脚本逻辑 [图片] 配置 [图片] 其次小程序也由页面/组件 组成 脚本逻辑 模版 样式 配置 因为小程序的项目中每个文件都是独立的,比如小程序一个页面由js,json,wxml.wxss组件,而不是像web一样可以将文件打包在一起,这样我们使用webpack打包小程序就有一定的限制条件,既然输出的结果一定要按照小程序的规范,那么入口文件也要根据要求去操作,可能webpack 配置就不是一个单页面的配置,就要考虑使用多入口的方式实现,那么就要解决如下问题点: 确定入口文件 在小程序的app.json中会有一个pages 里面都是小程序中所有的页面,那么我们可以通过一个方法getPages获取这些页面的所有内容如js,json,wxss,wxml等信息,但是有个问题就是因为页面中可能包含有很多组件部分,所以还需要去解析页面组件的依赖,可以通过页面json中 usingComponents 配置去解析 [图片] [图片] 如图所示,页面有很多组件组成,我们可以通过一个方法getComponents方式,用递归的方式获取到项目页面中所有的组件信息,包含组件模版,样式 编译模版 问题点:webpack 无法直接去编译小程序的wxml文件 如何解决:可以自定义一个loader去解析这些文件,让webpack能够识别到。 [图片] [图片] 通常导出⼀一个函数,⼊入参为上⼀一个 loader 的返回值,可以有多个⼊入参,通常为源码 返回值⼀一般为处理理后的代码,如要返回多个值,⽤用 this.callback() 使⽤用 loader-utils 来辅助处理理,例例如通过 loader-utils 获取 loader 传⼊入 options,⼀个 loader 只处理理单一事务 处理样式 可以使用如下loader编译小程序样式 saas-loader/less-loader -> postcss-loader -> css-loader -> filer-loader [图片] 处理配置 考虑一个问题,小程序的配置文件是一个json文件,我们是否可以通过webpack的file-loader去编译 [图片] 上图中的确可以处理我们页面的配置文件,但是有个问题就是如果页面文件夹中出现另一个json文件,比如是一些静态数据的json文件,我们知道小程序是不能从本地引用本地文件,所以必须要通过一个loader去做这些事 [图片] 移除不必要的文件 [图片] 通过file-loader 打包之后会出现以下红色框的文件,但是我们小程序是不需要这些文件的,那么如何移除呢?我们知道webpack的编译过程是 [图片] Compiler 负责⽂文件监听和启动编译,包含完整 webpack 配置,全局唯⼀ compiler.hooks.* entryOption run watchRun compilation Compilation 第⼀次以及监听到⽂文件变化创建,包含当前模块信息、编译⽣生成资源等信息 compilation.hooks.* buildModule optimize beforeChunkAssets optimizeChunkAssets [图片] 编译结果输出还不是很优雅还需要完善,后续要通过抽离公共代码,封装一些插件优化。。。
2020-04-28 - webpack为小程序输出npm包
我知道小程序支持npm包构建,但没有很好的解决npm包的深依赖,导致有很多好的Npm包不能被使用。so~,使用webpack来解决这个问题 [代码]const path = require('path'); module.exports = { entry: './_hp2.js', output: { filename: 'hp2.js', path: path.resolve(__dirname), libraryTarget: 'commonjs2' }, mode: 'production', module: { rules: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader', options: { babelrc: false, presets: [ 'env', 'stage-0' ] } } ] } }; [代码] _hp2.js [代码]module.exports = require('...') // npm包名称 [代码] 注意[代码]libraryTarget: 'commonjs2'[代码]一定要设置,保证require的文件能够被正确引入 这样输出的js文件可以直接被小程序调用
2019-11-26 - recorderManager.start()调用之后为什么没有反应?
mikestart() { const recorderManager = wx.getRecorderManager() const innerAudioContext = wx.createInnerAudioContext() const recordOptions = { duration: 6000, // 录音的时长,单位 ms,最大值 60000(1 分钟) sampleRate: 44100, // 采样率 numberOfChannels: , // 录音通道数 encodeBitRate: 192000, // 编码码率 format: 'aac'// 音频格式,选择此格式创建的音频消息,可以在即时通信 IM 全平台(Android、iOS、微信小程序和 Web)互通 }; // 3. 开始录音 // wx.showLoading({ // title: '开始录音', // mask: true // }) console.log(recordOptions) recorderManager.start(recordOptions); recorderManager.onStart(() => { console.log('recorder start' }) }, recordOptions可以打印,监听函数内的不打印
2020-01-06 - 实时数据推送,今天一超时bug?
Error: errCode: -402002 realtime listener init watch fail | errMsg: Error: wsclient.send timedout (initWatch requestId 1573471762483_0.9670197861152376)。 问题描述:云函数创建数据不会,云控制台改变数据不会,但是云函数更新数据就这样的bug。 超时后,就一直这样了,就算删除云数据库中该集合的所有数据,就一直超时了。不会报其他的错误。
2019-11-11 - 关于云开发新服务“实时数据推送”,你需要了解的全在这了!
“微信小程序工程师邓坤力带你了解如何利用千呼万唤始出来的云开发实时数据推送服务打造生动的小程序和小游戏!” 在数据库在小程序·云开发中的应用一文中,我们了解到实时数据推送作为云开发即将上线的一项新能力,主要指客户端使用官方SDK发起socket连接建立对一个集合的监听,目标集合中如果有符合过滤条件的数据发生变更,将会直接推送到建立监听的客户端。 [图片] 简单来说,使用实时数据推送可以更有效率的拉取数据,帮你把你的应用变成实时有状态,场景会非常有用,比如可以用来做弹幕,做实时排名更新,做实时刷新,或者实时推送一些通知给到用户。 那么,实时数据推送具体是如何为小程序与小游戏赋能,提升开发效率的?让我们跟随微信小程序工程师邓坤力一起,深入了解这项新服务诞生的来龙去脉。 为什么要做实时数据推送? 介绍实时数据推送服务之前,弄懂一个直击灵魂问题将有助于我们的理解,那就是“为什么要做实时数据推送?” 想要更回答这个问题,需要从即时通信服务说起。 [图片] 我们都知道建立一个简单、常规的即时通信服务需要长连作为实现实时性的基础,需要足够的存储来保证消息与文件的持久化,还需要实时推送功能来实现主动同步客户端的能力。在此过程中,开发者往往需要面临: (1)需从零自建完整服务,无法聚焦在原型和核心业务开发上。 (2)开发成本高。由于前后端逻辑复杂,开发者往往需要经历设计基础设施搭建,长连管理、数据库开发、安全管理等琐碎繁杂的步骤。 (3)维护成本高。开发者还需负责维护,完成基础设施管理、异常处理等。 (4)微信能力集成。自建服务器的开发者如要基于微信用户登录态进行操作并让小程序安全运行,就不可避免地需要接入微信鉴权体系,整合accesstoken和 sessionkey流程并保证其安全性。 看到这里,可能有很多读者已经想到了具有开箱即用、集成原生微信能力、自带云数据库、云函数、云存储的云开发,那么云开发的这些优势能否有效解决开发者在建立即时通信服务中常常会遇到的难题呢? 答案是不完全能,由于云开发不支持长连,并且不具备主动同步客户端的能力,因此只能通过短轮询以次级长连和推送的次级替代方案,在即时通讯服务构建时往往需要面临短轮询带来的资源浪费、成本与体验难平衡以及实时性差等问题。 [图片] 可能又有小伙伴要问了,让云开发支持长连不就可以弥补这些缺陷?答案也是否定的,因为若云开发支持长连,整个即时通讯服务的实现仍避免不了对长连的开发和管理,并且需要接受和处理消息,导致流程仍较为复杂,而这恰恰有悖于云开发作为高效率、轻量级解决方案的理念。 由此,云开发的实时推送服务应运而生,它将即时通讯服务所需的能力与云开发独有的优势串联起来,让开发者可以更便捷地使用并快速实现需求。 [图片] 实时数据推送有哪些能力? 能力概述 实时数据推送是云开发数据库新增的服务,通过这项服务,小程序端可实时监听数据库变更,即它支持根据开发者给定的查询语句进行监听,每当查询语句的结果发生变化时,小程序端就会收到包含更新内容的推送,并对实时数据变化做出响应。 总体来说,使用云开发的实时数据推送能力相比起自建服务可以享受以下便利,从而使其更专注于业务逻辑的设计: 原生能力,开箱即用 无需管理长连 无需编写服务端代码 无需搭建和管理基础设施 自动收到更新推送 丰富的应用场景 实时数据推送的应用场景十分丰富。 在即时通信方面,实时数据推送支持小程序直播聊天室、弹幕等以及小游戏的区服聊天、房间聊天、私信等功能的实现。 在状态同步方面,小程序可以使用实时数据推送来保持应用最新状态的同步,以信息流为例,可以支持实时提示有新的文章、评论、点赞,从而达到更好的用户体验;对小游戏来说,可以支持使用状态同步的模型开发的小游戏,比如棋牌类小游戏。 而在实时协作方面,实时数据推送可以为在线共享文档、项目管理协作工具等提供支持。 [图片] 简单易用的API 实时数据推送提供简洁易用的API,调用方便,并且可以完整描述整个维度的数据变化,以便开发者对具体业务逻辑做出响应。 [图片] 自动处理异常 SDK在异常时会尽可能自动恢复状态,并且此恢复为开发者无感知,开发者仅需处理 SDK 无法自动恢复的错误。具体来说: 实时数据推送在断网、网络切换、NAT 地址刷新等情况时均能自动检测异常和恢复连接,并且在更新事件推送失败或丢失时有机制保障会成功拉取,而在更新事件乱序时有机制保障开发者收到的是顺序事件。 [图片] 云开发新能力矩阵 云调用:云函数免鉴权调用微信服务端开放接口,获取微信开放数据,接收微信服务端消息推送。 HTTP API:小程序外访问云开发资源。 数据库聚合:分组查询、统计查询、流水线批处理。 控制台数据库高级查询:控制台中批量数据库增删查改。 云开发Network面板:小程序Network面板支持展示云开发请求。 实时数据推送
2019-08-28 - 数据库没有提供原子操作或事务接口,这类需求如何实现?
数据库 没有提供原子操作(findAndModify)或者事务接口.这类需求应该如何实现? 我要创建多个字段组合的唯一索引?应该如何实现?
2018-09-30 - “分享监听”能力调整
近期我们收到了很多用户对小程序/小游戏中分享功能的投诉:在某些小程序/小游戏中,分享并非是用户主动自发的行为,而是受到了某类利益的诱惑,或是被迫分享。这样的内容充斥在群里、小程序里,对用户造成了骚扰。 分享功能,旨在帮助用户更流畅地与好友分享内容和服务,应是用户自发的行为。在原来的分享接口中,用户发起分享动作之后,可以通过 [代码]success[代码] 、[代码]fail[代码]、[代码]complete[代码]等回调来判断用户是否完成了最后的分享动作。通过这个能力,开发者可以将产品交互在分享这个能力上做得比较自然和顺畅。现在为鼓励用户自发分享喜爱的内容,减少“强制分享至不同群”等滥用分享能力,破坏用户体验的行为,在我们权衡了分享功能带来的利弊后,分享功能将进行以下调整: 10月10日起新提交发布的版本,不再支持分享回调参数 [代码]success[代码] 、[代码]fail[代码] 、[代码]complete[代码],即用户从小程序/小游戏中分享消息给好友时,开发者将无法获知用户是否分享完成,也无法在分享后立即获得分享成功后的回调参数[代码]shareTicket[代码]。该调整可以在基础库 2.3.0及以上版本体验。 此次调整可能影响到三种分享功能的用法。 第一种:判断用户是否分享成功,进而给予用户奖励。 例如:小程序提示用户“分享到5个群,可以获得一张20元的优惠券”。 这类诱导用户分享的行为是我们平台所不倡导的,后续将没有办法实现。 第二种:分享完成后变更当前的页面状态 例如:赠送礼品场景下,用户点击“赠送”按钮,将礼品分享出去,分享成功后,界面展示“等待领取”。 这类场景,我们建议可以适当调整交互方案。例如在分享后继续保留“赠送”按钮,但在页面上提示用户一个礼品只能被一人领取,重复赠送无效。 第三种:通过用户分享之后的 [代码]shareTicket[代码] 获取群唯一标识 [代码]openGId[代码] ,以显示对应群的相关信息。 例如:通过分享小程序到某个群里,可以查看该群内成员的排行榜。 此次调整后,用户分享完成后无法立刻显示该群的排行榜信息,但仍可在用户从群消息点击进入小程序时显示该群的排行榜信息。 10月10日起新提交发布的版本将会受到此调整的影响。 需要各位开发者注意,10月10日起新提交发布的版本将会受到此策略的影响,请及时调整分享相关能力,考虑兼容上述调整带来的影响。 调整策略在基础库 2.3.0 及以上版本生效,该基础库版本对应微信客户端6.7.2版本。另外,考虑到兼容性等问题,在基础库版本 2.3.0 以下的环境中不受此策略影响,小程序/小游戏可继续获取分享回调事件。
2018-09-13 - 设置withShareTicke后,群内长按小程序卡片弹出菜单的「转发」按钮丢失
微信群内长按小程序卡片弹出的菜单,在设置wx.showShareMenu({withShareTicket: true}) 后菜单「转发」按钮会丢失 设置withShareTicket= false 后转发按钮就又显示出来了,但是又不能获取openGID 这是bug吗?我们需要同时使用获取 openGID能力 和 长按「转发」按钮,请问有什么实现方法吗? 问题详细描述: 1. 开启转发分享格式,分享参数设置withShareTicket为true,在群聊中卡片含有“转发”按钮 [图片] 2. 关闭转发分享格式,分享参数设置withShareTicket为false,在群聊中卡片没有“转发”按钮 [图片] 3. 能否提供withShareTicket为true,同时群聊中卡片依旧含有“转发”按钮的解决方案
2019-04-20 - 如何使用数据库聚合match过滤$.and
我需要在云函数中查询数据库,聚合计算一个人的某月1-31号的消费金额: [代码]let queryFeeSum = await db[代码][代码] [代码][代码].collection([代码][代码]'lunch'[代码][代码])[代码][代码] [代码][代码].aggregate()[代码][代码] [代码][代码].match({[代码][代码] [代码][代码]eno: eno,[代码][代码] [代码][代码]date: $.and([$.gte([[代码][代码]'$date'[代码][代码], dateNumRange.begin]), $.lte([[代码][代码]'$date'[代码][代码], dateNumRange.end])])[代码][代码] [代码][代码]})[代码][代码] [代码][代码].group({[代码][代码] [代码][代码]_id: [代码][代码]null[代码][代码],[代码][代码] [代码][代码]fee: $.sum([代码][代码]'$goodsPrice'[代码][代码])[代码][代码] [代码][代码]})[代码][代码] [代码][代码].end()[代码]date是数值型:它的值是8位整数,如20190701、20190728 上面的 $.and 语句按文档中的写法,聚合这个功能也是官方开发出来不久,找不到相关帮助文档。 运行报错,查看日志提示: {"errorCode":1,"errorMessage":"user code exception caught","stackTrace":"errCode: -502001 database request fail | errMsg: [FailedOperation] (BadValue) unknown operator: $and; "} 请问一下,为什么提示操作失败,无效的值、未知的操作器$and。
2019-07-28 - 云开发 where使用or和正表达式;无法获取到数据
- 当前 Bug 的表现(可附上截图) - 预期表现 - 复现路径 - 提供一个最简复现 Demo 在云开发 where使用or和正表达式;无法获取到数据; 无法获取到数据的代码: 图1是是没加.get() ; [图片][图片] 数据库里是有数据的,不加or是可以获取到数据的,但我想判断两个字段;请问下除了_.or还有其他操作不?
2019-02-17 - # 使用小程序云开发API更新数组中的单个数组元素
使用小程序云开发API更新数组中的单个数组元素 看了看mongoDB的更新数据方式,找到了解决办法,解决方法如下,亲测可用: 第一种方法:使用位置操作符$ [代码]代码,条件更新写在云函数中 [代码] [图片] [代码]test_api集合原始数据如下 [代码] [图片] [代码]在云函数中执行1中的代码,数组users中id为1001的用户添加了一个新的属性test [代码] [图片] [代码]原理分析 [代码] where条件是查找数组中id属性为1001的用户 update中的使用’users.$.test’: ‘test’ 注意里面的$符号,在mongoDB中,这个符号叫做位置操作符,代表数组的下标,如下引自《mongoDB实战》 [图片] 第二种方法:直接使用数组下标 云函数代码 [图片] test_api集合原始数据如下 [图片] 代码执行后 [图片] 相对于第一种方法,这种方法更加简单,只不过users.1.test这种写法有点颠覆js和java中的属性书写规则,让人感觉怪怪的,在mongoDB中,也支持点数字这种写法。 一个可能的疑惑 可不可以写作’users[1].test’:‘test’,测试结果如下: [图片] [图片] 可以看到’user[1]'无法被识别为数组的第二个元素,而是作为了属性名新增了一个属性,结论:必须写成”点数字“不能写成“中括号” 结论: 经过测试,使用这两种种方法可以更新数组中的一个元素。 方法一适合在不知道数组元素下标的情况下根据查询条件更新元素; 方法二适合在知道数组元素下标的情况下更新元素; 当然也存在既知道元素下标也可以通过属性查到的情况,想用哪个就看心情了-.- 但是暂未找到查询返回数组中的一个元素的方法,再探索探索吧 ——。——
2019-03-06 - 云开发数据库如何满足“或”关系查询
以下是开发者文档里的原话: 如果需要[代码]或[代码]关系,可使用 [代码][command.or]((reference-client-api/database/command.or))[代码] 但是这一行命令怎么用啊? 以下是我自己的“与”关系查询的代码 [代码]cloud.collection([代码][代码]'123'[代码][代码]).where({[代码][代码] [代码][代码]phone:phone,[代码][代码] [代码][代码]num:num[代码][代码] [代码][代码]}).get({[代码][代码] [代码][代码]success:[代码][代码]function[代码][代码](res){[代码][代码] [代码][代码]console.log(res)[代码][代码] [代码][代码]}[代码] [代码] })[代码]
2019-07-30 - 小程序使用async/await 来处理异步
小程序使用async/await 来处理异步 regeneratorRuntime https://github.com/facebook/regenerator/blob/master/packages/regenerator-runtime/runtime.js 详细看代码片段 https://developers.weixin.qq.com/s/FlIPCOmw7P3c //引入编译模块 const regeneratorRuntime =require("../libs/regeneratorRuntime.js") const promisify = require('../libs/promisify.js'); //微信 API,转成返回 Promise 的接口 云开发API的有Promise 风格 不需要再转了 const getUserInfo= promisify(wx.getUserInfo); const login = promisify(wx.login); wx.cloud.init(); Page({ data: { }, onLoad: async function () { console.log(this) const user = await getUserInfo(); console.log("onLoad user",user) const code = await login(); console.log("onLoad code",code); const res = await wx.cloud.database().collection('todos').where({ _openid: 'xxx' }).get(); console.log("onLoad res", res) }, onShow: async function(){ const user = await getUserInfo(); console.log("onshow", user) } })
2018-11-10