在2021年11月20日,Svelte 召開了第四次虛擬會議。
而會議中最令我眼前一新的當然是 輪子哥 Rich-Harris 帶來的 Svelte Cubed 了。
科普:輪子哥 Rich-Harris:Svelte、Rollup 作者
這個專案亮眼的地方,並不是因為其他的演講者不好,也並不是因為輪子哥是 Svelte 作者的原因。而是因為他帶來的 Svelte-Cubed 和我目前在公司負責專案的技術棧有非常相似的感覺。在公司由於需要開發一個 新 的 H5 專案,因此我採用了較為激進的 Svelte + Aframe/Three.js + Tailwind.css + Vite 的組合。整套組合下來,無論是開發體驗還是最後生產包的體積都非常的美妙~ 因此當我看到 輪子哥釋出這個 新輪子 的時候,我無比激動,居然把我想要的組合直接整合到了 Svelte 。
然後我們來看看 Svelte-Cubed 面貌:
開啟 https://svelte-cubed.vercel.app/ ,目前官網沒有用自定義的域名,直接用了 vercel 的域名,猜測和 輪子哥去了 vercel 工作有關係。
我們來看看 cubed 官方的一些示例:
實戰
我們來嘗試一下自己寫一個專案,首先初始化一個 svelte 專案
npm init svelte@next my-new-app
cd my-new-app
npm install
npm run dev
安裝 Three.js 和 svelte-cubed
npm install three svelte-cubed
如果使用 TypeScript ,還需要引入 Three.js 的 ts 宣告
npm install -D @types/three
開啟 src/routes/index.svelte
<script>
import * as THREE from 'three';
import * as SC from 'svelte-cubed';
</script>
<SC.Canvas>
<SC.Mesh geometry={new THREE.BoxGeometry()} />
<SC.PerspectiveCamera position={[1, 1, 3]} />
</SC.Canvas>
然後執行 npm run dev
然後就報錯了,通過查詢,大概是因為沒有設定一個 vite 選項。
開啟 svelte.config.js
,加入關旭 vite ssr 的選項即可解決。
import adapter from '@sveltejs/adapter-auto';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
adapter: adapter(),
// hydrate the <div id="svelte"> element in src/app.html
target: '#svelte',
vite: {
ssr: {
noExternal: ["three"]
}
}
}
};
export default config;
我們的專案就被執行起來了。
官方也明確說了,不會對 Three.js 物件進行包裝,而是直接使用 Three.js 去建立並設定物件,因此需要在程式碼中引入 Three.js ,(個人感覺這樣的好處是能夠讓我們沒有成本地從其他非資料驅動的 Three.js 專案中,遷移到 Svelte-cubed 中)。
可以看到如果用 純 Three.js 去寫程式碼,將會比用 Svelte-Cubed
多出好幾倍的內容。隨著時間的推移,命令式程式碼也會變得不太容易維護。
通過新增控制器,我們可以輕鬆進行互動。
開啟 src/routes/index.svelte
<SC.Canvas antialias background={new THREE.Color('papayawhip')}>
<SC.Mesh geometry={new THREE.BoxGeometry()} />
<SC.PerspectiveCamera position={[1, 1, 3]} />
+ <SC.OrbitControls enableZoom={false} />
</SC.Canvas>
利用 Svelte 的資料驅動輕鬆修改 Three.js Objects.
<script>
import * as THREE from 'three';
import * as SC from 'svelte-cubed';
+
+ let width = 1;
+ let height = 1;
+ let depth = 1;
</script>
<SC.Canvas antialias background={new THREE.Color('papayawhip')}>
<SC.Mesh
geometry={new THREE.BoxGeometry()}
material={new THREE.MeshStandardMaterial({ color: 0xff3e00 })}
+ scale={[width, height, depth]}
/>
<SC.PerspectiveCamera position={[1, 1, 3]} />
<SC.OrbitControls enableZoom={false} />
<SC.AmbientLight intensity={0.6} />
<SC.DirectionalLight intensity={0.6} position={[-2, 3, 2]} />
</SC.Canvas>
+<div class="controls">
+ <label><input type="range" bind:value={width} min={0.1} max={3} step={0.1} /> width</label>
+ <label><input type="range" bind:value={height} min={0.1} max={3} step={0.1} /> height</label>
+ <label><input type="range" bind:value={depth} min={0.1} max={3} step={0.1} /> depth</label>
+</div>
+
+<style>
+ .controls {
+ position: absolute;
+ }
+</style>
利用資料驅動,動畫也可以快速新增。
<script>
import * as THREE from 'three';
import * as SC from 'svelte-cubed';
let width = 1;
let height = 1;
let depth = 1;
+
+ let spin = 0;
+
+ SC.onFrame(() => {
+ spin += 0.01;
+ });
</script>
<SC.Canvas antialias background={new THREE.Color('papayawhip')}>
<SC.Mesh
geometry={new THREE.BoxGeometry()}
material={new THREE.MeshStandardMaterial({ color: 0xff3e00 })}
scale={[width, height, depth]}
+ rotation={[0, spin, 0]}
/>
<SC.PerspectiveCamera position={[1, 1, 3]} />
<SC.OrbitControls enableZoom={false} />
<SC.AmbientLight intensity={0.6} />
<SC.DirectionalLight intensity={0.6} position={[-2, 3, 2]} />
</SC.Canvas>
總結
不過隨著 Svelte-Cubed 的釋出,也有不少的質疑,也有人認為這個東西並沒有是真正意義上的"創造新事物",而只是編寫了一些膠水層程式碼。
RH 也親自進行了回覆
簡而言之,你使用Svelte Cubed的原因與你使用Svelte(或任何元件框架)本身的原因相同:宣告性程式碼往往比指令性程式碼更健壯、更易讀、更易維護。
直接使用Three絕對沒有錯,但這相當於直接使用DOM。在某種程度上,很難跟蹤沒有被表達為層次結構的層次關係,而且管理整個應用程式的狀態也成為一種負擔。此外,由於元件有一個可管理的生命週期,如果你使用Vite(或使用Vite的SvelteKit)這樣的框架,你可以 "免費 "獲得熱模組過載這樣的東西。一旦你嘗試過用這種方式構建場景(例如,在你調整你所放大的物體的屬性時保持你的相機位置),Cmd-R驅動的開發就會感覺很蒼白了。 ——由 deepl.com 翻譯
額外說明:宣告式與函式式的區別,建立 div為例:
1.宣告式寫法<div></div>
2.函式式寫法 document.createElement('div');
不過個人感覺,Svelte-Cubed 帶來了以下優點
1.宣告式帶來的層級清晰
2.資料驅動能夠帶來遍歷(寫起來比 Three.js 快很多)
3.元件沒有非常龐大的情況下,它的體積還非常的小(相比 React、Vue 需要引入一整個執行時就小很多)
既然 Svelte-Cubed 已經融合了 Three.js ,在 meta 概念崛起的年代,離 VR/AR 還會遠嗎?(事實上只要融合了 Three.js ,使用 Three.js 的生態來寫 VR 就已經非常容易了)
最後再列幾個在VR/AR 領域比較優秀的框架吧(如果大家對這方面感興趣),aframe(與 Svelte 異曲同工之妙的宣告式),react-three-fiber、babylon.js 。
參考
https://twitter.com/opensas/s...
https://twitter.com/SvelteSoc...
https://svelte-cubed.vercel.a...
https://github.com/Rich-Harri...
https://news.ycombinator.com/...
結語
❤️關注+點贊+收藏+評論+轉發❤️ ,原創不易,鼓勵筆者創作更好的文章
關注公眾號秋風的筆記
,一個專注於前端面試、工程化、開源的前端公眾號