loadrunner可以做loadrunner自动化测试试吗

用react的ReactCSSTransitionGroup插件实现简单的弹幕动画-爱编程
用react的ReactCSSTransitionGroup插件实现简单的弹幕动画
1,开始的思路
公司想做直播方面的项目,并想加入弹幕的功能,直播的页面已经作为一个组件放在了用react+redux写好的一个网站项目上。所以技术老大让我研究下如何用react实现弹幕的功能。下面我就简单说下我的react弹幕折腾之路。一开始其实是两手空空,作为一个php的初级开发人员,我对前端技术掌握的很少,远不到熟练的程度。所以,我得从头学习如何用js+css实现弹幕,然后再将弹幕移植到react项目上去,这是我一开始的思路。
2,中间的折腾
我百度了下“js 弹幕”,发现大部分都是用jquery的animate()函数和css配合来实现的,比如这个,有些则是jquery配合css的animation来实现。我学习了下用jquery的animate()函数配合css来实现弹幕的方法,然后就尝试将这个方法引入到react项目中去。但我在这个地方费了好多时间都没有进展,最终我放弃了将jquery引入react的想法。技术老大提醒我,可以找找react动画的解决方法。于是百度、google,在sgemenfault和知乎上有不少问答,给出了三个解决方向:1,用react官方提供的动画插件(ReactCSSTransitionGroup)可以实现基本和简单的动画2,引入专业的第三方的动画库3,用第三方的react动画插件第1种方法,简单、直接,需要对react的动画插件有所了解,第2种方法需要非常熟悉第三方库的用法,像我这种前端的半吊子还是算了:),第3种方法,我也没考虑。总之,我选择了第1种。我大致看了下react官方的tutorial和docs,然后就开始动手了。
3,初现曙光
按照react官网上给的,我写出了我的第1个react动画(没有用到redux),
实现的基本功能就是在一个输入框中输入文字,然后enter发送文字,文字从一个div的右侧走到左侧,最后消失。先把代码贴出来:
点击我查看代码
1 import React from 'react';
2 import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
4 class App ponent {
constructor(props) {
super(props);
this.state = {
value: '',
this.returnWord = this.returnWord.bind(this);
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
componentDidMount() {
// 监听回车事件
document.onkeydown = (event) =& {
if (event.keyCode === 13) {
document.getElementById('sendBullet').click = null;
handleSubmit(event) {
event.preventDefault();
this.setState({ value: '' });
handleChange(event) {
this.setState({ value: event.target.value });
returnWord() {
const word = this.myTextI
const index = this.state.
const top = this.state.
if (word === this.state.value) {
this.setState({ word, index: index + 1 });
if (top &= 435) {
this.setState({ top: top + 75 });
} else if (top & 435) {
this.setState({ top: 0 });
render() {
const item = (
className="bullet"
key={this.state.index}
style={{ top: `${this.state.top}px`, color: `#${((1 && 24) * Math.random() | 0).toString(16)}` }}
{this.state.word}
&form onSubmit={this.handleSubmit}&
type="text"
(ref) =& {
if (ref !== null && ref.value.trim() !== '') {
this.myTextInput = ref.
value={this.state.value}
onChange={this.handleChange}
&button id="sendBullet" onClick={this.returnWord}&发送弹幕&/button&
position: 'relative',
width: '1200px',
height: '500px',
margin: 'auto',
background: 'rgba(255, 0, 0, 0.1)',
overflow: 'hidden',
&ReactCSSTransitionGroup
transitionName={{
enter: 'bullet-enter',
transitionEnterTimeout={5000}
transitionLeave={false}
&/ReactCSSTransitionGroup&
<span style="color: #0
<span style="color: #1 }
<span style="color: #2
<span style="color: #3 export default A
可以看到我这里引入了ReactCSSTransitionGroup,它是react提供的一个动画插件,可以实现基本、简单的css动画和渐变功能,它需要单独安装,具体的安装方法可以百度或google。
下面来说下比较关键的地方:
1,代码第51~59行,定义要动的弹幕文字组件。 render方法中定义了一个item,这个item就是弹幕中要动起来的弹幕文字组件。要注意:item中的key属性是必须要给定的,哪怕你只有单独的1个item也要指定key,
这样React才能决定哪个item该如何动作,这也是react官方文档中所强调的。我定义了自增的index作为state来管理item的key,这样每个item都有一个唯一的key。
2,代码第87~95行,ReactCSSTransitionGroup配置。需要注意的是,一定要将要操纵的动画元素完全包含到ReactCSSTransitionGroup中去,然后就是根据动画需要设置要做的动画过程。我只要入场动画(有字幕出现时就开始动画)就可以了。
所以设置入场动画时间transitionEnterTimeout={5000}。另外,出场动画不需要可以设置为false:&transitionLeave={false},不能忽略这个属性,不然会报错。transitionName中可以设置动画过程的css样式名称,设置规则可参考官网。
3,下面是我的入场动画css样式,也是要注意的第3点
1 .bullet {
opacity: 0.01;
5 .bullet-enter {
opacity: 1;
position: absolute;
left: 1100px;
<span style="color: #
<span style="color: # .bullet-enter.bullet-enter-active {
<span style="color: #
opacity: .5;
<span style="color: #
position: absolute;
<span style="color: #
left: -100px;
<span style="color: #
transition: all 5000ms ease-in;
<span style="color: # }
.bullet-enter对应入场动画开始时的item样式,.bullet-enter.bullet-enter-active对应入场动画结束时的item样式,可以看到用到了css的transition,这也是实现动画的关键。
以上3点比较关键,其余的问题就是如何产生item的问题,这个暂时先不写了。
4,将弹幕作为一个组件整合到react+redux项目中
其实只要实现了弹幕动画,整合也就容易了,下面先把弹幕组件的代码贴出来。
1 import React, { Component, PropTypes } from 'react';
2 import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
4 class BulletScreen extends Component {
render() {
const item = (
className="bullet"
<span style="color: #
key={this.props.index}
<span style="color: #
<span style="color: #
top: `${this.props.top}vh`,
<span style="color: #
color: 'rgb(255, 255, 255)',
<span style="color: #
whiteSpace: 'nowrap',
<span style="color: #
fontSize: '3vh',
<span style="color: #
<span style="color: #
<span style="color: #
{this.props.word}
<span style="color: #
<span style="color: #
<span style="color: #
<span style="color: #
<span style="color: #
<span style="color: #
id="bullt-screen"
<span style="color: #
<span style="color: #
position: 'relative',
<span style="color: #
width: 'auto',
<span style="color: #
height: '46vh',
<span style="color: #
overflow: 'hidden',
<span style="color: #
margin: '-50vh auto auto auto',
<span style="color: #
background: 'rgba(0, 255, 0, 0.01)',
<span style="color: #
<span style="color: #
<span style="color: #
&ReactCSSTransitionGroup
<span style="color: #
transitionName={{
<span style="color: #
enter: 'bullet-enter',
<span style="color: #
<span style="color: #
transitionEnterTimeout={5000}
<span style="color: #
transitionLeave={false}
<span style="color: #
<span style="color: #
<span style="color: #
&/ReactCSSTransitionGroup&
<span style="color: #
<span style="color: #
<span style="color: #
<span style="color: # }
<span style="color: #
<span style="color: # BulletScreen.propTypes = {
<span style="color: #
word: PropTypes.string,
<span style="color: #
index: PropTypes.number,
<span style="color: #
top: PropTypes.number,
<span style="color: # };
<span style="color: #
<span style="color: # export default BulletS
到时在视频播放的页面中引入这个组件就可以了。
这个项目目前是我司的开源项目,感兴趣的朋友可以去github上看下:
参考资料:*[HTML+CSS+jQuery实现弹幕技术](/article/a948d65179ade90a2ccd2e77.html)**[Animation Add-Ons](https://facebook.github.io/react/docs/animation.html#reactcsstransitiongroup)*
版权所有 爱编程 (C) Copyright 2012. . All Rights Reserved.
闽ICP备号-3
微信扫一扫关注爱编程,每天为您推送一篇经典技术文章。CSS Modules 详解及 React 中实践
CSS Modules 详解及 React 中实践
CSS 是前端领域中进化最慢的一块。由于 ES 的快速普及和 Babel/Webpack 等工具的迅猛发展,CSS 被远远甩在了后面,逐渐成为大型项目工程化的痛点。也变成了前端走向彻底模块化前必须解决的难题。
CSS 模块化的解决方案有很多,但主要有两类。一类是彻底抛弃 CSS,使用 JS 或 JSON 来写样式。Radium,jsxstyle,react-style 属于这一类。优点是能给 CSS 提供 JS 同样强大的模块化能力;缺点是不能利用成熟的 CSS 预处理器(或后处理器) Sass/Less/PostCSS,:hover 和 :active 伪类处理起来复杂。另一类是依旧使用 CSS,但使用 JS 来管理样式依赖,代表是 CSS Modules。CSS Modules 能最大化地结合现有 CSS 生态和
JS 模块化能力,API 简洁到几乎零学习成本。发布时依旧编译出单独的 JS 和 CSS。它并不依赖于 React,只要你使用 Webpack,可以在 Vue/Angular/jQuery 中使用。是我认为目前最好的 CSS 模块化解决方案。近期在项目中大量使用,下面具体分享下实践中的细节和想法。
CSS 模块化遇到了哪些问题?
CSS 模块化重要的是要解决好两个问题:CSS 样式的导入和导出。灵活按需导入以便复用代码;导出时要能够隐藏内部作用域,以免造成全局污染。Sass/Less/PostCSS 等前仆后继试图解决 CSS 编程能力弱的问题,结果它们做的也确实优秀,但这并没有解决模块化最重要的问题。Facebook 工程师 Vjeux 首先抛出了 React 开发中遇到的一系列 CSS 相关问题。加上我个人的看法,总结如下:
1. 全局污染
CSS 使用全局选择器机制来设置样式,优点是方便重写样式。缺点是所有的样式都是全局生效,样式可能被错误覆盖,因此产生了非常丑陋的 !important,甚至 inline !important 和复杂的[选择器权重计数表](Selectors Level 3),提高犯错概率和使用成本。Web Components 标准中的 Shadow DOM 能彻底解决这个问题,但它的做法有点极端,样式彻底局部化,造成外部无法重写样式,损失了灵活性。
2. 命名混乱
由于全局污染的问题,多人协同开发时为了避免样式冲突,选择器越来越复杂,容易形成不同的命名风&#26684;,很难统一。样式变多后,命名将更加混乱。
3. 依赖管理不彻底
组件应该相互独立,引入一个组件时,应该只引入它所需要的 CSS 样式。但现在的做法是除了要引入 JS,还要再引入它的 CSS,而且 Saas/Less 很难实现对每个组件都编译出单独的 CSS,引入所有模块的 CSS 又造成浪费。JS 的模块化已经非常成熟,如果能让 JS 来管理 CSS 依赖是很好的解决办法。Webpack 的 css-loader 提供了这种能力。
4. 无法共享变量
复杂组件要使用 JS 和 CSS 来共同处理样式,就会造成有些变量在 JS 和 CSS 中冗余,Sass/PostCSS/CSS 等都不提供跨 JS 和 CSS 共享变量这种能力。
5. 代码压缩不彻底
由于移动端网络的不确定性,现在对 CSS 压缩已经到了变态的程度。很多压缩工具为了节省一个字节会把 ’16px’ 转成 ’1pc’。但对非常长的 class 名却无能为力,力没有用到刀刃上。
上面的问题如果只凭 CSS 自身是无法解决的,如果是通过 JS 来管理 CSS 就很好解决,因此 Vjuex 给出的解决方案是完全的 CSS in JS,但这相当于完全抛弃 CSS,在 JS 中以 Object 语法来写 CSS,估计刚看到的小伙伴都受惊了。直到出现了 CSS Modules。
CSS Modules 模块化方案
CSS Modules 内部通过 [ICSS](css-modules/icss · GitHub) 来解决样式导入和导出这两个问题。分别对应 :import 和 :export 两个新增的伪类。
:import(&path/to/dep.css&)
&&localAlias:
keyFromDep;
&&exportedKey:
exportedValue;
但直接使用这两个关键字编程太麻烦,实际项目中很少会直接使用它们,我们需要的是用 JS 来管理 CSS 的能力。结合 Webpack 的 css-loader 后,就可以在 CSS 中定义样式,在 JS 中导入。
启用 CSS Modules
// webpack.config.js
css?modules&localIdentName=[name]__[local]-[hash:base64:5]
加上 modules 即为启用,localIdentName 是设置生成样式的命名规则。
/* components/Button.css */
normal 相关的所有样式 */
disabled 相关的所有样式 */
// components/Button.js
styles from
'./Button.css';
console.log(styles);
buttonElem.outerHTML
= `&button
class=${styles.normal}&Submit&/button&`
生成的 HTML 是
&button class=&button--normal-abc53&&Submit&/button&
注意到 button--normal-abc53 是 CSS Modules 按照 localIdentName 自动生成的 class 名。其中的 abc53 是按照给定算法生成的序列码。经过这样混淆处理后,class 名基本就是唯一的,大大降低了项目中样式覆盖的几率。同时在生产环境下修改规则,生成更短的 class 名,可以提高 CSS 的压缩率。
上例中 console 打印的结果是:
'button--normal-abc53',
&&disabled:
'button--disabled-def886',
CSS Modules 对 CSS 中的 class 名都做了处理,使用对象来保存原 class 和混淆后 class 的对应关系。
<p style="margin-top:0 margin-bottom:0 padding-top:0p
感谢关注 Ithao123CSS频道,是专门为互联网人打造的学习交流平台,全面满足互联网人工作与学习需求,更多互联网资讯尽在 IThao123!
Laravel是一套简洁、优雅的PHP Web开发框架(PHP Web Framework)。它可以让你从面条一样杂乱的代码中解脱出来;它可以帮你构建一个完美的网络APP,而且每行代码都可以简洁、富于表达力。
Hadoop是一个由Apache基金会所开发的分布式系统基础架构。
用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。
Hadoop实现了一个分布式文件系统(Hadoop Distributed File System),简称HDFS。HDFS有高容错性的特点,并且设计用来部署在低廉的(low-cost)硬件上;而且它提供高吞吐量(high throughput)来访问应用程序的数据,适合那些有着超大数据集(large data set)的应用程序。HDFS放宽了(relax)POSIX的要求,可以以流的形式访问(streaming access)文件系统中的数据。
Hadoop的框架最核心的设计就是:HDFS和MapReduce。HDFS为海量的数据提供了存储,则MapReduce为海量的数据提供了计算。
产品设计是互联网产品经理的核心能力,一个好的产品经理一定在产品设计方面有扎实的功底,本专题将从互联网产品设计的几个方面谈谈产品设计
随着国内互联网的发展,产品经理岗位需求大幅增加,在国内,从事产品工作的大部分岗位为产品经理,其实现实中,很多从事产品工作的岗位是不能称为产品经理,主要原因是对产品经理的职责不明确,那产品经理的职责有哪些,本专题将详细介绍产品经理的主要职责
IThao123周刊基于ES6,使用React、Webpack、Babel构建模块化JavaScript应用
发表于 19:42|
来源medium|
作者Tim Ermilov
摘要:如何基于ES6,使用React构建一个新JavaScript应用?如何将ES6代码发布到NPM上?又如何在后续项目中使用这些代码?……本文通过具体的编程实践,一一揭晓。
【编者按】本文为《》的简译内容,讲述了作者基于ES6,使用React、Webpack、Babel构建模块化JavaScript应用的编程心得。如果你想用React构建一个新的JavaScript应用,而且你还想实践ES6语法中的新特性,此外,你甚至想创建一些可重用组件并发布到NPM上,那么你究竟应该怎样实现这些需求?你如何将ES6代码发布到NPM,又如何在后续的项目中使用这些代码?我花了一些时间解决上面这些问题,现在我愿意与你们分享我习得的新知识。
如果你真的不希望阅读所有的细节,只想看看代码最终的效果——可以直接阅读最后一部分。
我们先来搞清楚我们到底想要得到什么,应该如何去实现。
我们的主要目标是:基于ES6,使用我们自定义的React组件创建一个React应用。其中最棘手的部分是自定义React组件。以下是实现这些目标的需求列表:
自定义组件应该使用ES6编写;
自定义组件应该完全自给自足(使用方法足够简单:安装,导入,渲染);
自定义组件应该提供自身所需的样式(参考第2条,自给自足);
自定义组件应该通过安装(因为);
最后——所有自定义组件应该有单元测试和代码覆盖率报告;
加分项——自定义组件不应该相互依赖,但是应该能够相互影响。
此外,我们需要一些很棒的调试工具,例如:代码检查、源码映射(因为代码需要编译,所以这是调试的必要工具)。
现在我们已了解所有需求,可以开始寻找满足这些需求的方法。所以,首先需要选定我们将使用的工具集和相关库。
我们要基于ES6开发应用,目前的,所以我们需要将ES6编译为ES5。同时我们希望通过NPM管理自定义组件,需要选用一个兼容CommonJS的工具集。
目前有两种流行的可用选择——和。二者都满足我们的大部分需求,考虑到我们的项目需要使用样式文件,而Webpack对非JavaScript文件(例如:样式文件、图片、字体文件)非常友好,所以最终我们将选用Webpack。
Webpack已经能够满足大部分需求,我们将在此基础上加入,帮助我们完成更多任务(例如:单元测试、代码覆盖率检测、静态资源伺服)。
现在我们已经知道如何使用Webpack和Gulp.js来构建代码,可是如何才能满足我们的第一个需求——使用ES6?我们可以使用转译器,帮助我们将ES6代码转译为主流浏览器支持的ES5代码。目前流行的转译器有:、、(勉强算是),我们将选用Babel.js,它有一个更好的生态系统(插件、扩展等)。如果你尚不知晓其为何物,请记住这是一个非常棒的项目,我推荐你阅读它们的文档。最棒的是,Babel.js不仅支持ES6语法,它还可以编译JSX,所以我们可以在编译步骤彻底弃用标准React
JSX编译器了!
如果你只想使用Babel.js,我推荐你阅读它们的。Axel Rauschmayer博士曾经撰写,也值得一读,如果你对JavaScript感兴趣,我也极力推荐订阅他的博客。
现在我们选定了ES6转译器,让我们讨论一下自给自足的问题。如果我们开发纯React组件——那么可以轻松地让它们独立工作(可重用),你甚至可以参考学习编码方式。但如果我们需要在组件内提供默认的自身样式,需要怎样实现呢?
当然,我们可以选择“纯JS”方法向我们的JSX文件加入内联样式,就像这样:
const render = function() {
const defaultStyle = {
color: &#039;red&#039;,
&div style={defaultStyle}&
I have inline styles
JSX内联样式
这个方法存在一个问题,我们几乎无法通过父应用控制这个组件的样式。而且,如果我们需要加载图片或自定义字体文件,这个方法就会失效。所以,是否有更好的方法呢?
Webpack可以帮你解决这个问题!幸运的是,Webpack 加载器可以加载许多类型的文件。其背后的思想非常简单——在加载过程中动态地对载入文件进行可插拔转换。从本质上来说,加载器为我们处理各种文件。我们将选用一个特殊的来将我们的ES6代码转译为ES5代码。
但最酷的是,加载器可以处理任何文件。所以,如果我们想加载样式——我们只需要添加style-loader!最终,我决定使用LESS,它稍微复杂一些——我将创建如下的加载链:
首先,使用处理*.less文件,将其转换为CSS;
然后,使用将编译好的css传递给下一个步骤;
最后,使用将最终的样式引入到生成的代码中。
通过这个加载链,我们可以使用LESS编写组件的样式,下面这段代码演示了这种组件的入口点:
import &#039;./style/style.less&#039;;
import Component from &#039;./src/component&#039;;
export default C
借助Webpack将样式引入到JavaScript中&
正如你所见,加载样式像导入文件一样简单。的确,由less-loader、css-loader以及style-loader构成的加载链必须要在我们的Webpack配置文件中提前配置好(参考下一节的第一个示例)。
现在我们可以从相互独立的组件中加载样式,但是CSS默认使用全局变量,这意味着如果两个组件中使用了相同的类名,其中一个将被改写,我们如何回避这个问题呢?
我能想出来的最简单的方法是:在HTML标签和样式文件中,使用组件名称作为最外层元素的类名,人为地创建组件的作用域。就像这样:
.component-name {
const render = function() {
&div className="component-name"&
&span&I have scoped styles&/span&
组件样式的人为作用域
如此一来,所有组件将拥有唯一命名,当他们被封装进同一个应用中时不再产生冲突,能够很好地协同工作。而且,当我们想在应用层重新定义组件样式时,可以使用组件命名作为类名直接改写。
接着,你如何将ES6模块发布到NPM上呢?事实上,你无须这样做。至少目前还不需要。你可以直接向外发布你的原生代码,但这通常是一个糟糕的想法,当你后续想将代码引入到主应用或其它组件中时会感到非常痛苦。当然,你可以通知Webpack(同样也可以通知Browserify)来编译需要用到的代码。但是,如果这样做,你不得不使用Webpack(以及浏览器)来运行各种测试,我通常在命令行中运行测试,因为这样运行速度更快,并且便于后续的自动化测试封装(也就是我们常说的持续集成)。
目前我在项目中应用的最好方法是——同时传送原生ES6代码和编译后的ES5代码,实现这个方法非常简单:
向你的package.json文件添加构建指令;
在预发布阶段运行构建指令;
使用编译后的ES5代码作为主文件;
通过package.json文件的额外字段暴露ES6代码。
它看起来是这样的:
"name": "es6-component",
"version": "1.0.0",
"description": "My awesome ES6 component",
"main": "es5/component.js",
"es6": "index.js",
"scripts": {
"build": "gulp build",
"prepublish": "npm run build"
将ES6模块发布到NPM上的package.json
这种方法有两个优点:
在所有ES5代码中,我们可以轻松地引入或require()这个模块,它能够正常工作!
如果我们出于某些原因需要用到模块的源代码,我们同样可以轻松地通知Webpack使用“ES6”字段来加载或引入ES6代码。
单元测试及代码覆盖率
你必须佩服的是,在Babel中配置单元测试和代码覆盖率检测非常简单(得益于Babel伟大的生态系统,正如我之前提到的那样)。
--compilers: jsx?:babel/register
我一直使用作为测试工具,所以我会讲解如何将其应用到项目中。支持ES6代码非常简单,你只需在执行mocha指令时添加一个编译flag(或添加到mocha配置文件)就可以通知mocha使用babel预编译器:
完成这一步之后,就可以在ES6代码中运行测试了,当然你也可以使用ES6来编写测试文件!
现在要处理最棘手的部分——我们有了React组件,我们想使用mocha完成测试,却又不想在浏览器中运行测试(可以运行一个,但是它非常繁重),我们应该如何去做呢?
答案就是——基于用JavaScript实现了WHATWG的DOM和HTML标准。它比Phantom更轻量,并且满足几乎所有我们测试React所需的功能。
以下是为React配置jsdom环境的测试helper文件的示例:
import localStorage from &#039;localStorage&#039;;
import {jsdom} from &#039;jsdom&#039;;
// init jsdom
global.document = jsdom();
global.window = global.document.defaultV
global.navigator = global.window.
// local storage polyfill
global.window.localStorage = localS
global.localStorage = localS
// import react after dom
const React = require(&#039;react/addons&#039;);
before(function() {
// expose react and testutils
this.React = R
this.TestUtils = React.addons.TestU
beforeEach(function() {
// create container
this.container = global.window.document.createElement(&#039;div&#039;);
afterEach(function(done) {
// clean jsdom
this.React.unmountComponentAtNode(this.container);
// timeout
setTimeout(done);
在命令行中运行React测试的jsdom环境
注意我使用import声明引入jsdom和localStorage,但却使用require()加载React,这是因为import声明会被提前,我们需要确保在jsdom初始化之后加载React。如果你尝试在DOM就绪前加载React,那么直到你与组件进行交互时它才会开始工作,然后你得到的往往是各种各样的错误,因为React假设这属于非浏览器环境,不使用DOM相关特性。
现在我们有了正确运行的mocha测试,我们也可以轻松获取Istanbul覆盖率检测工具并正常执行:
istanbul cover _mocha -- -R spec
接下来实现我们的加分需求——无相互依赖的交互。这一部分内容来自于我正从事的一个项目,如果你不太感兴趣,大可跳过这一节。
当然,如果你依然感兴趣,那让我们一起讨论一下实现这个目标的方法。
我们需要使松耦合的系统中各部分相互交流,在完美的实现中它们甚至无须知道相互的存在,只须响应请求。这样的任务听起来是否非常熟悉?
你或许曾经听说过微服务这个概念,你甚至可能已经使用过它们。如果你对微服务所知甚少,我推荐你看一下。
如果你懒得看(或者想稍后看)他的演讲,那么简单了解一下微服务的思想:许多小规模、独立的,通过通用接口相互交流的离散服务实体。通用接口可以有多种形式,其中包括:消息总线、表征状态传输(REST,又称表征状态转移)、远程过程调用(RPC)等。
因为我们做的是客户端JavaScript应用,在接口问题上我们的确没有那么多的选择。幸运的是,有一个非常赞的库,它专门处理类似这样的情况——postal.js。
即使它仍然基于回调函数实现底层功能,但是它将消息分为channel和topic两类,提供了非常大的弹性。
通过示例演示所有的这一切是如何工作的,十分容易。
想象一下我们有一个App需要一些认证和URL签名功能来获取数据。通过postal我们可以定义一个认证channel,它将会监听那些签名请求,并通过不同的topic返回已签名的URL,就像这样:
import postal from &#039;postal&#039;;
// get postal channel for current component
const channel = postal.channel("auth");
const signUrl = () =& {
// signing code here
// listen to sign requests
const signAction = channel.subscribe("url.sign", function(url, envelope) {
const signedUrl = signUrl(url);
channel.publish("url.signed", signedUrl);
import postal from &#039;postal&#039;;
// get postal channels
const channel = postal.channel("query");
const authChannel = postal.channel("auth");
// define data fetching stuff
const requestUrl = &#039;http://...&#039;;
const getData = () =& {
// data-fetching logic here
// listen for data requests
const allItemsAction = channel.subscribe("items.all", () =& {
// wait for signed url
authChannel.subscribe("url.signed", (signedUrl) =& {
const data = getData(signedUrl);
channel.publish("items.data", data);
authChannel.publish("url.sign", requestUrl);
在组件中使用postal.js的channels进行通信
这段代码可以很好地工作,因为我们无须了解任何有关其它组件的信息——我们只须了解使用哪个channel和topic。一方面,这意味着管理这些内容的负担落到开发者身上;另一方面,在这种实现的基础上,我们可以轻松地更换认证组件——今天我们使用OAuth,明天我们使用自定义token系统,以后使用其它功能,我们只须更换一下认证组件就可以支持新的工作流。
代码检查和源码映射(Source Map)
最后,我们再为项目加入一些小改进:支持代码检查,启用源码映射。
不支持ES6和React代码,我们将使用代替它。eslint支持JavaScript和JSX的语法,并可以通过插件进行扩展。
将之于Webpack结合非常容易,你只须在你的Webpack配置文件中添加几行代码。下面这个代码片段展示了所需的配置:
var path = require(&#039;path&#039;);
module.exports = {
devtool: &#039;inline-source-map&#039;,
debug: true,
// your other props here
preLoaders: [
test: /\.jsx?$/,
exclude: /node_modules/,
loader: &#039;eslint-loader&#039;
// other modules options here
注意node_modules文件夹不包括在检查的范围内,所以程序只会检查你实际的组件代码。
Webpack将在编译过程结束后把所有的检查结果输出到控制台。
Turris.js——汇总一切
结合以上提及的所有内容,我创造了Turris.js——它包含一系列helper包,还有一个yeoman生成器,你可以用它轻松地为ES6 React应用和独立组件搭建脚手架。
如果你对生成器不感兴趣,只想看看应用和独立组件的示例代码,你可以在它们各自的Github仓库中找到它们:还有。
创建新应用
我尝试使创建新应用尽可能地简单,你可以这样创建一个新应用:
确保你已安装最新的io.js和NPM;
从NPM安装yeoman和turris-generator:
npm install -g yo generator-turris
创建一个新文件夹存放你的App,进入这个文件夹,执行turris生成器:
在回答一系列问题后,yeoman将为你完成所有工作;
执行“npm start”,启动你的新App;
访问http://localhost:8080,打开你最喜欢的编辑器并将应用改为你喜欢的样子。
除了为基础应用搭建脚手架外,Turris生成器还提供了三个helper生成器:
组件生成器——将在你的App中生成一个新的组件,可以非常便捷地生成你将不会重用的小组件;
页面生成器——将生成一个新页面并将它插入到React路由中,这里没有什么奇妙之处,它只是一个帮助你节省时间的子生成器;
Docker生成器——将生成一个dockfile,其中包含所有运行App所需的文件。
更多有关使用方法、子生成器、项目结构以及其它内容信息,可以在中找到。
创建一个独立组件
创建一个组件并不难,你可以这样做(需求与主生成器相同):
通过NPM安装turris-generator-component:
$ npm install -g generator-turris-component
为你的组件创建一个新文件夹,进入这个文件夹,执行turris组件生成器:
在回答一系列问题后,yeoman将为你完成所有工作;
执行“npm start”,在调试模式下启动你的组件;
访问http://localhost:8080,打开你最喜欢的编辑器并将应用改为你喜欢的样子。
更多有关使用方法、项目结构以及其它内容信息,可以在中找到。
希望你已在这篇文章中找到有用的内容,或许你甚至已尝试我编写的生成器。即使你没有这样做——也请帮助我宣传一下!如果你已经尝试过——我非常乐意听取任何反馈意见,处理你们可能遇到的问题。当然,也很欢迎大家提交Pull Requests。(译者:刘振涛,审校:陈秋歌)
关于作者:Tim Ermilov,从事移动和Web开发工作。
英文原文:欢迎加入CSDN前端交流群:,进行前端技术交流。&
推荐阅读相关主题:
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章

我要回帖

更多关于 java做接口自动化测试 的文章

 

随机推荐