:::

初探網頁前端框架Svelte / Preliminary Study of Svelte, a Front-end Framework

6-Svelte_Preliminary_Study_of_Svelte.png

最近嘗試摸索了號稱簡短程式碼就能運作網頁前端框架Svelte,一開始我的確為它的簡潔所吸引,嘗試架了一個Svelte專案來跑跑看。不過實際摸索後,若從開發大型複雜專案的角度來看,Svelte無法將腳本與樣式拆開成獨立檔案、也難以抽出額外的圖片檔案等不足,使得它仍然比不上Vue.js好用。

這篇先給大家準備一個我嘗試Svelte的試作專案,再來談談我對Svelte的使用感想。如果對Svelte有興趣的人,說不定也能基於我的試作專案再來改造,改善我對Svelte的批評呢。


網頁前端框架:Svelte / Front-end MVVM framework: Svelte

svelte_logo.png

(圖片來源:sveltejs/template-webpack)

Svelte是一個嶄新的使用者介面建構方案。跟React和Vue這種傳統的網頁前端MVVM框架不同,他們往往是在瀏覽器上建構應用程式,Svelte則是強調在編譯階段就建構好應用程式。

svelte_exampel.gif

(範例來源:Svelte)

而且Svelte希望建構一個不需要框架的框架(frameworks without framework),它可以用相當少的程式碼,以類似於原生JavaScript程式的方式開發,就能做到跟其他網頁前端框架類似的功能。它要撰寫的程式碼遠比其他框架少了許多。

此外,Svelte也不使用虛擬DOM(virtual DOM)差異化的技術,它認為虛擬DOM只是多餘的操作。Svelte做法更直接:變更DOM的內容,而在2018年AJ Meyghani的評測中,Svelte的效率跟其他框架相比也毫不遜色。因為Svelte更強調在編譯時期就建構應用程式,它的記憶體程度明顯比其他框架更少,對低階硬體來說更為友善。

Svelte雖然一般會被當作是網頁前端框架,但實際運作時,不能只靠瀏覽器就建構應用程式,必須搭配編譯器才行。以下我就準備一個試作專案,以此作為探索Svelte的起點吧。


試作專案 / Demonstration project

2019-0927-140920-Pull-requests-Issues-Marketplace.png

(網頁截圖:GitHub)

svelte_logo.png

(圖片來源:sveltejs/template-webpack)

一開始我本來打算照Svelte教的方式,從sveltejs/template範本來建立Svelte專案。不過我在第一個指令「npx degit sveltejs/template my-svelte-project」就卡住了,發生錯誤「! could not find commit hash for master」,看了下其他人對問題的討論,也沒找到合適的解法,最後索性找尋其他方案。

事後想想,這時候似乎只要直接分歧(fork)sveltejs/template範本,然後再複製(clone)分歧的專案到本機端來運作,這樣就可以了喔?

事後發現,執行「npx degit sveltejs/template my-svelte-project」卻發生錯誤「! could not find commit hash for master」的情況,這是因為電腦裡面沒有安裝Git所引起的問題。後來我安裝Git之後就能順利執行了

webpack_logo.png

(圖片來源:webpack)

總之,我還是換了另一個方案:基於使用Webpack來編譯Svelte的sveltejs/template-webpack。以這個專案為基底,因為我比較熟悉Webpack,很快就能編譯Svelte並且看到成果。除此之外,我還嘗試了以下功能:

如果你也想要試試看的話,可以用以下方法安裝這個範例。


環境配置 / Environment setup

初次使用之前,請先先執行一次環境配置。

程式語言環境 Node.js / Environment: Node.js

nodejslogo.png

(圖片來源:Codementor)

我目前Windows 7 64位元作業系統上運作的是Node.js v10.16.1。請確保你的電腦有安裝10版以上的Node.js。你也可以到以下網址下載Node.js:

版本控制 Git / Version control: Git

git.png

(圖片來源:TechBridge)

以下操作會用到版本控制Git。如果你有習慣操作的整合開發環境IDE,那它通常都已經內建了Git的功能,例如NetBeans的「Git合作開發從NetBeans開始!NetBeans複製git專案教學」。

此外,我也建議你在作業系統安裝好Git。畢竟Node.js裡面很多指令都會用到Git:

準備好Node.js跟Git之後,接下來就來處理專案吧。

複製儲存庫 / Clone repository

接下來我們要把位在GitHub上的保存庫pulipulichen/20190927-SvelteJS-Webpack-Test複製到你的本機端中。

請開啟你電腦的命令列,移動到合適的位置,然後執行以下指令:

git clone https://github.com/pulipulichen/20190927-SvelteJS-Webpack-Test.git

稍待片刻,就能順利將GitHub保存庫裡面的程式碼下載到你的電腦中,保存在「20190927-SvelteJS-Webpack-Test」資料夾裡面。

然後我們要移動到該目錄底下,請執行以下指令:

cd 20190927-SvelteJS-Webpack-Test

然後我們就進行下一步吧。

安裝套件Install packages

我們現在要移動到專案資料夾底下,並且安裝專案所需要的套件。

請開啟你電腦的命令列,並執行以下指令:

cd 20190927-SvelteJS-Webpack-Test
npm i

2019-0927-152759-ciwedoouowwyewdsw-je-TS-THe-ER-NTR.png

這樣子環境就配置好了。


啟動服務 / Start up service

現在我們要啟動Webpack,讓它編譯Svelte,並且運作測試用的伺服器。

請開啟你電腦的命令列,並執行以下指令:

npm run demo

2019-0927-152911-upn-LS-build-Built-at-PM-Size-Chunks.png

然後打開你的瀏覽器,進入以下網址:

http://localhost:8080/

2019-0927-153441-mm.png

這樣就表示整個專案順利運作了。

修改專案 / Try to modify svelte files

2019-0927-153534-io-amgH-Organize-opm-New-der-Be.png

Svelte程式碼都放在「src」資料夾底下。你可以嘗試修改這些檔案,網頁伺服器上會立刻顯示修改完的結果。

2019-0927-153350-EF-ppsvele-Notepads-EE-BEE-REO-WAY.png

舉例來說,我在App.svelte樣式設定<style>中,將h1標籤的顏色改成綠色(green),並儲存檔案。

2019-0927-153749-SUCHE-eoanea-localhost-TOT.png

回到瀏覽器來看,你會看到h1標籤的字體顏色立刻更新了。這種即時更新的效果就是Svelte熱重載(HotReload)的功能,我們就能自由修改Svelte程式,並立即檢視效果了。

附帶一提,如果程式寫錯的話,畫面會出現一片白喔。這時候我們可以在剛剛執行啟動服務的命令列裡面看看錯誤訊息。

到這裡為止,基本的Svelte已經可以正常運作了,我們也能自由修改想要的功能囉。


Svelte的使用感想 / Thoughts to Svelte

我之前幾個專案都是用Vue.js加上Webpack開發,現在摸索Svelte的時候,自然就會把它跟Vue.js來做比較。Svelte能夠做到Vue.js的許多功能,例如最基本的元件封裝和元件之間的資料交換。但Vue.js有些能協助大型專案開發的功能,卻是Svelte所欠缺的弱項。

以下先從強項的地方開始聊起,再來談談我覺得Svelte的不足之處。

強項 / Strength

2019-0927-155555-BE-Smw-uuy-MagcKoK-IGKoK-import.png

Svelte最大的特點就是「Write less code」,需要撰寫的程式碼更少了。相較於Vue.js要求特定架構,像是data、prop、methods等等,Svelte的寫法更為直覺。這樣子可以降低上手的門檻,也可避免很多拼錯字等低級錯誤。

要知道,我在Vue.js裡面常常把要寫在methods的方法寫到外面去,或是要新增一個變數時,還得找到data裡面設定,用起來欠缺彈性。這些問題不時困擾著我。

anime.gif

另一個強項就是即時熱重載(Hot Reload)的功能。理論上它並不是只是單純重新載入修改後的程式碼,而是可以保留現在程式運作的狀態,只更新我們改過的部分。不過實際上運作起來,好像還是會把整個網頁重新載入的樣子,不知道是我哪裡設定錯誤了。

老實說,熱重載並不是Svelte的獨門特色,理論上Vue.js應該也有熱重載的能力。但我之前研究了一陣子,並沒能在Webpack和Vue.js的組合下順利啟動熱重載。倒是NetBeans跟Chrome擴充套件搭配運作的LiveReload,就達到儲存時自動重新載入的效果。

弱項 / Weakness

雖然Svelte初期寫起來很容易上手,但是要開發的大型專案的話,許多不足之處就浮現出來了。

第一個問題是對於圖片檔案的整合。我們常常會在CSS或是HTML程式碼裡面用到圖片。在Webpack與Vue.js的組合中,我們可以把圖片抽取出來擺到其他地方、修改路徑,使得編譯完的檔案依然能夠順利連到該圖片。理論上換到Webpack跟Svelte之後,這件事情應該也要能夠順利運作,但我卻一直沒辦法成功。

當然,我們也可以乾脆就固定圖片的路徑,一開始就以編譯後的位置來設定路徑,這樣就能避免這個問題。因此這個問題仍算是小事。

第二個問題是樣式檔支援的語言。Svelte的樣式檔採用的是CSS,但我現在不太喜歡直接撰寫CSS語法,更偏好使用LESS。我試著找了一陣子,目前Svelte的樣式檔似乎還沒支援LESS,只能用最基本的CSS,搭配Svelte特有的語法來撰寫,但能夠提供的功能並不多。我看stackoverflowsvelte-loader有提到可以改用sass()的做法,不過還不確定這能不能用在LESS上。

當然,這也許是Svelte希望我們把每個組件都做得很小,小到用基本的CSS就能搞定了。這樣好或不好就是見仁見智,至少我還是比較喜歡用LESS來撰寫樣式。

第三個問題,也是目前我覺得比較麻煩的問題是,Svelte的邏輯腳本<script>、樣式<style>、HTML呈現的三個部分,目前仍不能拆開成獨立檔案。通常在開發比較複雜的專案時,我們需要來回比對邏輯腳本、樣式以及對應呈現之間的不同。如果只有一個檔案,那就得要拉動卷軸來回比對,或是要用能夠同時在不同視窗編輯同一個檔案的編輯器,實在是很麻煩。

如果能夠把各個部分從Svelte中獨立成單一檔案的話,另一個好處是,整合開發環境IDE更能夠瞭解該檔案的架構。例如我在撰寫Vue.js的時候,喜歡將LESS樣式的部分獨立成.less檔案,而NetBeans能夠理解LESS的語法,提供標亮、大綱導航與語法自動補完的功能,非常方便。相較之下,在同一個檔案,NetBeans就無法完全理解Svelte的寫法,只能把它當作普通的HTML來看。

最後一個問題是對於Svelte太過簡單的隱憂。我在撰寫Vue.js的時候,時常會用到一些Vue.js以外的JavaScript框架,例如Semantic UI。因為Vue.js會複寫Semantic UI付與元素的事件,所以最好的方法,是把這些額外框架所產生的元素與事件,與Vue.js框架區隔開來,然後用Vue.js額外做管理。這種做法是因為Vue.js有明確的寫法和範圍,所以我們可以做到這件事情。但Svelte這種簡潔的寫法,我就不太確定能不能如法炮製。


結語:Svelte仍有發展空間 / Conclusion: Svelte still needs to develop

2016年Svelte誕生,2018年4月18日發佈第二版,而目前最新的Svelte第三版則是於2019年4月22發佈。相較之下,Vue.js第一版於2014年2月發佈,React第一版於2013年發佈,Angular更是早在2010年就已經誕生。對比這些前端框架的老前輩們,Svelte有著年輕帶有的各種改革熱情,但也有許多不夠成熟的地方。

評估至此,我目前仍決定還是繼續使用Vue.js跟Webpack的組合。不過,如果有朝一日Svelte能夠解決上述問題和疑慮的話,我會非常樂意轉用Svelte來開發。畢竟Svelte所強調的Write less code特色,正是符合程式設計師的三大美德(three great virtues of a programmer)中的怠惰(Laziness)和不耐煩(Impatience)呢。


那麼這次對於Svelte的試作和看法就講到就到這裡了。寫到最後,我有些問題想問問大家:

  • 你用過那些網頁前端框架呢?Angular、React、Vue,還是其他的框架呢?
  • 你喜歡網頁前端框架的什麼特色呢?資料雙向綁定?組件化?還是其他特色呢?
  • 許多網頁前端框架都需要搭配編譯器或打包器,才能發揮它的最大能力。你通常是用什麼打包器呢?WebpackGulpParcel

歡迎在下面的留言處跟我們分享你的想法。大家的意見是我繼續分享的動力喔!如果你覺得我這篇實用的話,請幫我在AddThis分享工具按讚、將這篇分享到Facebook等社群媒體吧!

感謝你的耐心閱讀,我是布丁,讓我們下一篇見。

總共10 則留言 ( 我要發問 , 隱藏留言 顯示留言 )

  1. 目前使用人數似乎還不多,謝謝你的分享。

    回覆刪除
    回覆
    1. To appletest:

      商用產品大多不敢採用這種新興的框架,我想這是很正常的想法。
      有趣的是,我現在關注的Vue最新第3版中的function-based API,也帶了一些Svelte的味道
      https://kuro.tw/posts/2019/08/06/%E5%88%9D%E6%8E%A2-Vue-3-0-Function-based-API/

      可以確定的是,網頁前端框架的開發,應該會越來越朝向靈活、自由、扁平的方向演化
      早期那種需要瞭解大量框架規則才能進行開發的思維,已經逐漸退出潮流了

      刪除
    2. Vue3 的 function-based API 帶的是 React 的味道吧XD

      刪除
    3. 哈哈哈,暴露出我的膚淺了
      我還有很多要學的呢

      刪除
  2. 謝謝分享!我寫了一篇文章補充了一些觀點,歡迎指教~
    https://link.medium.com/scgsAcH7n6

    回覆刪除
    回覆
    1. To 愷開,

      你專業許多啊!! OAO
      我還沒到這個程度呢,佩服佩服

      刪除
  3. 我一直覺得有真正試著找出解決方法,並寫了project並再來寫評論會比較好,否則只是跑跑教學例子就將其視為理所當然,真的會如同瞎子摸象!! 簡單說明幾個文章不清楚點:
    1. Svelte 有svelte-preprocessor,可以處裡Sas, less, Babel.... 之類問題.
    2. Svelte 在整合UI framework (Bulma, Uikit....)不是問題,以我整合Bulma的經驗,比Vue方便太多. 有些問題是在Bundle tool而不在Svelte.
    3. Svelte 是強調Component Base, 就如同Object一般, 將<style, <script , html 合起來就是一component. 當你真正用Svelte,你會發現你根本不需要分開檔案,因為每個Component 都獨立而簡潔。 當然你如要真分開,svelte-preprocessor是可以做到的. 以我的經驗,還真的用不到.
    4. Svele真正的核心是讓事情單純化,但這不是簡單化! 它更不會為了解決問題而多了一些更複雜的架構。 所以它沒有React JSX,也沒有Vue 一堆method, v-... 和Virtual DOM. 以我的經驗,Planin JS 寫library或code(沒使用framework)都能與Svelte整合沒問題.
    5. 許多 IDE 都有Svelte的Plug-in. 例如VScode, jetBrains, Atom ... 都能理解Svelte的語法。 因我很久沒使用NetBean,但以我使用的VSode 和JetBrain的相關IDE tool都能完整支持Svelte語法。

    回覆刪除
    回覆
    1. 你好,

      真是專業的解說!
      下次有機會我再來嘗試看看Svelte。

      刪除
    2. 這個部落格就是超不專業 寫文章誤人子弟的== 各位真的要小心

      刪除