京东技术:使用京东Taro重构小程序

35岁的程序员 2018-09-13 16:58:55 ⋅ 829 阅读

>>>>  Taro 简介

Taro 是一个基于 React 语法规范的多端统一开发框架,大家可以通过 taro.aotu.io 进一步了解。而前段时间 Taro 发布后,京东购物小程序就开始了部分页面基于 Taro 的重构工作,本文便是对商品分类页使用 Taro 进行代码重构的一些实践分享。

>>>>  混合开发模式

过去的京东购物小程序未使用任何第三方框架,而是在原生小程序模式的基础上,进行了页面/组件基类、网络请求、本地存储、页面跳转等模块的封装。

由于项目庞大(涉及 100 多个页面),把整个项目直接改造成 Taro 的开发方式肯定是不可行的,于是采用这么一种原生小程序与 Taro 相混合的开发模式,将部分旧页面使用 Taro 重构,部分新的页面则直接使用 Taro 进行开发。

这里以商品分类页为例,先来看下原京东购物小程序项目的目录结构:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

├── dist

│   ├── app.js

│   ├── app.json

│   ├── app.wxss

│   ├── assets/

│   ├── common/

│   ├── libs/

│   └── pages

│       ├── cate

│       │   ├── components/

│       │   ├── index.js

│       │   ├── index.json

│       │   ├── index.wxml

│       │   └── index.wxss

│       └── index/

├── src/

├── README.md

├── gulpfile.js

├── package.json

└── node_modules/


>>>>  1. 初始化 Taro

在项目根目录处运行命令 taro init jdwxa-taro 进行初始化,完成后会新增一个名为 jdwxa-taro 的目录,Taro 相关的源代码就写在该目录中:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

├── dist/

├── src/

└── jdwxa-taro

   ├── config

   │   ├── dev.js

   │   ├── index.js

   │   └── prod.js

   ├── node_modules/

   ├── package.json

   ├── project.config.json

   └── src

       ├── app.js
        ├── app.scss

       ├── index.html

       └── pages

           └── cate

               ├── index.js

               └── index.scss


>>>>  2. Taro 配置

独立的 Taro 项目会将包括 app.jsapp.jsonapp.wxss 及页面文件均生成在 dist/ 目录中,而混合开发模式下只需要生成单个页面,这里需要对 Taro 进行一些配置,打开并编辑 config/index.js 文件:


1

2

3

4

5

6

7

8

9

10

11

const config = {

   outputRoot: '../dist',

   weapp: {

       appOutput: false,

       npm: {

           dir: '../../dist/common',

           name: 'taro'

       }

   },

   // ...

}


如代码所示,outputRoot 字段为生成目标页面的存放路径,这里把它指向顶层(即原项目)的 dist/ 目录;weapp 部分,我们把 appOutput 设置成 false, 这样就不会生成 app.js、app.json、app.wxss 三个文件了,npm 字段则表示 Taro 运行时框架文件的存放目录,这里遵循原项目的规范,把它指定为 common/ 目录。这样 Taro 编译生成的目标文件就完美地融入进了原小程序项目。

>>>>  3. 页面开发

页面开发过程中,跟原生小程序最大的不同就是 React + JSX 的编码方式了,习惯了原生小程序的同学可能要一些适应过程,具体的编码就不细说了,这里提几点注意事项:

  • 与小程序的 setData 方法不同,Taro 用于更新页面数据的 setState 是异步的,相关代码的执行时序需要特别注意;

  • 为了方便 JSX 模板的书写,原先很长的 WXML 内容建议拆分成一些小的组件;

  • 关于旧组件的复用,无论是小程序原生组件、普通 JS 模块、样式文件或是第三方组件库,都能很好的进行引入调用,这点无需担心;

  • 目前对于 Taro 编译生成的目标代码,调试起来会有些困难,但对 SourceMap 的支持正在积极开发中。

>>>>  4. 最终效果

如今重构后的商品分类页已经在线上稳定运行有一段时间了,可以扫描下面的小程序码进行体验:

>>>>  Taro 带来的收益

>>>>  多端运行

最大的收益便是可以生成多端版本,避免重复工作、节省开发成本。以分类页为例,只需运行 npm run build:h5 便可生成 H5 版本的分类页,运行效果和小程序一致,大家可以扫描下面的二维码进行体验:

注:以上仅为 Taro 生成的示例页面,由于一些业务组件尚未完全适配两端,所以 H5 版本暂时没有正式投入使用。

>>>>  性能提升

小程序项目中遇到的性能问题,大多是频繁地调用 setData 造成的,这是由于每调用一次 setData,小程序内部都会将该部分数据在逻辑层(运行环境 JSCore)进行类似序列化的操作,将数据转换成字符串形式传递给视图层(运行环境 WebView),视图层通过反序列化拿到数据后再进行页面渲染,这个过程下来有一定性能开销。

所以开发过程中,我们建议尽量对 setData 进行合并,减少调用次数,例如:


1

2

3

this.setData({ foo: 'Strawberry' })

this.setData({ foo: 'Strawberry', bar: 'Fields' })

this.setData({ baz: 'Forever' })


以上代码调用了 3 次 setData,造成不必要的性能开销,应对其进行合并:


1

2

3

4

5

this.setData({

   foo: 'Strawberry',

   bar: 'Fields',

   baz: 'Forever',

})


而使用 Taro 之后,更新数据时调用的 setState 为异步方法,它会自动地对同一事件循环里的多次 setState 调用进行合并处理,此外还会进行数据 diff 优化,自动剔除那些未变更的数据,从而有效避免了此类性能问题。例如:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

// 初始时

this.state = {

   foo: '1967',

   bar: {

       foo: 'Strawberry',

       bar: 'Fields',

       baz: 'Forever',

   }

}


// 第一次更新

this.setState({

   bar: {

       foo: 'Norwegian',

       bar: 'Fields',

       baz: 'Forever',

   }

})


// 紧接着进行第二次更新

this.setState({

   foo: '1967',

   bar: {

       foo: 'Norwegian',

       bar: 'Wood',

       baz: 'Forever',

   }

})


以上代码虽然经过两次 setState,但只有 bar.foo 和 bar.bar 的数据更新了,此时 Taro 内部会自动对数据进行合并、并剔除重复数据,最终执行代码为:


1

2

3

4

5

// this.$scope 在小程序环境中为 page 实例

this.$scope.setData({

   'bar.foo': 'Norwegian',

   'bar.bar': 'Wood',

})


>>>>  其他收益

比起原生小程序开发,Taro 带来了许多激动人心的特性(如支持 TypeScript、NPM、丰富的 JSX 语法、更高级的 ES 特性等等),不仅提升了开发体验,对自动化测试、持续构建等也会有不小的帮助。

举个例子,京东购物小程序里封装了一个 getImg 方法,该方法接受一个图片 url 及可选的宽高作为参数,然后根据设备类型决定是否使用 webp 格式、根据当前网络环境应用适当的图片压缩率、自动处理协议头和域名转换,最后生成符合目标大小的图片 url。我们要求所有的图片都必须经过 getImg 方法处理后才能进行展示,但由于 JS 方法只能在逻辑层进行调用,处理好后再传递给 WXML 进行展示,使得很难在自动化工具中进行检测,及时发现未调用 getImg 输出图片的情况。

而使用 Taro 之后,可以直接在 JSX 模板的 Image 标签输出时对 src 调用 getImg 方法进行处理,将此种写法作为规范明确后,就很容易通过自动化工具进行检测了:


1

2

3

render () {

   return <Image src={getImg(url, 750)} />

}


So 对于现有项目来说,不需要进行整体重构,也能很好的将 Taro 集成进去。还等什么,赶紧试试吧

长按,识别二维码,加关注


---------------END----------------

后续的内容同样精彩

长按关注“IT实战联盟”哦



全部评论: 0

    我有话说:

    京东到家订单中心系统mysql到es的转化之路

    原文:https://www.toutiao.com/i6796507988602389006 京东到家订单中心系统业务中,无论是外部商家的订单生产,或是内部上下游系统的依赖,订单查询的调用量都非常

    京东技术使用JDReact程序双向转换

    JDReact是京东商城前台产品研发部推出的多端融合开发框架。

    微信程序 - iconfont 图标字体

    你还在使用图片作为程序的图标?大猪告诉大家如何在程序使用iconfont字体图标

    微信程序-Image的widthFix属性和rpm尺寸的使用

    在做微信程序的商品详情页,商品的详情是图片集合,渲染完成后发现图片加载的很不自然

    微信程序实现商品数量加减

    这是一个用微信程序原生代码实现的数量加减demo,主要是用于商品购物车或者商品详情修改数量使用

    微信程序抖音实战-首页(下)

    抖音程序首页动态数据获取

    京东技术:多数据模型数据库 | 应用实例解析

    作 者 简 介吕信,京东商城技术架构部资深架构师,拥有多年数据产品研发及架构经验。

    微信程序电商实战-入门篇

    程序开发工具有新版本更新啦!开发体验更好了,接下来一起为电商程序做一下准备前期准备工作~~

    微信程序电商实战-商品详情(上)

    先看一下今天要实现的程序商品详情页吧!

    微信程序抖音实战-首页(上)

    你也可以用微信程序编写一个抖音

    「开源资讯」BookChat v2.4 发布,通用书籍阅读微信程序

    BookChat - 面向程序员的开源书籍和文档阅读学习程序

    微信程序实战篇:程序之页面数据传递

    我们在写程序的时候经常会遇到子页面向主页面回传数据或者普通页面跳转到tabBar 页面携带数......

    微信程序:最新微信登录授权并获取openid等信息

    为优化用户体验,使用 wx.getUserInfo 接口直接弹出授权框的开发方式将逐步不再支持。从2018年4月30日开始,程序游戏的体验版、开发版调用 wx.getUserInfo 接口,将

    微信程序电商实战-购物车(上)

    好久没更新程序电商实战的文章了,是因为最近一直做整体架构调整,一些准备工作也是比较耗费时间的。在这几天将会有新版的 程序电商教程推出.......

    微信程序电商实战-首页(下)

    上一篇:微信程序电商实战-首页(上)好了,上一期我们把首页搜索、导航栏和广告轮播给做完了,那么接下来会继续

    微信程序实战篇:基于wxcharts.js绘制移动报表

    微信程序图表插件(wx-charts)是基于canvas绘制,体积巧,支持图表类型饼图、线图、柱状图 ......

    微信程序电商实战-首页(上)

    上一篇:微信程序电商实战-入门篇 嗨,大家好!经过近两周的精心准备终于开始微信程序电商实战之路喽。那么最终会做成什么样呢?好了,不啰嗦了 我们先看首页长什么样吧!   首页效果图