一些废话

沉寂了两个月,我又回来了。

跟你们猜的一样,我已经到淘系实习了一段时间了,从上一篇文章之后就放了更多的心思在工作上。上篇文章发出去之后,我去腾讯实习了一段时间,等待阿里实习生入职流程开启。

收到淘系的实习生 offer 后,我买了人生中的第一张机票,第一次坐上了飞机,来到了一个陌生的城市——杭州。干净的街道、宽敞的沥青马路,吸引了我这个来自小城市的年轻人。

博客很久没更新了,不管是个人的网站还是掘金,都很少有更新了,偶尔上掘金看看一些好文,总想更新一下,但又没找到好的题材。现在实习了一段时间后,上手了淘系的开源跨端框架——Rax,新奇又好玩,也总结了一些很基础的开发技巧,补充一下官方文档的缺漏(官方文档对于新手来讲确实不太友好)。

基础部分演示项目 Git 仓库:Rax-TODO

进阶技巧演示项目 Git 仓库:Software-Engineering(同时也是我的课程设计,欢迎大伙点个 Star

前面的部分是针对只有一点 React 基础的同学的,高端玩家请点击:进阶技巧

项目环境

  1. node >=10.3.0
  2. npm >= 6.1.0

前置知识

  1. JSX
  2. Hooks
  3. TypeScript(可选)
  4. Jest(可选)
  5. Enzyme(可选)

创建项目

初始化项目

这部分官网文档比较详细了,先看一下官网文档:快速开始

官网文档提供的方案还挺多的,可能会选择困难,我们就从最基础的 TODO 开始,使用 Rax 搭建一个 Web 项目:

npm init rax todo-list

选择项目类型

输入上面的命令之后,会使用 npx 安装 rax-cli 脚手架工具,安装完成后会弹出这样的界面:

added 106 packages from 53 contributors in 10.5s
? What's your project type? (Use arrow keys)
❯ App (Build universal application)Component (Build universal component)API (Build universal API library)Plugin (Build plugin for miniapp)

使用 上下键 移动箭头,后面的操作同理。

这里我们就直接使用默认的选项,创建一个 APP,按下回车。

选择应用运行平台

? Choose targets your project want to run? (Press <space> to select, <a> to togg
le all, <i> to invert selection)
❯◉ Web◯ Weex◯ Kraken (Flutter)◯ Alibaba MiniApp◯ WeChat MiniProgram

使用 空格键 选择,按下 字母a 可以全选,这里我们就先选择 Web,后续如果有编译为 Weex小程序 的需求可以在项目目录的 build.json 中添加。

编译为 Flutter 应用的功能目前还不稳定,且坑比较多,建议动手能力强的玩家尝试,小白就先绕道吧。

选择应用类型

? What's your application type? (Only valid in target: Web/Weex/Kraken) (Use arr
ow keys)
❯ Single-page application (SPA)Multi-page application (MPA)Create lite application (The simplest project setup)

选择 APP 的类型,是 SPA 还是 MPA,这里的选项只在 Web/Weex/Kraken(Flutter) 应用中有效。

我们选择默认的选项 SPA,不明白 SPAMPA 的区别的同学,可以移步文章:认识单页应用(SPA)与多页应用(MPA)

输入作者名字

? What's author's name? (rax): 炽翎

选择开发语言

? What type of language do you want to use? (Use arrow keys)
❯ JavaScriptTypeScript

这里我们就先选择 JavaScript,后续如果有引入 TypeScript 的需求,可以手动引入。

开启特性

? Do you want to enable these features? (Press <space> to select, <a> to toggle
all, <i> to invert selection)
❯◯ Server-side rendering (SSR) (Only valid in target: Web)◯ Aliyun Function Compute (FaaS) (Only valid in target: Web)◯ Compatibility with React

这里我们就什么都不选。

当然,如果有需要我们可以选择 Compatibility with React 配置与 React 的兼容,也可以为我们的应用开启 服务端渲染(SSR)。如果有需求开启 Serverless,也可以选择开启 功能即服务(FaaS)SSRFaaS 都只能在 Web 应用中有效。

不懂 SSRServerless 的同学请自行百度(Google)哈。

自动安装依赖

? Do you want to install dependences automatically after initialization? (Y/n)

这里就直接回车,这个选项的意思是询问是否在初始化完成后自动安装依赖。默认是 Yes,就不用我们手动进入项目文件夹执行 npm install 了。

等待依赖安装完成

To run your app:cd todo-listnpm start

当终端出现这一段文字的时候,就说明依赖安装完了,我们可以进入到项目的文件夹下,执行 npm start 跑起我们的项目。

启动项目

在执行 npm start 后,终端会显示:

Rax development server has been started:[Web] Development server at:http://localhost:3333/

这时候我们就可以在浏览器输入 Dev Server 的地址,查看我们的项目了。

开始开发

随便选择一款自己喜欢的 IDE,进入项目的文件夹,我们会看到这样的一个目录结构:

.
├── README.md                   # 项目说明
├── build.json                  # 项目构建配置
├── package.json
└── src                         # 源码目录├── app.js                  # 应用入口文件├── app.json                # 应用配置,包括路由配置,小程序 window 配置等├── public                  # (可选)静态资源目录,会拷贝内容至 build 目录├── components              # 应用的公共组件│   └── Logo                # 组件│       ├── index.css       # Logo 组件的样式文件│       └── index.jsx       # Logo 组件 JSX 源码├── document                # 页面的 HTML 模板│   └── index.jsx└── pages                   # 页面└── Home                # home 页面└── index.jsx

开发之前,我们需要了解一些 Rax 下的一些小规矩:

  • rpx:默认以 750rpx 为屏幕宽度,即 1rpx = 1/750 * 屏幕宽度
  • 样式简写:在 Rax 中,由于目前兼容性的问题,不支持 部分 样式简写,例如:在写 border 样式时,应该将各个部分分开:border-widthborder-styleborder-color。在遇到属性简写在非 Web 平台不生效的问题时,尝试将属性分开或许就能解决问题。

删掉初始页面

我们要做的第一件事是删除初试化后默认的 Home 页面中的 Logo 组件,在 src/components 文件夹下,整个删除。

删除之后,src/pages/Home/index.jsx 肯定会报错,我们先稍作修改,改成 Hello World!

// index.jsx
import { createElement } from 'rax';
import View from 'rax-view';
import Text from 'rax-text';import './index.css';export default function Home() {return (<View className="home"><Text>Hello World!</Text></View>);
}

这个时候会发现页面变成了 Hello World!,后面应该不用讲解太多,就是使用 React 应用开发的方式,开始愉快的 coding 过程。

可能你会发现,为什么在这里我们只能用 Rax 提供的 ViewText 组件?

因为为了使跨端显示效果一致,Rax 为开发者抹平了不同平台之间样式显示不一致的问题。

当然,如果你只是想用 Rax 做一个 Web 应用,那你可以使用 HTML 标签(汗)。

View 组件和 Text 组件的用法可以移步文档:基础组件-View 和 基础组件-Text

创建 Item 组件

按照 耦合度,我们应该将组件放在 src/pages/Home 文件夹下。

在这个文件夹下,我们创建一个这样的目录:

src/pages/Home
└── components                  # 组件文件夹└── ListItem                # ListItem 组件├── index.css           # CSS└── index.jsx           # JSX

首先我们应该构思一下这个 ListItem 应该暴露给父组件哪些接口:

  1. 每一项对应的 id
  2. 每一项的内容
  3. 每一项的完成状态
  4. 每一项的 onClick 事件

明确了组件应该暴露的接口之后,就可以开始写代码了:

// index.jsx
import { createElement } from 'rax';
import View from 'rax-view';
import Text from 'rax-text';import './index.css';const ListItem = (props) => {// 解构 id 完成状态 内容 onClick 事件const { id, done, content, onClick } = props;// 完成项文字样式const style = {fontSize: '64rpx',lineHeight: '96rpx',textDecoration: done && 'line-through'};return (<View className="list-item" onClick={() => onClick(id)}><View className="list-dot"></View><Text style={style}>{content}</Text></View>);
};export default ListItem;
/* index.css */
.list-item {flex-direction: row;justify-content: flex-start;align-items: center;width: 100%;height: 100rpx;
}.list-dot {width: 20rpx;height: 20rpx;margin-right: 20rpx;border-radius: 10rpx;background-color: #333;
}

创建 List 组件

还是一样,先创建文件:

src/pages/Home
└── components                  # 组件文件夹├── List                    # List 组件│   ├── index.css           # CSS│   └── index.jsx           # JSX└── ListItem                # ListItem 组件├── index.css           # CSS└── index.jsx           # JSX

创建一个 List 组件作为 ListItem 的容器管理所有的 Item,实现 添加/删除 的功能。

既然要做 添加 功能,那输入框肯定是必不可少的,在我们创建的项目里,默认是没有输入框组件的依赖的,所以我们要先安装 Rax 提供的输入框组件:

npm install rax-textinput --save

组件的用法可以转战文档:基础组件-TextInput

// index.jsx
import { createElement, useState } from 'rax';
import View from 'rax-view';
import Text from 'rax-text';
import TextInput from 'rax-textinput';import ListItem from '../ListItem';
import './index.css';const List = () => {// 初始化 itemId 每次添加新列表项就 +1const [itemId, setItemId] = useState(0);// 初始化列表const [list, setList] = useState([]);// 初始化 TextInput 内容const [inputValue, setInputValue] = useState('');// 输入框输入事件const handleUserInput = (e) => {setInputValue(e.target.value);};// 添加按钮点击事件const handleAddButtonClick = () => {// 构造列表项数据结构const item = {id: itemId,content: inputValue,done: false};// immutable 思想 生成新的引用const newList = [...list, item];setList(newList);// 清空输入框setInputValue('');// itemId ++setItemId(itemId + 1);};// 列表项点击事件const handleItemClick = (id) => {// 遍历列表 当事件未完成时标记为已完成 当事件已完成时删除const newList = list.filter((item) => {if (item.id === id) {if (item.done) {return false;} else {item.done = true;}}return true;});setList(newList);};return (<View className="list"><View className="list-input-wrapper"><TextInputclassName="list-input"value={inputValue}onInput={handleUserInput}/><View className="list-add-button" onClick={handleAddButtonClick}><Text>添加</Text></View></View><View className="list-item-wrapper">{list.map((item) => (<ListItemkey={item.id}id={item.id}content={item.content}done={item.done}onClick={handleItemClick}/>))}</View></View>);
};export default List;
.list {align-items: center;
}.list-input-wrapper {flex-direction: row;justify-content: flex-start;align-items: center;
}.list-add-button {justify-content: center;align-items: center;width: 150rpx;height: 100rpx;margin-left: 20rpx;border-radius: 10px;background-color: #dcdcdc;
}.list-input {width: 100%;height: 100rpx;line-height: 96rpx;font-size: 64rpx;border-width: 1px;border-color: #dcdcdc;
}.list-item-wrapper {width: 100%;
}

至此,组件的基本功能就完成了。

引入首页

现在我们要将组件引入首页 Home 中:

import { createElement } from 'rax';
import View from 'rax-view';import List from './components/List';
import './index.css';export default function Home() {return (<View className="home"><List /></View>);
}

现在就能看到一个能完成基本功能的 TODO 应用了。

进阶技巧

我猜,有些高玩看到我前面写的部分,肯定会说:

啊~ 你这个这么简单,不是有手就行嘛~

有一说一,确实有手就行(误)。

前面的部分只是写给不爱读官方文档或者只有一点 React 基础的同学的,从这个部分开始,会开始引入一些高级的内容。

修改路由配置

在前面创建的项目中,我们会看到项目的文件夹下有一个 app.json 文件,打开它你会看到:

{"routes": [{"path": "/","source": "pages/Home/index"}],"window": {"title": "Rax App"}
}

这个文件就是用来控制项目路由,如果后续的开发增加了更多的页面,就需要在 routes 下添加对象。path 就是你新加入的页面的访问路径(URL),source 就是你新添加的页面所在的文件目录。

修改为多页应用(MPA)

在项目文件夹下还有一个 build.json 文件,里面的内容是这样的:

{"plugins": [["build-plugin-rax-app",{"targets": ["web"]}]]
}

因为我们之前创建项目的时候,选择的是单页应用(SPA),我们想改成多页应用怎么办?
很简单:

先安装多页应用依赖:

npm install build-plugin-rax-multi-pages --save-dev

然后在 targets 所在的对象下,增加一个键 "type",值为 "mpa",像这样:

{"plugins": [["build-plugin-rax-app",{"targets": ["web"],"type": "mpa"}]]
}

重启 Dev Server 后会发现页面变成了这样:

添加跨端支持

我们在最开始创建项目的时候,并没有选择多平台,但是 Rax 作为一个跨端开发框架,不添加跨端支持怎么行,这里会给一个教程教大家添加跨端支持(当然一开始就选择好更方便)。

还是 build.json 文件,有一个 targets 数组,想要添加跨端支持,就在数组中添加对应的内容即可:

{"plugins": [["build-plugin-rax-app",{"targets": ["web", "weex", "miniapp", "wechat-miniprogram"],"type": "mpa"}]]
}

weex 对应 Weex 平台,miniappwechat-miniprogram 对应 阿里小程序微信小程序

查看 Weex 效果

我们在 build.json 中使用了上面的配置后,页面会变成这个样子:

点开 Weex Preview 后,你会发现是一堆 JavaScript 代码,那怎么预览?

有一个稍微麻烦一点的方法,就是先确定你本机在内网的 IP 地址,将 URL 中的 localhost 改成内网 IP,然后将 URL 转换为二维码(Chrome 有很多插件可以实现)。

在手机上下载 Weex Playground 然后扫描二维码,就能在手机上预览到 APP 的效果。

Weex Playground 下载地址

TypeScript 支持

在前面的项目里,我们没有引入 TypeScript,那如果想引入应该怎么办?

很简单,在官网的文档中也有讲解:项目开发- TypeScript 支持

只需要先安装 rax-typestypescript

npm install rax-types typescript --save-dev

在项目文件夹下创建 tsconfig.json 文件,使用以下配置:

{"compilerOptions": {"module": "esNext","target": "es2015","outDir": "build","jsx": "preserve","jsxFactory": "createElement","moduleResolution": "node","sourceMap": true,"alwaysStrict": true,"baseUrl": ".","paths": {"rax": ["node_modules/rax-types"]}},"include": ["./src/**/*"]
}

即可添加 TypeScript 支持。

引入自动化测试

这是一个比较大的坑,以至于让我摸索了一个上午才解决。

Rax 官方文档中并没有自动化测试相关配置的教程,以至于我只能直接在钉钉找负责 Rax 维护的师兄求助,历经千辛万苦终于将测试用例跑通。

首先,我们需要安装几个依赖,数量有点多,建议分开安装:

npm install jest --save-dev
npm install @types/jest --save-dev
npm install @babel/preset-env --save-dev
npm install babel-jest --save-dev
npm install rax-test-renderer --save-dev
npm install @babel/plugin-proposal-class-properties --save-dev
npm install @babel/plugin-proposal-decorators --save-dev
npm install @babel/plugin-proposal-export-default-from --save-dev
npm install @babel/preset-flow --save-dev
npm install @babel/preset-react --save-dev
npm install babel-plugin-transform-jsx-stylesheet --save-dev

依赖安装好之后,在项目的目录下创建 .babelrc.jsBabel 进行配置:

module.exports = function (api) {// Cache the returned value forever and don't call this function again.if (api) api.cache(true);return {presets: ['@babel/preset-flow',['@babel/preset-env',{loose: true}],['@babel/preset-react',{pragma: 'createElement'}]],plugins: ['@babel/plugin-proposal-export-default-from',['@babel/plugin-proposal-class-properties', { loose: false }],'babel-plugin-transform-jsx-stylesheet',['@babel/plugin-proposal-decorators', { legacy: true }]],ignore: ['build', 'coverage', 'node_modules']};
};

配置好之后,Jest 还是无法跑通的,要在 package.json 中添加启动脚本:

{"scripts": {"build": "build-scripts build","start": "build-scripts start","lint": "eslint --ext .js --ext .jsx ./",// 添加 jest 启动脚本"test": "jest"}
}

同时,还要对 Jest 进行配置:

{"jest": {"collectCoverage": true,"moduleNameMapper": {"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js","\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"}}
}

配置添加完成之后,在项目的目录下创建一个文件夹:

.
└── __mocks__├── fileMock.js          # 静态资源处理└── styleMock.js         # 样式处理

分别在两个文件中加入添加代码:

// fileMock.js
module.exports = 'test-file-stub';
// styleMock.js
module.exports = {};

配置这个部分的目的是让 Jest 处理样式和静态资源时到 mock 的文件夹下找。因为在测试的时候,测试脚本并不会真的去访问引入的静态资源,遇到需要引用静态资源的地方就引导到 __mocks__ 文件夹下查找,就不会因为找不到资源而报错。配置来源于 Jest 官网处理静态文件。

一切配置完成后,就可以在一个需要做测试的组件下创建 __test__ 文件夹并将测试脚本放在文件夹下了,或者你也可以直接使用 xxx.test.jsx 为文件命名,这些文件都会被 Jest 识别为测试脚本。

除了 Jest,Rax 团队还为 Rax 提供了 Enzyme 适配器,示例项目:raxjs/enzyme-adapter-rax,提供了 Enzyme 的使用示例。

总结

得益于淘系强大的技术实力,Rax 的相关生态相对比较完善。同时,性能也非常强大,这里我就不过多介绍了。

Rax 在小程序上的性能甚至优于市面上其他小程序框架:Rax ——完美融合编译时与运行时的双引擎小程序框架。

其他的一些介绍 Rax 的文章可以移步官网的博客。

文章的最后,推荐一下自己的公众号:Hello FE,是我和跟我一起实习的小伙伴们一起运营的,会定期分享一些干货。

同时,关注公众号还有前端书籍大全一份赠送,欢迎大家关注,也欢迎大家进群交流:

写给跨端玩家:支撑淘宝上亿日活的跨端框架—— Rax 的入门教程(附 TODO Demo)相关推荐

  1. 性能第三讲:百万级QPS,支撑淘宝双11需要哪些技术

    性能第三讲:百万级QPS,支撑淘宝双11需要哪些技术 又到一年双11,相信大部分同学都曾经有这个疑问:支撑起淘宝双11这么大的流量,需要用到哪些核心技术?性能优化系列的第二篇我想跟大家探讨一下这个话题 ...

  2. python3淘宝商品目录_Python3中级玩家:淘宝天猫商品搜索爬虫自动化工具(第一篇)...

    一.前言 大家好,今天我要来讲讲一个比较实用的爬虫工具,抓取淘宝的关键字商品信息,即是: 输入关键字,按照价格等排序,抓取列出的商品信息以及下载图片,并且支持导出为Excel. 如果如下: 看完下面的 ...

  3. Python3中级玩家:淘宝天猫商品搜索爬虫自动化工具(第三篇)

    查看Github 欢迎回看第一篇和第二篇. Python3中级玩家:Python3中级玩家:淘宝天猫商品搜索爬虫自动化工具(第一篇 Python3中级玩家:Python3中级玩家:淘宝天猫商品搜索爬虫 ...

  4. 跨境电商和淘宝哪个好

    随着互联网的不断发展,每个人都不仅仅是将电子商务区域放在中国.由于我们可以通过互联网开展业务并将产品销售给国人,因此我们可以通过互联网向外国人销售商品.经济全球化的影响可能在今天其他国家的经济中存在问 ...

  5. 揭秘淘宝286亿海量图片存储与处理架构,互联网营销

    [IT168 专稿]8月27日下午,在IT168系统架构师大会存储与系统架构分论坛上,淘宝网技术委员会主席,淘宝网核心工程师章文嵩向我们详细介绍了淘宝网图片处理与存储系统的架构.章文嵩博士的演讲日程包 ...

  6. 怎么在手机上取消双重认证_用手机在淘宝上怎么开网店?流程步骤详解

       这是一篇关于"用手机在淘宝上怎么开网店?流程步骤详解"的文章: 开网店因为门槛低.收益大,成为众多年轻人创业的首选.很多新手朋友们都想开一家属于自己的网店,但是苦于没有经验, ...

  7. 手机淘宝:亿级用户APP的快速运维交付实践

    作者简介: 倪生华 淘宝网  资深技术专家 花名玄黎,12年加入淘宝无线事业部,经历了手淘从几十万日活到现在亿级日活的过程,一直负责手淘端研发运维等工程效率相关的工作,团队负责开发的支撑体系,很好的解 ...

  8. 你刚才淘宝上买衣服---具体分析技术工艺(淘宝页面显示处理的页面)

    声明:文章和保存之前看到在计算机网络中的文件,有没有办法找到原文地址.在该声明.为了上网project教师致敬. 你找到新的一年.所以,我想给你女朋友买一件毛衣,你打开www.taobao.com.这 ...

  9. python爬虫淘宝手机_【Python3 爬虫】14_爬取淘宝上的手机图片

    现在我们想要使用爬虫爬取淘宝上的手机图片,那么该如何爬取呢?该做些什么准备工作呢? 首先,我们需要分析网页,先看看网页有哪些规律 我们可以看到左侧是主题市场,将鼠标移动到[女装/男装/内衣]这一栏目, ...

  10. 我用维权失败经历告诉你,在淘宝上买到假货只能忍气吞声

    淘宝上的假货问题由来与久了,马云一直喊着要打击假货,可是呢,淘宝是怎么打击假货的,我用我的亲身经历告诉你,当你在淘宝上买到假货,很多时候,你只能忍气吞声. 2018年7月10日,我在淘宝店" ...

最新文章

  1. china-pub计算机图书最新一周排行榜
  2. jpgraph中文使用手册之文本和字体控制教程
  3. iar升级芯片库_顶10个GPU!阿里巴巴重磅发布含光800芯片
  4. CNN人脸关键点检测
  5. 外键查询_传统关系型数据库查询性能提高思路
  6. SAP CRM WebClient UI和CRM Fiori Account里显示Opportunity逻辑
  7. 用python实现远程复制 (scp + expect )
  8. wordpress房产信息网_Realia v3.1.2 wordpress房地产模板 租房网站模板
  9. 【fedora12】vlc-2.0.0编译
  10. Java集合之LinkedHashMap源码分析
  11. 企业安全建设之自动化代码扫描(代码审计)
  12. 判断相等_C语言判断字符串是否为回文
  13. HDOJ水题集合11:桶排序, 折半搜索
  14. caffe 使用笔记
  15. 安装matpower
  16. 合并报表和汇总报表之如何合并报表
  17. Tensorflow 2.0 医学图像分割(肝脏CT图像分割)
  18. c语言求数组中绝对值最小值,整数数组中两两之差绝对值最小的值
  19. ESP8266的Web配网以及强制门户的实现(连接wifi自动打开网页)
  20. 危化品从业人员资格证怎么考?

热门文章

  1. S3C2440驱动开发(一)
  2. Hugo Travis
  3. TDR 及其测试原理
  4. 论Python常见的内置模块
  5. 汇编语言,两个数字的想加_8085微处理器中的汇编语言程序将两个16位数字相乘...
  6. 东财《领导科学X》综合作业
  7. 删除字符串中多余的空格 美团校园招聘模拟测试题
  8. 鸿蒙os自定义主题,通过鸿蒙自定义属性,来创造一个可以为所欲为的自定义标题组件...
  9. python + selenium:怎么实现控制左右滑动开关
  10. SUDOKU-数独游戏