A. webpack作者評價vite
評價:Vite 是 vue 的作者尤雨溪在開發 vue3.0 的時候開發的一個 基於原生ES-Mole的前端構建工具。其本人在後來對 vue3 的宣傳中對自己的新作品 Vite 贊不絕口,並表示自己 」再也回不去 webpack 了「 。
webpack缺點是緩慢的伺服器啟動
當冷啟動開發伺服器時,基於打包器的方式是在提供服務前去急切地抓取和構建你的整個應用。
vite改進
Vite 通過在一開始將應用中的模塊區分為依賴和源碼兩類,改進了開發伺服器啟動時間。
依賴大多為純JavaScript並在開發時不會變動。一些較大的依賴(例如有上百個模塊的組件庫)處理的代價也很高。依賴也通常會以某些方式(例如 ESM 或者 CommonJS)被拆分到大量小模塊中。
Vite 將會使用 esbuild 預構建依賴。Esbuild 使用 Go 編寫,並且比以 JavaScript 編寫的打包器預構建依賴快10-100倍。
源碼通常包含一些並非直接是 JavaScript 的文件,需要轉換(例如 JSX,CSS 或者 Vue/Svelte 組件),時常會被編輯。同時,並不是所有的源碼都需要同時被載入。(例如基於路由拆分的代碼模塊)。
Vite以原生ESM方式服務源碼。這實際上是讓瀏覽器接管了打包程序的部分工作:Vite 只需要在瀏覽器請求源碼時進行轉換並按需提供源碼。根據情景動態導入的代碼,即只在當前屏幕上實際使用時才會被處理。
webpack: 分析依賴=> 編譯打包=> 交給本地伺服器進行渲染。首先分析各個模塊之間的依賴,然後進行打包,在啟動webpack-dev-server,請求伺服器時,直接顯示打包結果。
webpack打包之後存在的問題:隨著模塊的增多,會造成打出的 bundle 體積過大,進而會造成熱更新速度明顯拖慢。
vite: 啟動伺服器=> 請求模塊時按需動態編譯顯示。是先啟動開發伺服器,請求某個模塊時再對該模塊進行實時編譯,因為現代游覽器本身支持ES-Mole,所以會自動向依賴的Mole發出請求。
所以vite就將開發環境下的模塊文件作為瀏覽器的執行文件,而不是像webpack進行打包後交給本地伺服器。
分析了webpack和vite的打包方式後,也就明白了為什麼vite比webpack打包快,因為它在啟動的時候不需要打包,所以不用分析模塊與模塊之間的依賴關系,不用進行編譯。這種方式就類似於我們在使用某個UI框架的時候,可以對其進行按需載入。
熱更新方面,效率更高。當改動了某個模塊的時候,也只用讓瀏覽器重新請求該模塊,不需要像webpack那樣將模塊以及模塊依賴的模塊全部編譯一次。
B. 什麼是vue
Vue.js是一個構建數據驅動的 web 界面的漸進式框架,是一個JavaScript MVVM庫。Vue.js 的目標是通過盡可能簡單的 API 實現響應的數據綁定和組合的視圖組件。
與其他重量級框架不同的是,Vue 採用自底向上增量開發的設計。Vue 的核心庫只關注視圖層,並且非常容易學習,非常容易與其它庫或已有項目整合。另一方面,Vue 完全有能力驅動採用單文件組件和Vue生態系統支持的庫開發的復雜單頁應用。
C. vue和react為什麼運行時和編譯時
運行時與編譯時是前端工程師常常聽到的兩個詞。
比如 Vue 運行時、Angular 運行時、React 運行時……
又比如 svelte 框架,總聽到他的宣傳說的是「0 運行時」,所以他的工作其實就是在「編譯時」了。
這兩個詞到底是什麼意思呢?
D. 建設svelte生態靠大家
基於開源項目 svelma 擴展和修改, 所以在此感謝原作者 c0bra 以及 bulma , svelte 等團隊.
原項目組件比較少,存在一些小bug,所以我在在原有的組件庫的基礎上,擴展了一些常見的組件(例如時間,日期選擇器,仿antd的layout布局,分頁,等等),並對發現的一些bug進行了修改,對原有的組件功能,事件以及用戶配置進行更人性化的修改和擴展。
文檔及Demo
https://github.com/sveltejs/template 是一個svelte的初始化模板. degit 這個腳手架可以幫你獲取它:(PS: Rich-Harris 大神被稱為前端輪子哥果然是有有道理的,svelte,rollup,degit都是他的手筆)
因為組件使用sass模板,所以也集成一下sass的編譯.
在你的rollup或者webpack配置文件中添加scss支持:
在你的主HTML配置CDN頁面:
...或者通過npm包:
E. Svelte的UI組件庫
地址: https://sveltematerialui.com/
Material: 谷歌出品的扁平化風格。
地址: https://carbon-components-svelte.onrender.com/
Carbon:IBM 開源設計。
地址: https://carbon-svelte.vercel.app/
Smelte:Google Material Design 在 Svelte 和 Tailwind 上的另一實現。
地址: https://docs.svelteit.dev/
Svelteit: 簡約的 UI/UX 組件庫。
地址: https://illright.github.io/attractions/
Attractions: 時尚且實用。
F. 如何看待 svelte 這個前端框架
這個框架的 API 設計是從 Ractive 那邊傳承過來的(自然跟 Vue 也非常像),但這不是重點。Svelte 的核心思想在於『通過靜態編譯減少框架運行時的代碼量』。舉例來說,當前的框架無論是 React Angular 還是 Vue,不管你怎麼編譯,使用的時候必然需要『引入』框架本身,也就是所謂的運行時 (runtime)。但是用 Svelte 就不一樣,一個 Svelte 組件編譯了以後,所有需要的運行時代碼都包含在裡面了,除了引入這個組件本身,你不需要再額外引入一個所謂的框架運行時!
當然,這不是說 Svelte 沒有運行時,但是出於兩個原因這個代價可以變得很小:
1. Svelte 的編譯風格是將模板編譯為命令式 (imperative) 的原生 DOM 操作。比如這段模板:
<a>{{ msg }}</a>
會被編譯成如下代碼:
function renderMainFragment ( root, component, target ) {
var a = document.createElement( 'a' );
var text = document.createTextNode( root.msg );
a.appendChild( text );
target.appendChild( a )
return {
update: function ( changed, root ) {
text.data = root.msg;
},
teardown: function ( detach ) {
if ( detach ) a.parentNode.removeChild( a );
}
};
}
可以看到,跟基於 Virtual DOM 的框架相比,這樣的輸出不需要 Virtual DOM 的 diff/patch 操作,自然可以省去大量代碼,同時,性能上也和 vanilla JS 相差無幾(僅就這個簡單示例而言),內存佔用更是極佳。這個思路其實並不是它首創,之前有一個性能爆表的模板引擎 Monkberry.js 也是這樣實現的,ng2 的模板編譯其實也跟這個很類似(但是中間加了一層渲染抽象層)。
2. 對於特定功能,Svelte 依然有對應的運行時代碼,比如組件邏輯,if/else 切換邏輯,循環邏輯等等... 但它在編譯時,如果一個功能沒用到,對應的代碼就根本不會被編譯到結果里去。這就好像用 Babel 的時候沒有用到的功能的 helper 是不會被引入的,又好像用 lodash 或者 RxJS 的時候只選擇性地引入對應的函數。
基於這兩個特點,Svelte 應用的最終代碼量可以非常小。比如它的 TodoMVC min+gzip 之後只有 3kb。
但是,Svelte 也不是沒有它的潛在問題:
1. 雖然在簡單的 demo 裡面代碼量確實非常小,但同樣的組件模板,這樣的 imperative 操作生成的代碼量會比 vdom 渲染函數要大,多個組件中會有很多重復的代碼(雖然 gzip 時候可以緩解,但 parse 和 evaluate 是免不了的)。項目里的組件越多,代碼量的差異就會逐漸縮小。同時,使用的功能越多,Svelte 要包含的運行時代碼也越多,最終在實際生產項目中能有多少尺寸優勢,其實很難說。
2. Svelte 在大型應用中的性能還有待觀察,尤其是在大量動態內容和嵌套組件的情況下。它的更新策略決定了它也需要類似 React 的 shouldComponentUpdate 的機制來防止過度更新。另一方面,其性能優勢比起現在的主流框架並不是質的區別,現在大部分主流框架的性能都可以做到 vanilla js 的 1.2~1.5 倍慢,基於 Virtual DOM 的 Inferno 更是接近原生,證明了 Virtual DOM 這個方向理論上的可能性,所以可以預見以後 web 的性能瓶頸更多是 DOM 本身而不是框架。
3. Svelte 的編譯策略決定了它跟 Virtual DOM 絕緣(渲染函數由於其動態性,無法像模板那樣可以被可靠地靜態分析),也就享受不到 Virtual DOM 帶來的諸多好處,比如基於 render function 的組件的強大抽象能力,基於 vdom 做測試,服務端/原生渲染親和性等等。這一點在我看來比較關鍵。讓我在一點點性能和 Virtual DOM 之間做抉擇的話,我還是會選擇 Virtual DOM。
最後,我個人覺得 Svelte 最具有優勢的地方,就是用來編譯可獨立分發的 Web Components。傳統框架和 Web Components 結合最大的問題就在於運行時:單獨分發的 WC 裡面直接打包框架運行時顯然不現實,不打包的話,又做不到開箱即用。但 Svelte 就沒有這個問題,可以說是最適合這個用例的框架。
G. Svelte教程翻譯(七、存儲)
並非所有應用程序狀態都應用於程序的組件層次結構內。有時,您的值需要在多個不相關的組件或常規JavaScript模塊之間訪問。
在Svelte,我們通過存儲來做到這一點。 存儲只是一個帶有subscribe方法的對象,它允許在存儲值發生變化時進行同步操作。
在App.svelte中,count是一個存儲,我們在count.subscribe回調中設置了count_value。
stores.js文件中定義計數。它是一個可寫的存儲,這意味著它除了subscribe之外還有set和update方法。
Incrementer.svelte文件,編寫+按鈕組件事件代碼:
單擊+按鈕累加計數。而Decrementer.svelte文件中的代碼是進行遞減操作:
最後,在Resetter.svelte文件中,實現重置操作:
上一個示例中的應用程序可以工作,但有一個微妙的錯誤——存儲是subscribe狀態,但從未unsubscribe。如果組件被多次實例化和銷毀,這將導致內存泄漏。
首先在App.svelte中定義常量unsubscribe:
例如通過onDestroy生命周期銷毀
Svelte有一個技巧,可以通過在存儲名稱前加上$來引用store值:
完整代碼:
stores.js:
Incrementer.svelte:
Decrementer.svelte:
Resetter.svelte:
App.svelte:
並不是所有的存儲都應該由引用它們的人來寫。例如,您可能有一個表示滑鼠位置或用戶地理位置的存儲,並且不能從「外部」設置這些值。對於這些情況,我們創建可讀的存儲。
stores.js文件。readable的第一個參數是一個初始值,如果您還沒有初始值,則可以為null或undefined。第二個參數是一個start函數,它接受一個set回調並返回一個stop函數。當存儲獲得第一個subscribe時調用start函數;當最後一個unsubscribes時調用stop。
App.sevlte
您可以創建一個存儲,其值基於一個或多個具有派生屬性的其他存儲的值。在前面的示例的基礎上,我們可以創建一個存儲,它派生出一個計算頁面打開時間的函數:
stores.js
App.sevlte
只要對象正確實現subscribe方法,它就是一個存儲。除此之外,什麼都可以。因此,使用特定於域的邏輯創建自定義存儲非常容易。
例如,我們前面示例中的計數存儲可以包括遞增、遞減和重置方法,並避免外露set和update:
stores.js:
App.sevlte:
如果一個存儲是可寫的,即它有一個set方法,那麼可以綁定到它的值,就像綁定到本地組件一樣。
在本例中,我們有一個可寫的存儲name和一個派生的存儲greeting。更新 元素:
更改輸入值將更新name及其所有從屬項。
我們也可以直接賦值來存儲組件中的值。添加 元素:
Add exclamation mark!
$name+='!'賦值等價於name.set($name+'!')。
stores.js:
App.sevlte