微信小程序的发展与前景:统一开发流程,让开发更优雅

2024-06-19
来源:网络整理

2017年1月9日凌晨,张小龙及其团队正式发布微信小程序,瞬间引爆了业内人士的各种信息流。一个看似“银弹”的产品形态,受到了大家的热烈欢迎,一波开发热潮随之而来。微信近期又取得了两大突破:微信不顾苹果,开创了小程序市场(应用内搜索已经具备了“市场性质”),让小程序通过社交媒体进行传播(可通过第三方平台微信朋友圈和聊天进行传播,二维码可长按识别),同时让开发者看到了微信小程序发展的信心和前景。总之,无论是“红利”,还是“鸡血”,小程序都将成为产品布局中的重要一环。因此,在公司内部,统一规划小程序开发流程,让小程序开发变得优雅,是相当有必要的。

下面我们将以去哪儿网微信小程序为背景,详细分析去哪儿网微信小程序工程流程解决方案,同时与读者进行交流和探讨。

小程序开发的转型问题

读者肯定有疑问,为什么先讲“改造开发问题”?因为做架构和工程化的目的就是为了降低开发、测试、发布、运维等一系列环节的成本,同时解决这些环节之间的问题和痛点。所以只有明确了小程序开发过程中遇到的问题,才能更好地做架构和工程化。

那么,小程序开发亟待解决的问题是什么?问题又发生了怎样的变化?

从内测开始到半个月前,有一个数字很让人头疼——1024。这个数字代表小程序的总大小,打包后的小程序总大小不能超过 (也就是 1MB)。在这个有限的空间里,放入更多的业务逻辑是当时小程序开发遇到的最大难题。因此,压缩是当时的首要任务。

一开始公司准备把去哪儿酒店、去哪儿票务、去哪儿交通三个小程序的五条业务线合并成一个统一的小程序。我的团队接到了这个任务,在各业务线的配合下,用一周的时间完成了任务并上线,然后把剩下的体量里又挤进了另外两个业务。在当时的情况下,每压缩10KB的体量都是一件非常让人兴奋的事情。

现在不一样了,微信把小程序大小提升到了2MB,也就是,翻了一倍。根据之前1024的经验,翻倍之后,在同样的压缩逻辑下,已经足够满足大部分APP的需求了。比如把去哪儿旅游APP上主营业务的主要流程放到微信小程序里,应该没问题。

因此在压缩问题不再突出之后,如何更好地管理小程序的代码,如何隔离业务,如何分配业务资源比例,都会成为现在和未来需要解决的核心问题。当然压缩也是工程化过程中的一部分,只是优先级被降低了。

最后我来提一个问题:如上文所说,去哪儿旅行App的主要业务流程可以放到微信小程序中,但在小程序灵活的应用场景中,这真的是个好主意吗?它真的适合小程序的场景吗?这也是一个需要在工程化过程中思考和改进的问题。

小程序架构模型

小程序的架构可以用一句话概括,就是“类MVC的Web UI架构”。小程序的架构理念和微信类似,都采用了组件化和MVC模式,将UI层与其他层分离开来,同时保证了UI层的显示效率,保持了层的一致性;和微信最大的区别在于小程序使用的是微信的UI,而微信使用的是Web UI。

相比较而言,UI性能更优,但是对系统和App本身的依赖也较大,不易维护和热更新;而Web UI性能与UI有所差别,但依赖性较小,易于维护,容易实现热更新。

以上就是小程序架构的简单介绍,你可以在其他文章中了解更多。本文主要讨论小程序的流程。要实现小程序的流程,首先必须了解基于此架构的一些技术细节,例如代码结构、构建方法、调试发布方法等。

下面简要列出了一些比较重要的要点。

代码结构

首先项目中有三个公共的入口文件:

同样的,每个视图View都有一个对应的入口文件。假设这个View是一个页面,那么

其他的,无论是脚本还是Wxml模板和Wxss样式,都应该导入/使用。

施工方法

在小程序开发者工具的面板中,查看脚本会发现项目中的所有脚本无论是否加载都会被同步加载。

每个脚本都将用以下代码包装:

define("some.js", function(require, module){ // 原本的代码 });

这种加载方式和AMD类似,但是和标准AMD有些不同,缺少依赖部分的声明。

对于Wxml、Wxss文件,开发者工具会自动将其转换为后加载,其中:

预览发布方式

预览、调试、打包上传都集成在微信提供的开发者工具中,而发布试用版、上线发布则在微信小程序的管理后台完成,打包、上传、发布的逻辑均需要手动操作。

关于开发者工具的一些细节

小程序的打包、预览、上传等流程都包含在开发者工具中,所以想要更深入的了解小程序的流程机制,就必须从开发者工具入手。

简单研究了一下,发现开发者工具是基于 NW.js 构建的,这是一个基于 Node.js 构建的应用程序。对于前端来说,这是一件幸福的事情,直接通过阅读源码就能了解它的逻辑。

代码在哪里呢?在系统中,源代码比较容易找到:右键点击开发者工具“Show”(显示包内容),可以在/app.nw/下找到对应的源代码,填好的路径如下://.app///app.nw/。

源代码都是压缩脚本,可以使用js-格式化,方便阅读。

// 在源码目录的 app 目录下执行 find . -type f -name '*.js' -exec js-beautify -r -s 2 -p -f '{}' \;

一些技巧:

利用这两个技巧,读者可以优雅地阅读微信开发者工具的源代码。

工程工艺解决方案

上面我们简单了解了小程序的一些背景知识和架构模式,接下来我们从问题->解决方案的角度来讲解这个工程流程解决方案。

尺寸问题 -> 压缩工具

先说压缩这个老问题,虽然微信已经把大小限制从 1024 改成了 2048,但是总有一天代码会长到 2048 以上,大小会影响用户的加载速度,包括下载最新版本代码的速度、小程序初始化的速度,所以压缩总是有必要的。

虽然开发者工具已经支持代码压缩上传,但我认为它是一个“假压缩选项”。看了开发者工具的源码逻辑后发现,它的压缩只是为了混淆代码,并没有对Wxml、Wxss做任何压缩,同时也没有对资源路径中的无用文件进行处理。所以,关于压缩,我们还有很多事情需要做。比如:

合并和压缩

把所有脚本合并成一个文件,这样会让脚本压缩的效率更高(比如长路径没了),混淆性更强(代码的目录结构没了)。虽然脚本的打包形式类似AMD,但是使用的时候是同步加载和执行的,所以将多个脚本合并成一个并不会影响小程序的加载或者切换视图的效率,相反因为减少了IO次数,反而提升了加载效率。(暂时就这么用,用了会让代码更小,执行效率更快)但是怎么做呢?

首先,入口文件的选择:如上文代码结构中提到,小程序有统一的入口app.js,各个视图View有自己的入口page.js,将这些入口全部打包成统一的入口文件,这样就得到了一个带有脚本逻辑的.js文件。

其次需要对入口文件做一些修改,以便代码合并成一个文件之后还能正常运行。

对于视图View的入口,Page()是必须存在的,对于这样的视图注册逻辑,我们只需要通过正则表达式或者AST.__p('/path/to/page.js', , )将其改为自定义的()方法即可。

实现如下:

global.__p = pageName, index, pageOpt) => { // 其他相关逻辑 global['p' + index] = () => { Page(pageOpt || {}); }; };

这样,在视图View的入口文件中,就只需要.pXX()代码了。

对于小程序的入口点app.js,将原来的内容改为('.js')即可,因为与视图入口和代码路径无关。

最终形式如下:

模块化开发工具_小程序模块化开发方案_模块化开发流程

压缩其他文件

其他文件主要有Wxml文件、Wxss文件、JSON文件等,在前端开发中,HTML、CSS的压缩主要去掉空白符、换行符、删除注释等。

对于Wxml来说,只需要两个正则表达式就够了:

对于Wxss,直接使用就行;对于JSON,使用JSON.(JSON.(...))即可。

说到这里,有的读者可能会提出两个疑问:

关于第一个问题,左右的文件大小,大概包含10KB左右的空格和换行符,如果有上限的话,10KB还是值得珍惜的。

关于第二个问题,我觉得微信开发者工具的开发者们觉得没必要这么做。上面提到了,Wxml、Wxss 都会被转换成脚本,在这个过程中,不管 Wxml、Wxss 是否压缩,它们的转换结果都是一样的,所以压缩不压缩对最终的成品是没有影响的(最终的成品是指在服务端二次打包之后的结果,也是用户实际使用的)。但是大小是根据本地打包上传的内容来计算的,如果不做这一步压缩,微信服务端决定的大小会变大。

删除无用文件

删除无用的文件(因为已经打包为.js了,不需要其他非入口文件),删除没用的Wxss和Wxml文件,删除空目录等。

代码级优化

除了使用工具进行压缩之外,在编写代码时也有一些方法可以减少体积。这里简单说几点:

多业务并行开发 -> 模块化隔离业务代码

随着小程序诸多限制的放开,越来越多的产品想要分一杯羹,导致像去哪儿这样拥有多项业务的公司,小程序承担的业务逐渐增多,开发人员数量也急剧增加(一个小程序最多可以有 30 名开发人员)。这时候如果所有业务开发人员还在同一个项目中开发,那么项目管理起来就会非常困难。因此,以模块化的方式隔离业务代码势在必行。

至于模块的划分,显然是按照业务来划分,每个业务都是一个独立的模块,相互之间不能有依赖,可以且只能依赖共同的模块。如下图所示。

这种实现的最大好处就是可插拔性,也就是说可以随时修改或者删除任何模块,而不会影响其他服务。

上面提出了一个问题:把去哪儿旅行App上主要业务的主要流程放到微信小程序里,真的适合微信小程序吗?虽然这是纯产品的问题,但是可插拔的特性让这个问题变得很容易解决。产品同事可以很方便地根据业务模块增减业务。假设某个业务利润很少,产品同事可以立即把这个业务下线,而不会影响其他业务,用它的空间去接入新的业务或者分配给其他线上业务。

同时在业务开发的时候,只需要模块存在于本地就可以运行,减少了开发和调试的成本。

可插拔的模块化,不仅减少了模块变更的成本,也减少了用同一模块构建多个小程序的成本,增加了小程序产品的灵活性,可以根据场景构建最合适的即用型小程序。

如上图所示,使用不同的模块来构建针对不同场景的小程序。

当然这只是举例,具体情况还要看产品场景,不过个人觉得这种搭建方式更适合小程序这种灵活的场景,至于大而全的功能,还是交给小程序来做APP比较好。

那么又一个问题来了:如何有效地管理模块。

由于一个模块会被多个小程序项目引用,所以它的版本控制非常重要,否则一个微信小程序为了满足一个小程序项目的需求而修改后,在另一个小程序中可能会出现问题。

因此我们基于公司通用前端开发工具集YKit实现了插件,结合公司的代码仓库和公司的封装平台,实现了一套模块版本管理逻辑。

本地版本查询:

本地安装:

查询页面:

当然你也可以使用私有的npm仓库来实现模块管理,这个主要是为了和公司的发布系统对接。

实现模块化时要注意两点:

路由:业务模块已经隔离,路由配置在统一入口,会影响模块的插拔,所以在每个模块的根目录下,分别添加app.json配置,配置模块自身的路由,然后在工具打包的时候把各个模块的路由合并起来。

App.:业务模块有一些逻辑需要在App运行时执行,因此在每个模块的根目录下,添加各自的app.js脚本,完善相应,然后在工具打包的时候把脚本注入到相应的位置即可。

module.exports = () => { onLaunch: () => { // TODO Something } };

最后,可插拔模块化对于模块大小的计算也非常重要。

模块的 Size = 小程序总 Size - 拔去此模块时小程序的 Szie

这种计算方式非常可靠,有利于小程序给各个模块分配配额。

手动发布问题 -> 自动化发布系统集成

一般比较成熟的公司都会有自己的发布系统来进行项目发布,这样可以减少人力成本,避免人工操作的风险。但是微信小程序后端并没有提供这类操作的对应API,所以需要自己实现一套上传发布逻辑。

这个逻辑主要包含两点:小程序的封装和各种二维码扫描验证。

对于小程序的封装,可以直接从微信开发者工具中提取小程序封装的逻辑。

// wxBuild 为开发者工具资源下 app/dist/weapp/commit/build.js // wxPack 为开发者工具资源下 app/dist/weapp/commit/pack.js wxBuild({ projectpath: 'path/to/source', // 小程序项目路径 es6: true, postcss: true, minified: true }, { noCompile: true }, (err, data) => { wxPack(data, 'path/to/result.wx', (err, data) => { // data 为产出物的路径 }); });

对于扫码验证,其实就是模拟用户的行为,实现逻辑就是在发布日志的Job中打印二维码,管理员使用微信扫码即可,下面是发布日志的截图。(主要用到)。

由于篇幅有限,具体细节可以私聊。不过我觉得微信同事以后应该提供相应的上传发布接口。自动化发布其实是大部分公司的刚需。

在包发布完成后,还需要向项目干系人发送统计邮件。

总结

除了上面描述的几点之外,我们还实现了环境参数配置、项目参数注入、无嵌入点统计等通用逻辑来解决和改善开发中遇到的问题。

总结一下,去哪儿的小程序工程流程主要包括本地工具、模块仓库、发布系统关联三部分。

分享