我們是如何做好前端工程化和靜態資源管理 - 無雄 - 博客園

我們是如何做好前端工程化和靜態資源管理

我們是如何做好前端工程化和靜態資源管理

隨著互聯網的發展,我們的業務也日益變得更加復雜且多樣化起來,前端工程師也不再只是做簡單的頁面開發這么簡單,我們需要面對的十分復雜的系統性問題,例如,業務愈來愈復雜,我們要如何清晰地梳理;團隊人員愈來愈多,我們要如何更好地進行團隊協作;功能愈來愈多,我們要如何保證頁面的性能不至于下降,等等。所有的這些都可以歸結為如何提升開發體驗和性能問題。

提升開發體驗

我們主要從以下三個方面來提升我們的開發體驗。

規范化

當團隊人員不斷擴充時,我們需要制定統一的規范來對平時的開發工作做出一定約束和指導。統一的規范包括前端的代碼規范,根據規范定義好一套代碼檢查的規則,在代碼提交的時候進行檢查,讓開發人員知道自己的代碼情況。

同時,根據以往的開發經驗,我們制定了統一的項目框架,根據業務功能不同,將一個項目(app)拆分成不同的業務模塊(module),而每一個模塊都包含自身的頁面(page)以及構成頁面所需要的組件(widget),每一個項目涉及到app、module、page、widget這些已經約定好的概念,這樣讓項目結構更加清晰,而且讓團隊內不同業務的人員之間切換無障礙。

項目架構

組件化

在項目中引入組件化的概念,這里的組件對應上文講到的widget,每一個組件都會包含組件自身的模板、css、js、圖片以及說明文件,我們使用組件來拼裝頁面,像搭積木一樣來拼裝我們的頁面,同時一個組件內可以調用另一個組件。

組件化

在拿到設計稿后,我們首先需要確定哪些需要做成公共組件,那些是要做成獨立組件,以及組件間如何進行通信。在頁面中調用這些組件后,會自動加載組件的模板以及組件的靜態資源,而當組件不再需要時,只要移除掉組件引用,那么相應的模板和靜態資源也會不再加載。

組件化的好處主要有這么幾點

  • 管理方便,我們可以把一個獨立功能相關的文件在工程目錄中放在一起,這樣代碼管理起來會非常便利
  • 組件復用,通過抽取公共組件,可以實現組件復用,從而減少工作量,創造價值
  • 分而治之,這是組件化最重要的一點,將頁面組件化,就是對頁面功能的拆分,將一個大的工程拆成小的零件,我們只需要關注每一個零件的功能,極大地降低了頁面的開發與維護的難度

自動化編譯

在前端開發中,我們總是會去使用很多工具、手段來優化代碼、提升開發效率,例如,我們會使用sass、less等CSS預處理工具來編寫更好維護的樣式代碼,我們也會使用CSSLint、eslint等代碼檢查工具來檢查代碼的語法錯誤,使用文件合并壓縮等手段來減少資源大小,除此之外我們還會去做雪碧圖合并、多倍圖處理、字體壓縮處理、代碼發布等等。

曾經有大神說過,超過90s的工作都應該自動化掉。而以上所有的這些工作,貫穿我們整個開發流程,但是不同工具的切換不但顯得凌亂,而且影響開發效率。在自動化、工程編譯的思想早已深入人心的當下,我們當然也要緊跟潮流,所以我們考慮通過自動化手段來提升我們的效率,讓所有操作可以一鍵式開速執行完。

我們將通過定義好一系列的編譯任務,按照一定順序依次對我們的項目自動進行編譯操作,最后產生出可上線的代碼。

提升性能

我們主要從以下四個方面來做好性能優化。

首屏優化

頁面的打開速度一直是大家非常關心的一個指標,一個頁面打開太慢會讓讓用戶失去等待的耐心,為了讓用戶更快地看到頁面,我們考慮將頁面中部分靜態資源代碼直接嵌入頁面中,我們通過工具處理,在工程編譯階段,將指定的靜態資源代碼內嵌入頁面中,這樣可以減少HTTP請求,提升首屏加載速度,同時降低頁面裸奔風險。

按需加載

同時,我們考慮通過盡量減小頁面體積來提升頁面打開速度,在業務上我們將頁面劃分為一個個樓層組件,以京東美妝館為例,頁面中從上而下分為首焦、至IN尖貨、今日特惠、潮流前沿、口碑榜單這么幾個樓層組件,其實這個頁面還有很長,內容非常多且復雜。

京東美妝館

之前我們的做法是整個頁面直出,這樣一次性加載的內容會非常多,為了提升打開速度,我們考慮通過按需加載的方式來優化頁面的加載。我們在頁面中只放每一個樓層的框架性代碼,樓層的模板和數據都通過異步的方式去拉取,來實現樓層組件的按需加載,同時我們可以對模板以及數據進行緩存,以此來減少請求,做更極致的優化。在開發中我們以正常組件的方式去開發整個頁面,隨后通過編譯工具,在代碼編譯階段自動將樓層的模板抽離成一個獨立的JS文件,并給樓層容器打上標記位,通過頁面加載邏輯去按需拉取模板,再進行渲染。

通過給樓層容器和模板分別加上標記位?o2-out-tpl-wrapper?o2-out-tpl

按需加載1

在編譯時自動將指定的模板代碼抽離成獨立js文件

按需加載2

并且給樓層容器打上標記

按需加載3

同時在邏輯腳本適當位置自動加入模板的版本

按需加載4

通過上述步驟,實現按需加載的自動化生成,在提升性能的同時,很好地解放我們生產力。

基于資源表加載

根據頁面組件化,通過工具分析,我們將獲得頁面與組件的依賴關系表,同時也能確認頁面所引用資源的依賴關系,例如,我們在頁面hello中同步引用組件topbar,那么依賴關系表中將會記錄同步引用關系hello引用topbar.tpl、topbar.css、topbar.js,那么頁面hello將會自動加載組件topbar的CSS與JS,同時依賴表會記錄異步引用的關系,假如我們在組件C中通過API異步引用了組件D的js,那么會在依賴表中記錄C異步引用D.js這一個依賴關系,這樣D.js這個資源將會在用到的時候被異步調用。

組件依賴

資源依賴

同步引用的資源通過生成combo形式鏈接,在服務端進行文件合并,這樣在頁面加載的時候,頁面只會加載自己需要的同步資源,異步的資源將會在用到的時候再加載,有效避免資源冗余。同時刪除、增加組件也非常方便,只需改動模板中對組件調用,通過編譯工具會自動重新生成模板以及combo鏈接。

我們可以將資源加載的操作抽離出來,形成一套統一的資源加載框架設計,這樣我們使用的模板可以變得更加靈活,無論是純html模板,還是PHP或Java之類的后端模板都能有效支持。編譯工具掃描代碼后只生成資源依賴表,我們通過實現各語言平臺的資源加載框架,讓不同語言的模板都能基于同一個資源依賴表進行資源加載。

同時,對資源進行MD5重命名處理,文件md5重命名也是一種提升性能的有效手段,使用文件md5后開啟服務器強緩存,可以提升緩存的利用率并避免不必要的緩存判斷處理。但文件md5重命名后會出現開發時引用的文件名對不上的問題,這就需要在資源表中記錄原文件名與md5重命名后之間的對應關系,當我們引用一個資源時,就會通過查表獲取重命名后的資源名,然后利用代碼中引用資源定位的能力來進行資源名自動替換。

md5

靜態資源預加載

所謂靜態資源預加載,就是當用戶在進行瀏覽頁面的時候,我們可以在當前頁面靜默加載下一個頁面的靜態資源,這樣當用戶進入到下一個頁面時就能快速打開頁面,從而在不知不覺中提升頁面的打開速度。

靜態資源預加載設計

我們會在靜態資源預加載平臺上配置每一個頁面id對應需要預加載頁面資源的id,然后系統通過讀取資源依賴表獲取到所需要預加載的靜態資源,生成預加載資源列表文件,再將文件推送到線上服務器,通過頁面掛載js請求獲取預加載資源列表,隨后靜默加載資源。在有了資源依賴表后,我們可以準確地分析到每一個頁面引用資源的請求,就可以很好地實現靜態資源預加載的功能。

靜態資源預加載

Athena

工欲善其事,必現利其器。為了實現我們對提升開發效率和產品性能的訴求,我們提出了比較完整的工程化解決方案以及對應的工具Athena。

Athena是由京東【凹凸實驗室】(aotu.io) 推出的一套項目流程工具,通過Athena,我們可以很流程地跑完整個開發流程。Athena分為兩部分,一是本地自動化編譯工具,二是資源管理平臺,其架構如下

Athena

本地自動化工具

Athena本地編譯工具是一個基于NodeJs的命令行工具,通過執行命令的方式來優化我們的開發流程,目前Athena的主要功能有

  • 自動創建項目、模塊、頁面、組件結構
  • 輕量組件化功能,根據組件加載情況生成資源依賴表
  • Sass/less 編譯
  • 代碼檢查
  • CSS prefix等處理
  • CSS合并壓縮,JS合并壓縮
  • 自動生成雪碧圖,自動多倍圖,圖片壓縮
  • 字體文件壓縮
  • 自定義圖片轉base64
  • 文件內聯,可以內聯樣式及JS代碼
  • 文件MD5戳,將文件進行使用MD5進行重命名
  • 本地預覽,直接查看整個項目
  • 資源定位(圖片等資源路徑替換)
  • 生成CSS頁面片,提供將頁面引用的CSS/JS抽離成頁面片的形式,方便管理CSS資源
  • 部署到預覽機和開發機

創建項目結構

在執行創建命令時,Athena會從管理平臺下載自定義好的項目模板,可以根據模板創建項目、模塊、頁面、和組件。Athena有四個創建命令:

通過執行?$ ath app demo?命令就可以生成定義好目錄結構的項目。

創建項目

隨后可以通過?$ ath module home來創建一個業務模塊;

通過?$ ath page index?來創建頁面;

通過?$ ath widget widgetName?來創建組件。

開發使用

組件化

Athena中實現組件化主要是分為兩種,一是針對純HTML模板,通過擴展模板引擎方法實現,提供了組件化API?widget.load,它可以方法接收三個參數,第一個參數是widget的名稱,后面兩個參數是可選參數,第二個是向widget傳遞的一些參數,第三個是widget所屬的模塊,如果是本模塊,可以不傳例如

1

2

3

4

5

6

7

<%=?widget.load('user')?%>

<%=

widget.load('user', {

param:?'test'

})

%>

<%=?widget.load('user', null,?'gb')?%>

通過模板引擎編譯,執行widget.load方法,可以實現加載模板,記錄依賴關系的目的。

組件化形式

二是針對不同語言的后端模板,通過實現各自的組件化框架來進行組件的加載,例如?PHP?下使用?<?= $widget->load('user', NULL, 'gb') ?>?來進行組件加載,再通過代碼掃描得出組件依賴關系。

Athena中的API

Athena針對模板提供了一系列的API來擴展豐富的功能,例如前面提到的?<%= widget.load() %>?來實現組件化。

同時Athena中還提供了其他API:

<%= getCSS() %><%= getJS() %>?用來引用CSS/JS文件,傳入文件名和模塊名;

<%= uri() %>?提供了資源定位功能,可以在模板中標記資源,編譯過程中會進行替換,而且在JS中也有資源定位API?__uri()

<%= inline() %>?提供了內聯資源的功能,傳入文件名和模塊名,可以在模板中內聯任意資源,例如圖片以及JS腳本;而且?inline?也可以內聯一段網絡資源,例如線上的JS文件,同樣的在JS中也有內聯資源API?__inline()

雪碧圖標識??__sprite?,在CSS中引用圖片最后加上標識??__sprite?可以自動生成自定義名稱雪碧圖,同時支持自定義生成多張雪碧圖,只需要要標識后面帶上一個文件名,就可以生成一張以這個文件名來命名的雪碧圖,例如??__sprite=icons?,這樣所有帶同樣標識的圖片就會生成一張以?icons?為文件名的雪碧圖。

編譯預覽

編譯任務

在編寫完項目,就可以通過命令來對項目進行編譯了,執行編譯命令?$ ath build,會針對指定模塊執行已經定義好的編譯任務,根據項目需求,目前編譯都是基于業務模塊去編譯,編譯任務的最小執行單位是頁面,每次編譯都會執行以下編譯列表

編譯任務

編譯截圖

本地預覽

執行預覽命令?$ath serve?會執行精簡版編譯任務來編譯項目,編譯完項目后會生成一份站點地圖,隨后打開一個本地服務器來預覽項目,使用這個命令可以很方便地進行開發,在預覽時會同時watch目錄和文件的改動,并且提供了livereload功能,我們可以在預覽時任意修改文件,都將實時地反映到頁面中,同時可以新建另一個窗口執行新增組件和頁面的操作,讓整個開發過程非常順暢,我們只需關注開發本身就好,不需要再關注其他事。

ath serve

執行完編譯任務后,默認自動打開瀏覽器,預覽站點地圖

站點地圖

Mock server

在進行項目預覽的同時,Athena同時提供了mock data的服務,我們可以配置相應的路由,以及路由接口對應的假數據,所有的接口請求會發送到mock server上,在mock server中可以選擇將請求代理到假數據平臺還是代理到線上接口,這樣就可以脫離后端進行開發聯調了,以此實現數據的前后端分離。

mock server

項目部署

在開發預覽完后,通過命令?$ ath publish?就可以將項目發布到配置好的測試機上,發布同時支持ftp、sftp以及http形式。

組件維護

我們通過組件化的手段已經將我們的項目進行組件化了,這樣我們經過業務迭代積累,產出很多業務公共組件,但在以往的項目開發中,公共組件的更新與維護一直很受限制,而且有哪些公共組件、公共組件長什么樣子,只能依靠口口相傳或者手工維護的文檔。所以在Athena中我們加入了組件平臺,在組件平臺上統一展示各個業務的公共組件,而得益于本地工具,組件平臺不需要人工干預維護,我們可以在本地通過命令?$ ath widget-publish [widgetName]?命令來發布一個組件到組件平臺,這樣其他人就可以立即在組件平臺進行組件的預覽,而其他人若想使用該組件時,在本地通過命令?ath widget-load [widgetId]?就可以下載該組件到自己的模塊目錄下了。

這樣組件的維護更加自動化,公共組件的使用也更加方便了。

組件發布

組件發布

組件下載

組件下載

自身優化

為了提升開發效率,Athena做了一些優化操作

精簡項目預覽時的任務

在開發時進行項目預覽時,會執行精簡版的編譯任務,剔除了類似文件壓縮、雪碧圖生成、模板抽離處理等耗時的操作,只保留核心、必須的編譯任務,這樣可以極大地減少編譯時間,提升開發的效率。

預覽時監聽細化

在開發進行預覽時,會對所有文件的改動進行監聽,而針對每一類文件都有非常細化的操作,當文件改動時只會執行改文件所需要的編譯任務,而不會進行整體編譯,這樣可以很好地提升開發效率。例如改動某一組件的CSS文件,則只會針對該文件執行一些相關的CSS操作。

同時得益于所有文件依賴關系的記錄,在監聽時會根據依賴關系進行文件編譯,例如某sass文件中引入了另一個sass庫文件,修改這個sass庫文件的時候,會根據引用關系表同時更新到所有引用到這個sass文件的文件,這樣項目文件更新及時,讓開發流程更加流暢。

編譯緩存

在圖片壓縮和sass編譯時,開啟文件緩存,將已經編譯過且沒有改動的文件過濾掉,不再編譯,大幅提升編譯速度。

發布緩存

設置發布過濾,根據文件md5過濾掉已經發布過的文件,提升發布速度。

技術選型

Athena本地工具早期技術選型是?Yeoman?+?Gulp?的方式,但后來由于安裝、更新非常麻煩,命令太長很難打的原因,我們改成了自己開發一個全局安裝包的方式,編譯核心使用的還是?Gulp?的?vinyl-fs?來實現文件流處理,通過?ES6 Promise?來進行編譯流程控制,最小以頁面為單位,經過一系列編譯任務,最后產出編譯好的文件。

技術選型

管理平臺

性能優化一直是前端工程師探索的課題,很多時候就是資源的分配問題,也就是資源管理。為了更好地配合本地構建工具來管理資源,我們搭建了管理平臺。我們來看下,結合本地構建工具和管理平臺,工作流程變成了怎樣?

工作流程

  1. 在管理平臺上創建項目,輸入項目名稱和預覽機,以及選擇相應的模板等;
  2. 在終端執行ath app指令,工具會優先拉取遠程服務器的項目信息來初始化項目,如果沒有獲取到相關信息,就會在本地生成項目,并將項目信息上報給服務器;
  3. 項目初始化后,就可以創建模塊、頁面、組件了;
  4. 在編碼過程中,可通過ath server預覽頁面;
  5. 在本地通過后,可執行ath publish將代碼發布到開發機或者預覽機。

在上面的publish指令中,工具會掃描所有文件,執行代碼檢查,掃描頁面文件,獲取組件依賴關系,根據組件依賴關系進行文件合并,然后會進行樣式處理、js處理以及圖片的處理,根據配置是否進行md5重命名文件,組裝html,插入樣式、js和圖片,最后將編譯好的文件發布到相應的機器。在整個過程里面,會生成資源關系依賴表,最終會將資源關系表及編譯后的文件上傳至管理平臺。

除此之外,每個指令的操作都會上報給管理平臺。管理平臺收到數據后,會對數據進行處理,最終可以在平臺上看到項目相關的信息。

整體工作流程圖如下:

工作流程

從上面的工作流程中,我們可以看到,管理平臺需要有數據統計、資源管理以及項目管理的功能。整體架構圖如下:

管理平臺架構

數據統計

數據統計包含項目操作日志,主要是用于統計團隊每個成員具體的操作,方便項目成員查看項目代碼變更;另一部份是統計樣式表、腳本以及圖片的壓縮數據,用于顯示工具給我們項目帶來的提升。

以下是操作日志統計:

數據統計

資源管理

資源管理是管理平臺的核心,主要分為4個部分:模塊展示、依賴關系、組件預覽和權限控制。這部分功能主要通過本地構建工具提供的資源關系表來完成。

模塊展示

模塊展示,用于記錄項目具體包含哪些模塊以及模塊具體的信息。在平常開發中,我們的項目會分為許多模塊,不同的模塊有不同的人來開發和維護。當項目越大的時候,可以通過管理平臺清晰地看到模塊具體的信息。

模塊展示

依賴關系

依賴關系,主要是html、css、js和圖片相互之間的關系。通過分析資源關系依賴表,可以獲取到各個資源被引用的情況以及線上版本的情況。當線上環境采用md5來做資源管理時,我們不是很清晰地知道靜態資源對應線上哪個版本的資源,而有了這個依賴關系表,當出現問題時,我們可以更快地定位到具體的資源。

依賴關系

組件管理

我們采用組件來拼湊頁面,當項目越大時,組件越多,那么如何管理組件成為了一個棘手的問題。比如說,有一些比較老的冗余組件,我們不確定是否為其他頁面所引用,那么就不能愉快地刪除它。有了組件管理,可以清晰地知道組件的被調用情況,就可以對組件做相應的操作。

組件管理,結合組件平臺來使用,在管理平臺上引用組件地址預覽組件,同時可以獲取到組件被引用以及引用資源(如css、js、圖片)的相關情況。

組件管理

我們的組件分為兩種,一類是通過ath w自動創建的,通過ath pu提交到管理平臺的,在管理平臺上進行組件的相關分析和編譯,得到組件的信息,這類組件主要是跟業務綁定的;另一類是通過ath widget-publish提交到組件平臺的,由組件平臺進行相關處理,這類組件是通用組件,與業務無關,用于展示給開發以及相關業務方看的。

組件提交

在組件平臺上可以預覽與編輯相關的組件,通過與設計師約定相關的設計規范來促使組件達到盡可能地復用,進而減少設計師的工作量,提升我們的工作效率。

組件平臺

組件提交到組件平臺

通過ath widget-publish指令將組件提交到組件平臺,組件平臺會對組件源碼進行編譯,將組件名稱md5、組件歸類以及組件版本記錄等等。

組件發布

從組件平臺上下載組件

通過ath widget-load指令將組件下載到本地,當本地構建工具向組件平臺發起請求時,會帶上組件名稱,組件平臺會將源碼進行編譯,將組件名稱重命名,并且相應地替換源碼中的組件名稱,同時記錄組件的被引用記錄。

組件下載

權限控制

權限控制,項目中存在公共組件模塊,公共組件比較穩定,比如說輪播組件、選項卡組件等等,這部分代碼一般比較少變動,可由少部分人來更新和維護,所以加入了權限控制機制,保證公共組件的穩定性。

項目管理

我們在使用本地構建工具時,需要配置多個參數,比如主機信息、選擇模版等,在命令行環境下有些不直觀。為了簡化這個操作,管理平臺提供了項目創建的功能,同時提供了模版創建的功能。

項目管理

在項目信息、模塊信息以及組件信息發生變更的時候,為了第一時間能夠通知項目成員更新,加入了消息通知的功能,目前通過發送郵件的方式,后期可以加入微信提醒的功能。

技術選型

管理平臺前端采用React+Redux的方式,后端采用Express+MongoDB,整體技術選型如下:

技術選型

假數據服務

存在的問題

在平常的開發中,經常需要前后端聯調,但是在項目開始之初,很多接口并沒有提供,在以前的開發模式下,需要等待后端提供接口或者自己先定義接口,前端開發的進度可能會受影響。

Mock數據平臺

為了不影響前端開發的進度,我們搭建了Mock數據平臺,通過與后端協商數據格式,自定義數據接口,這樣子就可以做到前后端分離,讓前端獨立于后端進行開發。

Mock數據平臺基于mockjs搭建而成,通過簡單的mock語法來生成數據。

Mock數據平臺目前有如下功能:

  1. 創建模擬數據,使之符合各種場景;
  2. 生成json數據接口,支持CORS以及jsonp。

Mock數據平臺

寫在最后

本次分享首先講述了我們在業務膨脹、人員不斷增加的背景下遇到的項目開發上的問題,并提出了我們自己對于這些問題思考總結后得出的解決方案與思路,最后產出適合我們團隊、業務的開發工具——?Athena。希望我們的方案能給大家帶來一定的借鑒作用。

感謝您的閱讀,本文由?凹凸實驗室?版權所有。如若轉載,請注明出處:凹凸實驗室(https://aotu.io/notes/2016/07/19/A-little-exploration-of-front-end-engineering/)

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

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

相關文章

Mybatis-plus之RowBounds實現分頁查詢

物理分頁和邏輯分頁 物理分頁&#xff1a;直接從數據庫中拿出我們需要的數據&#xff0c;例如在Mysql中使用limit。 邏輯分頁&#xff1a;從數據庫中拿出所有符合要求的數據&#xff0c;然后再從這些數據中拿到我們需要的分頁數據。 優缺點 物理分頁每次都要訪問數據庫&#xf…

常見的6種JavaScript設計模式

常見的6種JavaScript設計模式 構造函數模式 /*** 構造一個動物的函數 */ function Animal(name, color){this.name name;this.color color;this.getName function(){return this.name;} } // 實例一個對象 var cat new Animal(貓, 白色); console.log( cat.getName() );工…

峰度(Kurtosis)和偏度(Skewness)

峰度&#xff08;Kurtosis&#xff09; 定義峰度又稱峰態系數&#xff0c;表征概率密度分布曲線在平均值處峰值高低的特征數&#xff0c;即是描述總體中所有取值分布形態陡緩程度的統計量。直觀看來&#xff0c;峰度反映了峰部的尖度。這個統計量需要與正態分布相比較。 公式定…

1.27

測試程序提出問題并解決轉載于:https://www.cnblogs.com/JustinTimberlake/p/10028870.html

javascript設計模式系列 - LukeLin - 博客園

javascript設計模式系列 創建型&#xff1a; 1.抽象工廠模式&#xff08;Abstract Factory&#xff09; 2.構建者模式&#xff08;Builder&#xff09; 3.工廠方法模式&#xff08;Factory Method&#xff09; 4.原型模式&#xff08;Prototype&#xff09; 5.單例模式&a…

多功能嵌入式解碼軟件(2)

多功能嵌入式解碼軟件&#xff08;2&#xff09; 驗證類庫 通信協議 下面進行一個示例&#xff1a; 下位機需要向上位機發送3中數據幀&#xff0c;數據幀以功能碼來識別&#xff0c;每種數據幀的協議如下3個表格所示&#xff0c;上位機需要把這些數據按照協議解碼出來&#xff…

vue項目如何打包扔向服務器 - Hi-Sen - 博客園

當我們將 vue 項目完成后&#xff0c;面臨的就是如何將項目進行打包上線&#xff0c;放到服務器中。我使用的是 vue-cli&#xff08;simple&#xff09; 腳手架&#xff0c;所以就講一下如何將項目進行打包&#xff0c;并放到 tomcat 上。 如果是 vue-cli (非 simple 腳手架…

MySQL備份與恢復-mysqldump備份與恢復

這片博文主要用來介紹MySQL的備份與恢復&#xff1a; MySQL的備份形式可以分為如下幾種&#xff1a; 熱備----即不停機備份冷備----需要關閉MySQL&#xff0c;然后備份其數據文件。&#xff08;停機備份一般是直接拷貝其datadir目錄&#xff09;溫備----在線備份&#xff0c;對…

第六次實訓作業異常處理

第六次實訓作業異常處理 編寫一個類ExceptionTest&#xff0c;在main方法中使用try-catch-finally語句結構實現&#xff1a;在try語句塊中&#xff0c;編寫兩個數相除操作&#xff0c;相除的兩個操作數要求程序運行時用戶輸入&#xff1b;在catch語句塊中&#xff0c;捕獲被0除…

k8s學習筆記-調度之Affinity

Kubernetes中的調度策略可以大致分為兩種 一種是全局的調度策略&#xff0c;要在啟動調度器時配置&#xff0c;包括kubernetes調度器自帶的各種predicates和priorities算法&#xff0c;具體可以參看上一篇文章&#xff1b; 另一種是運行時調度策略&#xff0c;包括nodeAffinity…

vue-cli webpack配置分析 - chenBright - SegmentFault 思否

相信vue使用者對vue-cli都不會陌生&#xff0c;甚至可以說&#xff0c;很熟悉了&#xff0c;但對其webpack的配置可能知之甚少吧。 過完年回來后&#xff0c;我接手了公司的新項目。新項目是一個spa。很自然&#xff0c;我就想到了vue-cli腳手架了&#xff0c;當時研究一下它的…

[Xcode 實際操作]六、媒體與動畫-(6)使用UIBlurEffect給圖片添加模糊效果

目錄&#xff1a;[Swift]Xcode實際操作 本文將演示如何給圖像添加模糊效果。 在項目導航區&#xff0c;打開視圖控制器的代碼文件【ViewController.swift】 1 import UIKit2 3 class ViewController: UIViewController {4 5 override func viewDidLoad() {6 super.…

MapReduce編程實踐

一、MapReduce編程思想 學些MapRedcue主要是學習它的編程思想&#xff0c;在MR的編程模型中&#xff0c;主要思想是把對數據的運算流程分成map和reduce兩個階段&#xff1a; Map階段&#xff1a;讀取原始數據&#xff0c;形成key-value數據&#xff08;map方法&#xff09;。即…

webpack基礎+webpack配置文件常用配置項介紹+webpack-dev-server - QxQstar - 博客園

一.webpack基礎 1.在項目中生成package.json&#xff1a;在項目根目錄中輸入npm init&#xff0c;根據提示輸入相應信息。&#xff08;也可以不生成package.json文件&#xff0c;但是package.json是很有用的&#xff0c;所有建議生成&#xff09; 2.安裝webpaack a.在全局中安裝…

(十)

空轉載于:https://www.cnblogs.com/shanae/p/10034479.html

編譯原理--NFA/DFA

現成的, 講義: https://www.cnblogs.com/AndyEvans/p/10240790.html https://www.cnblogs.com/AndyEvans/p/10241031.html 一個例子, 寫得非常好. 一下子就全明白了, 尤其是像我這種沒有聽過編譯原理課程的人. https://blog.csdn.net/tyler_download/article/details/53139240 …

Python中pass的用法

空語句 do nothing保證格式完整保證語義完整以if語句為例&#xff0c;在c或c/java中&#xff1a; if(true); //do nothingelse{ //do something}對應于python就要這樣寫&#xff1a; if true: pass #do nothingelse: #do something 1 pass語句在函數中的作用當你在編寫一個程序…

express路由管理的幾種自動化方法分享-js教程-PHP中文網

我們平時在使用express寫代碼的過程中&#xff0c;會根據類別&#xff0c;將路由分為多個不同的文件&#xff0c;然后在項目的入口文件&#xff08;例如app.js&#xff09;中將其依次掛載&#xff0c;例如&#xff1a; 1 2 3 4 5 6 7 const index require(./routes/index) con…

dotnet不是內部或外部的命令,也不是可運行的程序或批處理文件

>>這臺電腦>>屬性>>高級系統設置>>環境變量>>系統變量>>Path>>編輯>> 變量值中添加 %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem; 即可。轉載于:https://www.cnblogs.com/ZCrystal/p/10894591.html

轉載 vue的基礎使用

轉載https://www.cnblogs.com/majj/p/9957597.html#top vue的介紹 前端框架和庫的區別nodejs的簡單使用vue的起步指令系統組件的使用過濾器的使用watch和computed鉤子函數漸進式的JavaScript框架 vue react angualr作者:尤雨溪 facebook 谷歌公…