https://juejin.im/post/5e4c0357f265da570b3f25f2
引言
前幾天聽一個朋友說到 snowpack, 便去去看了下這個包是幹什麼的,看了下官網,發現這個東西還是蠻有意思的。號稱 無需打包工具(Webpack,Parcel)便能將代碼結果實時展現在瀏覽器中。可以先看以下的圖,是不是很誘人?
snowpack 以 ES Modules 為主,如果對 ES Modules 不熟悉的朋友,請先查看我的上一篇文章。
為什麼使用 snowpack
在 ESM 出現之前,JavaScript 的模塊化就有各式各樣的規範,主要有 CommonJS, AMD, CMD, UMD 等規範,最為廣泛的就是 Node.js 的 CommonJS,使用 module.exports 和 require 來導出導入模塊,它是 npm 中的模塊最主要提供的格式。由於瀏覽器並不直接支持這些模塊,因此打包工具(Webpack,Browserify,Parcel 等)出現了。
- 在開發過程中你是否遇到 webapp 總是需要等待才能看到結果,每次保存後電腦就非常瘋狂。
- webpack 之類的打包工具功能非常強大,他們引入配置,插件,依賴成本很低,任意創建一個 react 應用便將要安裝 200M 的依賴包,並且需要寫很多行的webpack配置。
- ESM在瀏覽器中使用了大約5年的時間,現在在所有現代瀏覽器中都受支持(可追溯到2018年初)。使用ESM,不再需要打包工具。您可以在沒有 Webpack 的情況下構建一個現代化,高性能,可用於生產的Web應用程序!
- 你只需安裝運行一次 snowpack 替換 Webpack,Parcel等繁雜的打包工具,可以獲得更快的開發環境,並減少工具複雜性。
環境支持
由於默認情況下,snowpack將npm依賴項安裝為ES模塊(ESM),那麼 ES 模塊的支持情況怎麼樣了呢?
不用擔心,目前使用的90%的瀏覽器都支持 ESM 語法。自2018年初以來,所有現代瀏覽器(Firefox、Chrome、Edge、Safari)都支持ESM。
示例
需要環境: Node 10 +
基礎
說了這麼多,就是說方便唄。那麼我來實際操作一下。
先以一個 react 項目為例
<code>mkdir snowpack-demo
cd snowpack-demo
npm init -y
複製代碼/<code>
安裝依賴
<code>npm i @babel/cli @babel/core @babel/preset-react servor snowpack -D
npm i react@npm:@pika/react react-dom@npm:@pika/react-dom -S
複製代碼/<code>
<code>// src/index.js
import React, { useState } from "react";
import ReactDOM from "react-dom";
function App() {
return (
hello world
);
}
window.addEventListener("load", () =>
ReactDOM.render(, document.getElementById("app"))
);
複製代碼/<code>
<code>
複製代碼/<code>
<code>npx snowpack
babel src/ --out-dir dist
npx servor --reload
複製代碼/<code>
打開 http://localhost:8080
進階
使用 css
由於瀏覽器不支持直接使用 JS 導入 CSS, 因此以下代碼無法使用。
<code>// ✘ NOT SUPPORTED OUTSIDE OF BUNDLERS
import './style.css';
複製代碼/<code>
如果想要引入css, 需要通過 style 標籤直接引入資源。
官方推薦的使用方式是
- 簡單應用,使用內斂 style
- 複雜應用推薦使用 CSS-in-JS
因此這裡採用 styled-components
<code>npm i styled-components -S
npx snowpack
複製代碼/<code>
修改 index.js
<code>import React, { useState } from "react";
import ReactDOM from "react-dom";
import styled from 'styled-components';
const UI = styled.div`
color: red
`
function App() {
return (
hello world
);
}
window.addEventListener("load", () =>
ReactDOM.render(, document.getElementById("app"))
);
複製代碼/<code>
修改下 package.json
<code>"start": "babel src/ --out-dir dist --watch & servor --reload"
複製代碼/<code>
<code>npm run start
複製代碼/<code>
使用圖片
<code>// ✘ NOT SUPPORTED OUTSIDE OF BUNDLERS
import './photo.png';
複製代碼/<code>
如今,沒有瀏覽器支持直接從JS導入圖像。 相反,您將要使用以下庫/解決方案之一:
使用TypeScript
<code>npm i @babel/preset-typescript typescript -D
複製代碼/<code>
修改 .babelrc
<code>{
"presets": ["@babel/preset-react", "@babel/preset-typescript"],
"plugins": [
"snowpack/assets/babel-plugin.js"
]
}
複製代碼/<code>
將 src/index 修改成 src/index.tsx 並加入聲明。
<code>import React, { useState } from "react";
import ReactDOM from "react-dom";
import styled, { ThemeProvider } from 'styled-components';
const ThemeColor = {
default: 'red'
}
interface Theme {
themeColor: typeof ThemeColor
}
const UI = ({ children }: { children?: React.ReactNode }) => {
return (
<>
<themeprovider>{children}/<themeprovider>
>
);
};
const AppStyle = styled.div<theme>((props: Theme) => {
console.log(props);
return {
color: props.theme.default
}
})
function App() {
return (
<appstyle>
hello world
/<appstyle>
);
}
window.addEventListener("load", () =>
ReactDOM.render(, document.getElementById("app"))
);
複製代碼/<theme>/<code>
修改 啟動命令,讓 babel 包含對 後綴 tsx 的轉義。
<code>{
"start": "babel src/ --out-dir dist --watch --extensions \".ts,.tsx,.js,.jsx\" & servor --reload"
}
複製代碼/<code>
優化
默認情況下,snowpack會安裝最小化的依賴關係並針對開發進行了優化。 準備好進行生產時,請使用--optimize標誌運行snowpack以啟用某些僅針對生產的優化:
- 最小化依賴關係
- 轉義低級語法
- Tree-Shaking(通過--include啟動自動模式)
- 支持舊版瀏覽 --nomodule
如果要構建單頁應用程序(SPA),請使用--nomodule運行snowpack並傳入應用程序入口點。 然後,在你的應用程序中創建第二個腳本標籤,帶有nomodule 標識的入口。
<code>
複製代碼/<code>
完成此操作後,運行snowpack生成一個/web_modules/app.nomodule.js腳本,這個腳本會自動在舊的舊版瀏覽器上運行。
緩存處理
通過傳入 addVersion
<code>/* .babelrc */
"plugins": [
["snowpack/assets/babel-plugin.js", {"addVersion": true}],
]
複製代碼/<code>
可以輸出帶有版本號的腳本
<code>// src/ File Input
import Foo from 'package-name';
// lib/ Babel Output
import Foo from '/web_modules/package-name.js?v=1.2.3';
複製代碼/<code>
結尾
snowpack 優勢
- 減少了打包的時間成本,只要一次 snowpack。修改源碼能夠實時反饋在瀏覽器上。
- 代碼可移植能力強,相當於純寫 JavaScript 語言。
- 模塊和源碼相互獨立,有點類似於 webpack 的 DDL。
- 對於簡單應用可以快速搭建,對於一些在線編輯的網站可以使用類似的方案進行構建。
snowpack 劣勢
- 對 ES Modules 的依賴性強,在npm 上雖然 ES Modules 的包在逐漸增加,但是短期內需要包都需要做額外的處理。例如我想引入 Antd, 發現其中依賴了很多 CommonJS 的模塊以及樣式未使用 CSS-in-JS, 引入較為繁瑣。
- 對於一些 css,images 資源處理不夠友好,需要額外手動處理,並且底層使用 rollup 來進行一次 ES Modules 的導出太過於生硬, 沒有強大的自定義的插件或者配置。
- 太多依賴包會造成網絡問題
以上例子: https://github.com/hua1995116/snowpack-demo
對於現階段的 snowpack 來說還是太年輕,但是年輕總是充滿希望和可能。
閱讀更多 GIS在線 的文章