我猜想大多數(shù)程序員都使用框架來(lái)開發(fā)應(yīng)用程序,框架有助于程序員構(gòu)建復(fù)雜的應(yīng)用程序并節(jié)省時(shí)間。每天,程序員都可以看到大量的好壞框架的列表。本文,將分享一位程序員對(duì)于使用框架創(chuàng)建應(yīng)用的例子,以及他為什么從React轉(zhuǎn)換到Cycle.js。
React是很受歡迎的前端框架,它有一個(gè)很好的社區(qū)。但它可能不如大家說(shuō)的那么好,大多數(shù)人開始使用React,而不考慮建立一個(gè)網(wǎng)絡(luò)應(yīng)用程序的更好方式。這種反思讓我嘗試了Cycle.js,這個(gè)新的框架變得越來(lái)越流行。在這篇文章中,我想解釋Cycle.js的工作原理以及為什么我認(rèn)為它比React更好。
什么是Cycle.js?
Cycle.js是一個(gè)功能和響應(yīng)式的JavaScript框架。它將應(yīng)用程序抽象為純函數(shù)main()。在函數(shù)編程中,函數(shù)應(yīng)該只有輸入和輸出,沒(méi)有任何副操作。在Cycle.js的main()函數(shù)中,輸入是來(lái)自外部世界的讀取效應(yīng)(source),而輸出(sink)是對(duì)外部世界的寫入效應(yīng)。使用驅(qū)動(dòng)程序來(lái)管理副操作。驅(qū)動(dòng)程序是處理DOM效果,HTTP效果和網(wǎng)絡(luò)套接字等的插件。
Cycle.js幫助建立用戶界面,測(cè)試它們并編寫可重用代碼。每個(gè)組件只是一個(gè)可以獨(dú)立運(yùn)行的純函數(shù)。
核心API只有一個(gè)功能,run:
它有兩個(gè)參數(shù),app和drivers。app主要是純功能,drivers是需要處理副操作的插件。
Cycle.js將附加功能分成較小的模塊。 它們是:
-
@cycle/dom-使用DOM的驅(qū)動(dòng)程序集合; 它具有基于snabdomvirtual DOM庫(kù)的DOM驅(qū)動(dòng)程序和HTML驅(qū)動(dòng)程序
-
@cycle/history - History API的驅(qū)動(dòng)程序
-
@cycle/http - 基于超級(jí)用戶的HTTP請(qǐng)求的驅(qū)動(dòng)程序
-
@cycle/isolation - 具有作用域數(shù)據(jù)流組件的功能
-
@cycle/jsonp - 通過(guò)JSONP進(jìn)行HTTP請(qǐng)求的驅(qū)動(dòng)程序
-
@cycle/most-run - 大部分應(yīng)用程序的run功能
-
@cycle/run - 使用xstream制作的應(yīng)用程序的run功能
-
@cycle/rxjs-run - 使用rxjs制作的應(yīng)用程序的run功能
Cycle.js編程實(shí)例
我們來(lái)看一些Cycle.js代碼吧!我們將創(chuàng)建一個(gè)簡(jiǎn)單的應(yīng)用程序,以演示它的工作原理。 我認(rèn)為這個(gè)例子應(yīng)該是一個(gè)很好的計(jì)數(shù)器應(yīng)用程序的理想選擇。我們將看到如何處理DOM事件并在Cycle.js中重新渲染DOM。
創(chuàng)建兩個(gè)文件index.html和main.js. 整個(gè)邏輯是index.html只提供main.js文件,還要?jiǎng)?chuàng)建一個(gè)新的package.json文件,因此運(yùn)行:
npm init -y
接下來(lái),安裝主要依賴項(xiàng):
npm install @cycle/dom @cycle/run xstream --save
這將安裝@cycle/dom,@ cycle/xstream-run和xstream。我們也需要babel,browserify和mkdirp,所以讓我們安裝它們:
npm install babel-cli babel-preset-es2015 babel-register babelify browserify mkdirp --save-dev
與Babel一起工作,請(qǐng)使用此內(nèi)容創(chuàng)建一個(gè).babelrc文件:
{
在package.json中添加腳本來(lái)運(yùn)行應(yīng)用程序:
"scripts": {
對(duì)于運(yùn)行Cycle.js應(yīng)用程序,使用npm開始。
就這樣設(shè)置完成,我們可以開始編寫一些代碼。我們?cè)趇ndex.html中添加一些HTML代碼:
< !DOCTYPE html><html lang="en"><head>
我們創(chuàng)建了一個(gè)id為主的div。Cycle.js將連接到該div并在其中呈現(xiàn)整個(gè)應(yīng)用程序。我們還包括thedist / main.js文件,這是將從main.js創(chuàng)建的被折疊和捆綁的JS文件。
現(xiàn)在是編寫一些Cycle.js代碼的時(shí)候了。 打開main.js文件并導(dǎo)入需要的所有依賴項(xiàng):
import xs from 'xstream'; import { run } from '@cycle/run'; import { div, button, p, makeDOMDriver } from '@cycle/dom';
包括xstream,run,makeDOMDriver和可幫助我們使用Virtual DOM(div,button和p)的函數(shù)。
我們來(lái)寫我們的main函數(shù)。它應(yīng)該是這樣的:
function main(sources) {
這是我們的main函數(shù)。它得到source并返回sinks。Source是DOM流,sink是虛擬DOM。
const action$ = xs.merge(
在這里,我們將兩個(gè)流合并成一個(gè)單獨(dú)的流,稱為action $(后綴含有$的流的變量名稱的約定)。一個(gè)是decrement點(diǎn)擊,另一個(gè)是 increment按鈕。我們將這兩個(gè)事件分別映射到數(shù)字-1和+1。在合并結(jié)束時(shí),action $ stream應(yīng)該如下所示:
----(-1)-----(+1)------(-1)------(-1)------
下一個(gè)流是count$。它是這樣創(chuàng)建的:
const count$ = action$.fold((acc, x) => acc + x, 0);
Fold功能非常適合此目的。它接受兩個(gè)參數(shù),accumulate和seed。seed首先被排出,直到事件發(fā)生。下一個(gè)事件與基于accumulate函數(shù)的seed 組合。它基本上是reduce()的流。
我們的count$數(shù)據(jù)流收到0作為起始值,然后在count$的每個(gè)新值上,我們將其與count $ stream中的當(dāng)前值相加。
最后,要使整個(gè)循環(huán)工作,我們需要調(diào)用main以下的run函數(shù)。
最后一點(diǎn)是創(chuàng)建虛擬DOM。 這是代碼:
const vdom$ = count$.map(count =>
我們正在映射count $ stream中的數(shù)據(jù),并返回流中每個(gè)項(xiàng)目的虛擬DOM。 虛擬DOM包含一個(gè)主要的div包裝器,兩個(gè)按鈕和一個(gè)段落。 如你所見(jiàn),Cycle.js正在使用JavaScript函數(shù)來(lái)處理DOM,但也可以實(shí)現(xiàn)JSX。
在主函數(shù)結(jié)束時(shí),返回Virtual DOM:
return {
我們正在傳遞我們的main函數(shù)和一個(gè)DOM驅(qū)動(dòng)程序,它連接到具有ID主體的div,并從該div獲取事件流。 我們正在關(guān)閉我們的圈子,并使完美的Cycle.js應(yīng)用程序。
這是它運(yùn)行時(shí):
為什么我從React切換到Cycle.js?
現(xiàn)在你了解了Reactive編程的基本概念,并在Cycle.js中看到了一個(gè)簡(jiǎn)單的例子,讓我們來(lái)談一談為什么我會(huì)將它用于下一個(gè)項(xiàng)目。
設(shè)計(jì)網(wǎng)絡(luò)應(yīng)用程序時(shí)遇到的最大問(wèn)題是處理不同來(lái)源的大型代碼庫(kù)和大量數(shù)據(jù)。我是React的粉絲,我在很多項(xiàng)目中都使用過(guò),但是React沒(méi)有解決我的問(wèn)題。
我們來(lái)看看使用Cycle.js的一些利弊。
優(yōu)點(diǎn)
-
大代碼庫(kù)
當(dāng)應(yīng)用變大時(shí),React有一些問(wèn)題。想象一下,100個(gè)容器中有100個(gè)組件,每個(gè)組件都有自己的樣式、功能和測(cè)試,這是許多目錄中許多文件中的許多代碼行,很難瀏覽這些文件。
Cycle.js被設(shè)計(jì)為通過(guò)將項(xiàng)目拆分成獨(dú)立的組件來(lái)處理大型代碼庫(kù),這些組件可以被隔離和測(cè)試而沒(méi)有副作用。沒(méi)有Redux,沒(méi)有副作用,一切都是純數(shù)據(jù)流。
-
數(shù)據(jù)流
React中最大的問(wèn)題是數(shù)據(jù)流。 數(shù)據(jù)流設(shè)計(jì)不是React的核心。開發(fā)人員已經(jīng)嘗試解決這個(gè)問(wèn)題,我們有許多庫(kù)和方法來(lái)嘗試處理這個(gè)問(wèn)題。最受歡迎的是Redux,但這并不完美。 Redux需要花費(fèi)時(shí)間配置并且需要編寫一個(gè)只適用于數(shù)據(jù)流的代碼。
使用Cycle.js,程序員只需要編寫使用數(shù)據(jù)執(zhí)行某些操作的函數(shù),Cycle.js將處理其他所有操作。
-
副作用
React有處理副作用的問(wèn)題。 在React應(yīng)用程序中沒(méi)有標(biāo)準(zhǔn)的方法來(lái)處理副作用。有很多工具可以處理,但需要一些時(shí)間來(lái)設(shè)置和學(xué)習(xí)。最流行的是redux-saga,redux-effect,redux-side-effect和redux-loop。
Cycle.js不需要那么麻煩,只需包含想要的驅(qū)動(dòng)程序(DOM,HTTP或其他)并使用它即可。驅(qū)動(dòng)程序會(huì)將數(shù)據(jù)發(fā)送到純函數(shù),程序員可以更改并將其發(fā)送回將會(huì)呈現(xiàn)或執(zhí)行其他操作的驅(qū)動(dòng)程序。最重要的是它是標(biāo)準(zhǔn)化的,不需要依賴第三方庫(kù),很簡(jiǎn)單!
-
函數(shù)式編程
最后但并非不重要的是函數(shù)式編程。Cycle.js是建立函數(shù)式編程范式的很好選擇。一切都不依賴任何外部狀態(tài)。此外,沒(méi)有類或類似的東西。 這更容易測(cè)試和維護(hù)。
缺點(diǎn)
-
社區(qū)
目前,React是較流行的框架,它隨處可見(jiàn)。但Cycle.js不是,它的社區(qū)還有待完善。
-
學(xué)習(xí)一個(gè)新的范式
Cycle.js是一個(gè)響應(yīng)式編程范例。響應(yīng)式編程是一個(gè)不同的范例,需要花費(fèi)一些時(shí)間習(xí)慣。