基于React開發范式的思考:寫在Lesx發布之際

例子:lesx-example
webpack loader: lesx-loader

一些背景

現在前端框架已經呈現出React、Angular、Vue三足鼎立的局勢,對于三者的對比以及技術選型的思考與爭論也被討論了非常多,比如知乎上的這個問題:react.js,angular.js,vue.js學習哪個好?,對于這個問題我們不再做過多贅述。但不管怎么樣,現在github上star數最多、npm上安裝量最大的還是React,阿里巴巴很多團隊的技術棧也是基于React的。此篇文章也是基于React的開發范式來進行討論的。

JSX的模板范式沒有選擇HTML模板,而是完全基于JS的,同時提供了一種JSX的語法糖,方便用戶的開發。這樣做是有幾種考慮的,首先React是跨平臺跨終端的,不僅可以在Web browser中運行,還可以基于RN在移動端APP、服務端基于SSR來運行,基于虛擬DOM的實現讓他可以輕松地做到以上幾點,另外,完全基于JS的開發可以不用掌握類似Vue/angular的指令式的語法,而是更多的偏向于使用純js的語法開發范式,一次學習終身受益,而不用每次在開發的過程中還要去查看API文檔。

但是,React的這種開發模式也帶來了一個額外的問題,就是jQuery時代尊崇的UI與邏輯分離的最佳實踐在JSX時代又有了極大的后退。于是我們一直在思考,能不能有一種模式,既能享受像Vue那樣UI、展示(樣式)與邏輯分離,方便維護與可擴展,又能享受React JSX的語法帶來的便利呢?

Lesx的誕生

基于上面的思考,于是有了Lesx這個構建式的框架

構建式的框架并不是我們的首創,但是這個概念不知道是不是我們第一次正式提出來。業界已經有的AOT(Ahead Of Time)、非侵入式的框架比較知名的是svelte,他的開發范式跟Lesx比較相似,但是他并不是基于React或者哪個框架的,而是自己研發了一套底層組件機制,對于模板代碼的解析也是基于自己實現的一套AST解析實現,語法類似于Handlebars。基于React的開發范式跟Lesx比較相似的還是react-templates,他稱自己是:Lightweight templates for React。他只是把React Class的render部分抽了出來,DSL會被編譯成React.createElement,然后生成一個函數作為React Class的render方法。同時,react-templates里還增添了很多類似vue的指令的功能,比如:rt-ifrt-repeat等,這樣的框架的問題就是問題解決的并不是很徹底,抽出render部分的同時,我們還是需要對React創建部分需要大量的代碼書寫;同時,對于JSX語法擴展指令的模式增添了開發者的學習成本,后面開發中也需要不斷地去查看文檔如何使用這些指令,這是我們極不推崇的。

在這樣的背景下,我花了兩天時間,早起晚睡、憋屎憋尿的完成了基于React做到UI、展示(樣式)與邏輯分離的構建式開發框架:Lesx的初版。

基于Lesx的開發模式

Lesx作為webpack的loader存在,使用類似Vue的單文件的開發范式,方便開發者的代碼組織與開發:

index.lesx:

<style>a {color: red;}
</style><template><div><a onClick={this.func}>點我</a>{console.log(this.props)}<If condition={ this.props.valid }><div>{this.state.name}</div></If><Button type="primary" onClick={() => {alert('I am an antd button!');$setState({name: 'new name'});}}>antd button</Button><My /></div>
</template><script>module.exports = {props: {valid: true},state: {name: 'xiangzhong.wxz'},func({setState,}) {alert('I am a function!');setState({name: 'new name'});}};
</script>

很明顯的,他有幾個特點:

UI、樣式與邏輯分離

lesx文件有style/template/script三個標簽,內部分別存放他們對應的內容代碼。

style部分我們默認使用跟css完全兼容同時有更多便利性語法的Sass語言,后面馬上也會支持Less語法。

tenplate部分則完全是React的jsx語法,同時由以下幾個擴展:

  • 我們基于babel插件jsx-control-statements提供了便利性的控制流標簽,比如:IfFor等等,語法非常簡單,一次學習終生高效!當然,有的同學可能會不認可這種標簽擴展控制流的模式,此時你也可以繼續使用你熟悉的三元運算符、數組map等方式來實現邏輯與展示控制,但是我們相信,標簽控制符是更清晰、更容易維護的開發模式;
  • 你可以在DSL里面使用一些輔助性全局變量:

    • $setState: this.setState的簡便寫法,通過改變state值來觸發UI渲染;
    • $getRef: React通過組件ref屬性獲取組件的簡便寫法;
    • $getProps: 獲取React屬性的簡便性方法,相當于:this.xxx;

后面我們還會做一些其他的更高級的便利性擴展,比如:接入axios的異步操作,React的forceUpdate便利性機制等等。

script部分是用于書寫前端邏輯處理的地方,你可以使用ES6的語法,做各種的數據處理,只需要最后把一個對象交給module.exports變量即可,這個對象可以包含如下內容:

  • state: React Component的state初始值,可以是對象也可以是函數;
  • props: React props初始值,可以是對象也可以是函數;
  • React組件的生命周期鉤子函數: 比如:componentDidMount等,會被自動掛在到最終生成的React Component Class里面去;
  • 其他任意的屬性或方法: 均會被掛在到React Component實例(this)上去,而且,對于方法部分會被自動綁定到this作用域(this.xxx.bind(this)) 。

對于異步處理部分,默認可以直接調用this.axios.xxx的方法來實現,并支持ES7:async/await語法:

module.exports = {async getData(reqArg = {}) {const res = await this.axios.post('url/post', reqArg);return res;}
};

同時,支持異步請求庫可配置,可以在loader的配置里配置自己的異步請求庫,此時會替換掉默認的axios。但這一塊功能暫時還沒有加入,承諾在接下來的一周之內會加上去。目前可以通過組件props傳遞的方式來使用異步,比如:

import App from './index.lesx';
import axios from 'axios';console.log('App:', App);render(<Appaxios={axios}components={{My,}}
/>, document.querySelector('#root'));

然后在lesx文件的script里面就可以這樣用:

module.exports = {props: {valid: true},state: {id: 1001,},async getData(reqArg = {}) {const res = await this.props.axios.post('url/post', reqArg);return res;},clickHandler({setState,}) {const {id,} = this.state;const userData = this.getData({id,});setState({name: userData.name,});}
};

開發的極大便利:

UI庫是我們在開發中重度依賴的部分,特別是對于像React這種完全組件化的開發框架來說,有個好用的UI框架簡直是如虎添翼,會讓我們的開發效率得到極大地提升!所以,我們的開發框架默認集成了國內最優秀的React UI庫:antd,當然了,你也可以通過loader的配置來更改UI庫,比如可以使用material-ui等。

在配置了UI庫之后,無需做任何工作就可以直接在template標簽里面使用該UI庫的任意組件了,比如使用Button組件:

<script><Button type="primary" onClick={() => {alert('I am an antd button!');$setState({name: 'new name'});}}>antd button</Button>
</script>

Lesx不僅會自動幫你打包你使用到的組件,同時,還會自動幫你把組件的樣式引入;另外,基于babel的插件:babel-plugin-import,我們做到了按需打包,只會把你用到的組件給打包進來,保證打包后的文件的最小體積。

開發者不需要書寫React的組件生成代碼

因為我們把React Component生成的過程全部放在了AOT里實現,所以開發者無需寫React組件生成、UI庫組件引入的操作,其實,開發者甚至不需要知道React的存在,也甚至更不需要學習React,唯一需要做的就是在渲染js文件中做一些組件引入以及渲染執行的操作,但是就這一塊的成本其實是極低的。

目前前端的資源是極度缺乏的,整個互聯網都缺前端,所以,我們在考慮如何釋放前端人力這個方案的時候,我們是否可以考慮如何降低前端的上手成本,讓后端同學可以上手前端開發,做到網后端開發賦能呢?其實Lesx的開發范式一開始就是為這個方向考慮的,在滿足降低前端開發成本、降低前端開發復雜度、提高代碼可維護性的同時,也可以很方便的提供給后端,讓后端同學可以輕松上手前端開發,從而達到合作共贏的狀態。對于前端人手緊缺的公司可以考慮這個方案的落地,也許會起到意想不到的效果。

同時,為了可擴展性,我們做了一些額外的處理。除了可以給Lesx DSL轉成的Component傳遞屬性然后可以在Lesx文件使用之外,當我們確實需要第三方或者自己之前基于React原生模式開發的組件需要拿過來直接使用的時候,我們提供了components屬性,將任意的第三方組件放在conponents屬性對象中,既可以直接在DSL中使用,如下:

import React, { Component } from 'react';
import { render } from 'react-dom';
import My from './My';
import App from './index.lesx';console.log('App:', App);render(<Appcomponents={{My,}}
/>, document.querySelector('#root'));

在上面我們引入了自己開發的My組件,并放在了Lesx DSL轉成的App組件的components屬性里,于是可以在lesx文件中像下面這樣使用:

<style>{ /** style代碼 */ }
</style><template><div><a onClick={this.func}>點我</a><My /></div>
</template><script>{ /** 邏輯代碼 */ }
</script>

其實,基于這種開發范式針對不同的場景可以有不同的代碼組織模式。如果你的界面不是很復雜,或者是比較典型的中后臺應用場景(增刪改查這種),你可以完全基于一個.lesx文件開發完你所有的頁面邏輯,更多的則是依賴于第三方的UI庫來為你的開發提供便利,說白了就是更多的依賴于組件搭積木式的開發范式,這個時候template就是開發的重點所在,而scriptstyle只是起到了添磚加瓦的便利性的開發,這個時候Lesx的職責就是頁面級別的代碼組織方式;如果是比較復雜的應用,比如SPA應用,這時我們可以基于Lesx來開發自己的一個個的React組件,然后加入vanex、dva等數據流管理框架來方便對大量數據的操作,最后通過react-router等router組件進行統一組織,然后進行渲染。這個時候Lesx的職責就不一樣了,變成了組件級別的代碼組織。

怎么樣,有沒有那么一點點的打動你的心呢?^_^ 如果有的話,不妨去體驗下Lesx,相信會帶給你不一樣的開發體驗。

例子:lesx-example
webpack loader: lesx-loader

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280473.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280473.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280473.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mac共享單個磁盤_如何與您的所有設備共享酒店的單個Wi-Fi連接

mac共享單個磁盤Many hotels still limit you to one or two Wi-Fi devices per room–a frustrating limitation, especially when traveling with someone else. Connection restrictions can apply anywhere you have to log into a Wi-Fi network via a portal instead of …

Python FastApi:快速建立docker容器/掛載共享文件夾/導入導出

一、目的 a.快速把原有fastapi代碼部署到docker&#xff0c;讓docker在server運行。 b.不涉及docker深入設置。 c.使用python第三方lib少或簡單。 二、步驟 ps:請提前安裝docker 1.新建Dockerfile&#xff0c;放入到項目根目錄 a.Dockerfile沒有后綴. b.準備好requireme…

PHP-FPM 與 Nginx 的通信機制總結

PHP-FPM 介紹 CGI 協議與 FastCGI 協議 每種動態語言&#xff08; PHP,Python 等&#xff09;的代碼文件需要通過對應的解析器才能被服務器識別&#xff0c;而 CGI 協議就是用來使解釋器與服務器可以互相通信。PHP 文件在服務器上的解析需要用到 PHP 解釋器&#xff0c;再加上對…

Android——監聽事件總結

各種監聽事件 1.按鈕 Button&#xff08;1&#xff09;點擊監聽btn_1.setOnClickListener(new View.OnClickListener() { &#xff08;2&#xff09;長按監聽btn_1.setOnLongClickListener(new View.OnLongClickListener() { 2.單選框 RadioGroupradio_gp.setOnCheckedChangeLi…

ChatGPT 大智近妖,從宇宙人生到手搓光刻機,從哄女朋友到寫年終總結我們聊得非常開心,反而讓人越來越憂心...

都說 ChatGPT 要干掉程序員&#xff0c;清理搜索引擎&#xff0c;取代Stack Overflow&#xff0c;還能消滅人類&#xff0c;這些有些言過其實了。ChatGPT 的定位是一個人工智能助理&#xff0c;它說&#xff0c;它的主要目的是通過回答用戶的問題&#xff0c;為用戶提供幫助。在…

如何在Windows Defender中安排掃描

Windows Defender automatically performs background scans during your PC’s idle moments, but doesn’t include an easy way to schedule a full scan. There is a way to do it, though. Windows Defender在PC空閑時自動執行后臺掃描&#xff0c;但是沒有包括安排完整掃…

復習深入筆記02:魔法方法/cookie,session,token/異常

魔法方法 對象生成 1.先調用__new__方法&#xff0c;生成空對象。控制對象生成。 2.當執行“對象類名&#xff08;namelqz&#xff09;”&#xff0c;觸發類的__init__()

比特熊故事匯獨家 | .NET 感恩專場

點擊上方藍字關注我們&#xff08;本文閱讀時間&#xff1a;15分鐘)大家好&#xff01;我是愛吃、愛玩、更愛學習技術&#xff0c;IT界新晉小紅人&#xff0c;開發者的好朋友——比特熊&#xff01;比特熊&#xff1a;本期故事匯是.NET專場&#xff0c;今天一次性邀請到DOTNET領…

Ubuntu Core 給物聯網提供更多安全支持

開發四年只會寫業務代碼&#xff0c;分布式高并發都不會還做程序員&#xff1f; Canonical 是 Ubuntu 的一個桌面環境&#xff0c;該公司目前在云服務業務賺到了錢。因為 Ubuntu Core 為嵌入式設備帶來了 Ubuntu 18.04 長期支持(LTS)代碼庫。Ubuntu Core 的鏡像大小為 260MB&…

semantic ui要裝什么才能使用

作者&#xff1a;呆呆笨笨鏈接&#xff1a;https://www.zhihu.com/question/32233356/answer/196799506來源&#xff1a;知乎著作權歸作者所有。商業轉載請聯系作者獲得授權&#xff0c;非商業轉載請注明出處。本答案將以兩種方式講解如何從零開始使用 Semantic-UI&#xff0c;…

用戶帳戶控制設置_創建快捷方式以避免用戶帳戶控制彈出式快捷方式

用戶帳戶控制設置There are numerous applications which, when launched, result in a UAC (User Account Control) warning being displayed. There are reasons why this security measure is a good idea, but it can also be extremely irritating. ElevatedShortcut lets…

Java Observer Pattern(觀察者模式)

當對象間存在一對多關系時&#xff0c;則使用觀察者模式&#xff08;Observer Pattern&#xff09;。比如&#xff0c;當一個對象被修改時&#xff0c;則會自動通知它的依賴對象。觀察者模式屬于行為型模式。 關鍵代碼&#xff1a;在抽象類里有一個 ArrayList 存放觀察者們。 優…

rest_framework01:前后端分離\規范\簡單例子(查詢某本書)

web 開發模式 RESTful規范 1 數據的安全保障 url鏈接一般都采用https協議進行傳輸 注&#xff1a;采用https協議&#xff0c;可以提高數據交互過程中的安全性 2 接口特征表現 用api關鍵字標識接口url&#xff1a; https://api.baidu.comhttps://www.baidu.com/api注&#xff…

.NET Core如何通過SSL訪問MongoDB?

【.NET Core】| 總結/Edison Zhou大家好&#xff0c;我是Edison。最近有一個ASP.NET Core通過SSL證書訪問MongoDB的需求&#xff0c;但是在網上發現資料很少&#xff0c;于是調查了一番&#xff0c;做了如下的筆記&#xff0c;希望對你有用。背景在實際場景中&#xff0c;開發環…

SQA

一、長大一條龍SQA計劃 SQA計劃需要包含軟件工程質量保證、質量控制、數據收集和統計報告這四方面內容&#xff0c;計劃以時間為線索&#xff0c;小組內成員為對象&#xff0c;以下為我組的工作計劃&#xff1a; 時間 任務 需完成的情況 2017年10月 用戶登錄注冊后臺實現 …

在pom.xml中配置nexus上傳地址

2019獨角獸企業重金招聘Python工程師標準>>> <distributionManagement> <repository> <id>thirdparty</id> <url>http://&#xff5b;nexusIP地址&#xff5d;:8081/nexus/content/repositories/thi…

網頁背景平鋪_在大約十秒鐘內為網頁創建無縫平鋪背景

網頁背景平鋪Creating a background image for your webpage (or desktop background) isn’t challenging at all. In fact, even a newbie Photoshop user can bash one out in about ten seconds. Here’s the simplest of simple methods with surprising, great results. …

9月11日學習內容整理:正則表達式,re模塊

一、正則表達式&#xff1a;正則是很大的一個知識點&#xff0c;不會僅僅是下面這些東西 1、概念&#xff1a;正則表達式就是一種對字符串匹配的規則&#xff0c;注意是只對字符串&#xff0c;正則表達式和python沒啥關系&#xff0c; 2、表達式&#xff1a; &#xff08;1&…

rest_framework02:修改數據/校驗鉤子/read_only和write_only

修改數據 1.傳入數據&#xff0c;選中data&#xff0c;以及修改data book_ser BookSerializer(instancebook, datarequest.data) 2.校驗&#xff0c;通過則保存。 if book_ser.is_valid(): # 返回True 表示驗證通過book_ser.save() # 不是book.save() rest_framework…

MongoDB的安裝與使用

MongoDB是一款NoSql數據庫。NoSql數據庫叫非關系型數據庫&#xff0c;NoSql的全名Not only sql。是為了解決高并發、高可用、高可擴展&#xff0c;以及大數據存儲等一系列問題而產生的數據庫解決方案。NoSql&#xff0c;它不能替代關系型數據庫&#xff0c;只能作為關系型數據庫…