小程序开发之快速实现运营需求

作为一枚前端,我想在我们的日常中,除了不断的积累各种语言框架外,我们更多的时候是给产品、业务提供切实、可行的解决方案,并最大程度上简化我们的后期维护工作。 本文以小程序端的两个场景为例,简述下我们在解决运营类数据的思路和方案。欢迎拍砖。 场景一:京东有礼小程序首页,动态实时更新页面数据     京东有礼小程序的首页,是为用户呈现的礼品卡列表。我们的需求是可以动态、实时更新礼品卡列表,比如春节期间推出一批拜年的卡面,而元宵节时更换为猜灯谜的卡面,平日再更换一批其他的卡面。这里我们称这些被动态实时更新的数据为运营类数据。 这其实是一个很简单的问题,即需求方在后台维护这些运营数据 => 后台提供数据接口 => 前端调用并渲染,就可以了。不过,当时后端没有维护“运营数据”的系统,在一周内完成系统并提供数据接口的方案基本被 pass 掉了。 当时适逢小程序推出 web-view 的解决方案,而在PC 和 M 端,需求方有通过运营活动平台搭建的活动链接,如果能够直接使用现有的活动链接,似乎也可以解决问题。不过 web-view 对业务域名做了限制,而我们搭建的活动页涉及到的域名、登录、领券等功能,未知风险不可控,一周内也未必能搞定,也放弃。 有趣的是,我们在考虑web-view方案的时候,发现运营活动平台可以提供数据接口!!活脱脱一个“配置系统”呀。很快我们确定了方案:在现有活动页的基础上,新增列表的数据结构,读取配置接口,渲染数据。 数据区域划分如下: 数据结构如下,数据结构如下,其中首焦、楼层通过groupName区分,首焦、楼层数据即是每个list的内容:

这样一来,从需求提出到实现,我们用了不到一天的时间。后来需求迭代更新时,增加了一个首焦图,和春节红包抽奖活动,我们在此基础上增加字段,只需在源码基础上增加一条判断和一次循环,就可以搞定需求,非常快捷,满足了产品的快速迭代,减少了前端的工作量,基本没有动用后端资源。 场景二:京东图书首页的多场景个性化实现。     京东图书小程序,承载着京东实体书,活跃在众多公众号的首页。比如我们的公众号首页,可以快速链接到京东图书的小程序。那么需求来了,我们每个公众号的受众群体存在着差异性,那我们怎么给用户提供精准的数据以便用户快速获取所需图书呢? 我们的方案就是为不同的公众号实现自己定制的京东图书小程序的首页,如下两张图中,分别是不同的公众号对应的不同京东图书的首页的活动页面,实现了多场景个性化的定制。 公众号一: 公众号二: 在收到该需求时,我们已经实现了通过 web-view 接入 H5 的方式,运营页面内容已经更加灵活。那如何实现这种差异性的展示呢? 有了场景一的启发,我们很快决定,借助活动平台,根据公众号的 appId 配置不同的 H5 url 链接。当数据约定完毕后,我们只需要在活动页根据数据,及当前小程序的 appId 进行匹配,待匹配成功后,将现在的 web-view 的 url 链接更新即可。 不过,我们在实现过程中也遇到了小程序的一些问题,即小程序只能获取特定场景下公众号的 appId,如下表所示: 以下是我们处理本次需求的流程图,其中也解决了小程序只能获取特定场景下公众号的 appId 的问题。 […]

Tree Shaking 与 package.json 文件中的 module 字段

本文来和大家聊聊 pkg.module 字段的功能以及使用场景。 在谈 pkg.module 之前,让我们先来了解一个和它有着紧密关系的概念 —— Tree Shaking。 什么是 Tree Shaking? 让我们通过两个小例子来了解。 假设我们有以下两个文件:

app.js 文件通过 import 引入了 math.js 中的 add1 方法。 我们通过 webpack 命令打包:

在生成的 app.bundle.js 文件中我们可以看到以下内容: 这里我们可以看到虽然我们只用到了 math.js 文件中的 add1 方法,但是在最终生成的 bundle 文件中却包含了 add1 和 add2 两个方法。这是为什么呢? 这是因为在 CommonJS 规范(math.js 文件的模块格式即为 CommonJS)中,模块只能通过 exports 对象向外暴露属性。所有要暴露的方法、变量等都只能作为 exports 对象的一个属性出现。 由于在 JavaScript 中访问对象的属性是在是太灵活了,例如: 所以打包工具并不知道我们代码中最终会用到模块中的哪些方法。为了安全起见,整个模块的代码都被包含在了最终生成的 […]

【译】Google出品 – 利用 Webpack 做 web 性能优化

原文 https://developers.google.com/web/fundamentals/performance/webpack/ 作者 Addy Osmani,Ivan Akulov Instroduction 介绍 作者 Addy Osmani 现代 Web 应用经常用到bunding tool来创建生产环境的打包文件(例如脚本、样式等),打包文件是需要优化并压缩最小化,同时能够被让用户更快地下载到。在这篇文章中,我们将会利用webpack来贯穿说明如何优化网站资源。这样可以帮助用户更快地加载你的应用同时获得更好的体验。 webpack 目前是最流行的打包工具之一,深入地利用它的特点去优化代码,将脚本拆分成重要和非重要部分,还有剔除无用的代码能够保证你的应用维持最小的带宽和进程消耗。 Note: 我们创建了一个练习的应用来演示下面这些优化的描述。尽力抽更多的时间来练习这些 tips webpack-training-project 让我们从现代 web 应用中最耗费资源之一的 Javascript 开始。 减小前端体积 利用长时缓存 监控并分析应用 总结 Decrease Front-end Size 减少前端体积 作者 Ivan Akulov 当你正在优化一个应用时,首要事情就是尽可能地将它体积的减小。下面就是利用 webpack 如何做。 Enable minification 启用最小化 最小化是通过去除多余空格、缩短变量名等方式压缩代码。例如:

React 也是类似 – 开发模式下 build 带有一些警告:

这些检查和警告通常在生产环境下是不必要的,但是他们仍然保留在代码中并且会增加库的体积。通过配置 […]

webpack 4.0.0-beta.0 新特性介绍

近年来前端技术如雨后春笋般蓬勃发展,我们也在这个潮流下不断地学习、成长。前端技术的不断发展,给我们提供了许多的便利。例如:JSX的出现为我们提供了一个清晰、直观的方式来描述组件树,LESS/SASS的出现提高了我们书写css的能力,AMD/CommonJS/ES6 的出现为我们模块化开发提供了便利。然而,我们需要使用其它工具将这些工具转化成原生语言以运行在浏览器上。为了能够更好的将这些不同的资源整合到一起,我们就需要一个打包工具,webpack就是这个需求下的产物。 webpack 可以看做是模块打包机。它做的事情是:分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。目前,webpack 总共发布了三个稳定版本。从17年八月底开始,经历了长达五个月的开发周期,webpack 团队通过增加大量新特性、bug修复、问题改善并于近期发布了 webpack 4.0.0 的 beta 版本。如果你对 webpack 感兴趣,下面我们就来学习一下 webpack 4.0.0-beta.0 的新特性。 P.S. 以下所有代码演示代码都是基于 webpack 4.0.0-beta.0。 1、安装webpack v4.0.0-beta.0 如果你使用yarn:

如果你使用npm:

2、webpack 4.0.0.beta.0 新特性介绍 下面是一些你肯定会感兴趣的新特性。如果阅读完本章后还觉得不过瘾,你可以再这查看完整的changelog。 本章将从以下几部分来介绍 webpack 4.0.0-beta.0。 2.1 环境 webpack 运行环境升级。已经不支持 Node.js 4 版本。源码升级到更高的 ECMAScript 版本。 根据 webpack package.json 配置中显示 Node.js 最低支持版本:”node”: “>=6.11.5” 2.2 模块 webpack 模块类型及 .mjs 的支持: […]

【译】如何构建React组件?

原文:https://reallifeprogramming.com/how-to-structure-components-in-react-54fc43e71546 编程是一项非常复杂的工程,尤其要编写干净整洁的代码更为困难。我们需要考虑很多问题—变量命名、函数作用域、异常处理、安全保障、性能监控等等。在编程中,变量命名唯一还是一件比较困难的事情,我倾向于编写松散耦合且高度聚合的组件。如果从面向对象或者函数式编程的角度来说,也会遇到同样的问题。构建体系是我认为最难的事情,因为它将影响到整个项目。想要成为能熟练设计软件架构的人,需要经过多年磨砺和积累。(也许没有人能完全掌握它— 在如此快速发展的行业中,总有人走在前面,也总有一个方法可以提高软件设计)。 我非常喜欢使用React,因为我觉得它最大优点就是足够简单。在简单和容易之间还是存在区别的,我的意思是React也很简单。当然你需要些时间来了解它,当你掌握其核心内容后,其他的事都是水到渠成的了。下文将介绍比较难的部分。 耦合&内聚 这些指标(耦合&内聚)或多或少的给我们改变编程习惯带了挑战。它们经常被运用在类形式的面向对象编程中。我们也将参考并且运用同样的规则在编写React组件上。 耦合指元素之间的相互连接和依赖关系。如果你改变一个元素需要同步的更新另外一个元素,我们称此为紧密耦合。而松散耦合指的是改变一个元素时,并不需要改变另外一个元素。举个例子,显示银行转账金额功能。如果展示金额依赖于汇率计算,那么内部转换结构更改时,展示的代码也会被更新。如果我们设计基于一个元素接口的,松散耦合的系统,这样元素的改变并不会影响视图层展示。很明显,松散耦合的组件更易于管理和控制。 内聚则是组件是否只为一件事情负责。这个指标是依循单一原则和unix原则:专注一件事情并且做好这件事。如果账户余额格式化展示需要计算相关汇率和检查是否有查阅历史权限,那么这个包含很多功能职责,而这些功能并不相互依赖。也许,权限处理和汇率应该是不同的组件。另一方面,如果有多个组件,一个用于整数部分,一个用于小数部分,另外一个用于货币展示,程序员想展示余额,他们则需要找到所有组件进行组装。其中的挑战则是创造高度内聚的组件。 构建组件 创建组件有很多种方法。 我们希望在合理程度下组件是可以被重用的 。我们也希望构建的小组件可以被用在更大的组件中。理想情况下,我们想构建松散耦合和高度聚合的组件,这样我们的系统更有利于管理和扩展。在React组件中props 类似函数中的参数,它们也可以看做是无状态功能的组件。我们需要思考在组件中如何定义props和组件如何被重用。 接下来,我们以费用管理系统为背景,分析费用详细的格式,来介绍如果构建组件:

根据模型,会有以下几种对费用格式的程序建模方式: 无props 传递一个expense对象 传递必要的属性 传递所有属性的map 传递一个格式化的子对象 下面分别讨论使用上述传递方式的优缺点。不过需要时刻关注使用以上任何方式是要看使用场景和依赖系统的。这也是我们所做的,建立适当的抽象场景。 无props 这是最简单的解决办法,往往就是构建一个写静态数据的组件。

不传递props,就不会给我们带来任何灵活性,而且组件也只能用于单一的场景。在费用明细的例子中,我们可以看到,最初组件是需要接受一些props。不过在某些场景下,没有任何props也是一个好的解决方式。首先,我们可以使用一些组件,其props的内容是一些不会轻易更改的内容,比如:商标,logo或者公司信息等。

编写尽可能小的组件使得系统更加容易维护。保持信息只保存在一处而且只需要在一处进行修改。不要在多处写重复的代码。 传递expense对象 在费用明细确定情况下,我们需要给组件传递数据。首先,我们需要传递一个expense对象。

传递费用对象给费用明细的组件是非常有意义的。费用明细的格式是高度一致的,它显示费用的数据。无论什么时候需要改变格式,这是唯一可以修改的地方。改变费用明细的格式也不会对费用对象自身带来什么副作用。 这个组件是和费用对象紧密耦合,这是一个坏的事情吗?当然不是,但是我们必须意识到这是如何影响我们系统的。 传递一个对象作为props,费用明细的组件将会依赖费用内部结构。当我们改变费用的内部结构时候,我们将需要更改费用明细组件。当然,我们只需要在一处进行修改。 这样的设计如何适应未来的改变呢? 如果我们增加、改变或者删除一个字段,我们将只需改变一个组件。如果我们需要增加一个其他的日历格式化展示?我们可以为日历格式化增加一个新的prop。

我们开始增加属性来使组件更加灵活。如果只有几个选项,那么一切都是很ok的。系统业务开始扩展后问题就来了,在不同的场景下我们需要维护大量的props。

增加props可以使得组件重用性更好,但你可能设计了多重功能职责的组件。这种规则也同样在函数写法中运用。可以用多个参数来创建一个函数,当参数的数目超过3个或者4个时候,意味着这个函数在做很多事情了,也许这时候应该将函数拆成更小的函数来的更加简单。 随着组件props的增加,我们将其拆分成定义明确的组件,比如:OverdueExpenseDetails, PaidExpenseDetails等。 只传递必要的属性 为了减少对象自身的内容,我们可以只传递必要的属性值。

我们分别传递属性,这样我们将一部分工作责任转移给了组件使用者。如果费用的内部结构发生变化,他将不会影响费用明细的格式化。但可能影响每个使用组件的地方,因为我们可能需要修改props。当我们以独立的属性传递props时候,一个组件将更加抽象了。 只传递需要的字段对未来设计改动是如何影响的?增加、更新或者删除字段将不会很容易。无论何时我们要增加一个字段,我们不仅仅要改变费用细节的实现,也需要改变每个使用组件的地方。另外一个方面,支持多种日历格式化几乎是现成的,我们可以传递日历作为prop,也可以传递格式化后的日历。

决定如何展示特定的字段应该在掌握在具体使用组件的人手中,这将不是费用明细组件关心的内容。 传递map或者array的属性 为了达到组件抽象化,我们可以传递一个map的属性值。

使用组件的人控制费用明细的格式化,传递给组件的对象格式则必须正确。

这个方案有很多缺陷,我们很难控制组件展示的样式,并且展示顺序也没有指定。因此,如果我们需要某种顺序的话,可以采用array代替map来解决这个问题。但是仍然还有缺陷。 […]

© 2018 JDC. All Rights Reserved.