最近在用 Vue 开发项目,偶然间发现了vitejs这个库,它在开发环境中使用原生 ES 模块标准引入 js 文件,这让我眼前一亮,本身我就对前端标准的发展十分感兴趣,所以就阅读了一下文档。
在文档中作者提到 vitejs 与Snowpack的区别,于是顺藤摸瓜,点亮了新技能。
更快的前端构建工具
Snowpack 在开发环境中使用原生 ES 模块代替以往的打包方式,每一个文件只需要构建一次并缓存,当某个文件改变时 Snowpack 只会重新构建这个被改动的文件并通过模块热替换(HMR)技术更新变更。
在生产环境打包时,Snowpack 可以集成其他打包工具,比如 Webpack。
关键功能
更快的开发速度,开发服务器可以在 50ms 以内启动
利用模块热替换(HMR)技术,代码的变更可以更快的在浏览器中体现出来
在打包生产环境时,可以结合其他类似 Webpack 这样的打包工具使用
内置了对 TypeScript,JSX,CSS Module 等功能,开箱即用
提供插件的方式提供对类似 Babel,Vue 等第三方库的支持
Talk is cheap, Show me the Code
废话不多说,直接上代码
Create Snowpack App(CSA)
Snowpack 提供了多种模版以帮助我们快速初始化一个项目
# using npm
npx create-snowpack-app new-dir --template [SELECT FROM BELOW] [--use-yarn]
# using yarn
yarn create snowpack-app new-dir --template [SELECT FROM BELOW] [--use-yarn]
复制代码
这里我们以 react 模板为例使用 CSA 创建项目
$ yarn create snowpack-app snowpack-react --template @snowpack/app-template-react-typescript
yarn create v1.15.2
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Installed "create-snowpack-app@1.8.7" with binaries:
- create-snowpack-app
[####################################################################] 68/68
- Using template @snowpack/app-template-react
- Creating a new project in /Users/eddy/Documents/workspace/snowpack-react
(node:28212) ExperimentalWarning: The fs.promises API is experimental
- Installing package dependencies. This might take a couple of minutes.
> esbuild@0.8.8 postinstall /Users/eddy/Documents/workspace/snowpack-react/node_modules/esbuild
> node install.js
added 254 packages from 195 contributors in 116.409s
- Initializing git repo.
- Success!
Quickstart:
cd snowpack-react
npm start
All Commands:
npm install Install your dependencies. (We already ran this one for you!)
npm start Start your development server.
npm run build Build your website for production.
npm test Run your tests.
✨ Done in 307.33s.
复制代码
除了 react 模版,Snowpack 还提供了其他模板
@snowpack/app-template-blank
@snowpack/app-template-blank-typescript
@snowpack/app-template-minimal
@snowpack/app-template-react
@snowpack/app-template-react-typescript
@snowpack/app-template-preact
@snowpack/app-template-svelte
@snowpack/app-template-vue
@snowpack/app-template-lit-element
@snowpack/app-template-lit-element-typescript
@snowpack/app-template-11ty
See all community templates
运行
安装成功以后,我们启动本地调试服务器
cd snowpack-react
npm start
复制代码
第一次启动非常快,在启动调试服务器的同时,我们还发现 Snowpack 会将 react 和 react-dom 两个库构建成单独的文件。
snowpack
http://localhost:8080 • http://192.168.2.9:8080
Server started.
▼ Console
[snowpack] installing dependencies...
[snowpack] ✔ install complete! [3.92s]
[snowpack]
⦿ web_modules/ size gzip brotli
├─ react-dom.js 926.73 KB 212.76 KB 0 KB
└─ react.js 1.57 KB 0.51 KB 0 KB
⦿ web_modules/common/ (Shared)
└─ index-9e52bee1.js 74.58 KB 20.27 KB 0 KB
复制代码
第二次启动服务器时,启动时间更短了.
snowpack
http://localhost:8080 • http://192.168.2.9:8080 • http://10.122.0.194:8080
Server started in 33ms.
复制代码
打开调试工具中的网络面板,我们发现源代码中的文件被构建成一个个独立的文件
而 react 和 react-dom 通过 Snowpack 的构建,可以直接以 ES 模块的方式加载。
核心概念
Snowpack 的核心概念很纯粹,不需要打包的开发模式。
不打包开发模式指文件被 Babel,TypeScript 和 Sass 等工具构建后以原生 ES 模块的方式独立的被浏览器加载。任何文件的变更都只会引起单个文件的重新构建。
不打包的开发模式有如下几点好处:
更快速的构建
更明确的构建目标
更容易调试
项目体量变大不会影响开发速度
文件被独立的缓存
每一个文件都被单独的构建和缓存。在开发环境中直到文件被改变前,每个文件只会被构建和下载一次。
这里我们在源代码中新增一个名为 Helloworld 的组件,并在 App.tsx 中使用,然后修改 Helloworld 组件中的代码。
我们发现只有组件本身被浏览器重新加载。相比较过往的重新打包构建方式,这样做十分高效。
生产环境构建
运行命令 yarn build.
$ yarn build
yarn run v1.15.2
$ snowpack build
(node:63681) ExperimentalWarning: The fs.promises API is experimental
[snowpack] ! building source…
[snowpack] ✔ build complete [0.07s]
[snowpack] installing dependencies...
[snowpack] ✔ install complete! [0.92s]
[snowpack]
⦿ web_modules/ size gzip brotli
├─ react-dom.js 127.47 KB 40.94 KB 0 KB
└─ react.js 0.22 KB 0.13 KB 0 KB
⦿ web_modules/common/ (Shared)
└─ index-e66f0a38.js 8.99 KB 3.54 KB 0 KB
[snowpack] ! verifying build...
[snowpack] ✔ verification complete
[snowpack] ! writing build to disk...
[snowpack] ✔ build complete [0.07s]
[snowpack] ▶ Build Complete!
✨ Done in 5.54s.
复制代码
会在项目目录中生成 build 目录,我们发现 Snowpack 默认的生产环境构建与开发环境相同,并没有打包的功能。
但通过安装 Snowpack 官方提供的 webpack 插件 @snowpack/plugin-webpack 就可以快速的与 Webpack 集成。再次构建时得到打包后的结果。
$ npm run build
> @ build /Users/eddy/Documents/workspace/snowpack-react
> snowpack build
[snowpack] ! building source…
[snowpack] ✔ build complete [0.07s]
[snowpack] installing dependencies...
[snowpack] ✔ install complete! [1.33s]
[snowpack]
⦿ web_modules/ size gzip brotli
├─ react-dom.js 127.47 KB 40.93 KB 35.99 KB
└─ react.js 0.22 KB 0.13 KB 0.11 KB
⦿ web_modules/common/ (Shared)
└─ index-e66f0a38.js 8.99 KB 3.54 KB 3.16 KB
[snowpack] ! verifying build...
[snowpack] ✔ verification complete
[snowpack] ! writing build to disk...
[snowpack] ✔ build complete [0.07s]
Asset Size Chunks Chunk Names
assets/logo-d264c5adf9650c78ea3f951b10fb965a.svg 2.27 KiB [emitted] [immutable]
css/commons.5e7507eb870db869e404.css 855 bytes 0 [emitted] [immutable] commons
js/commons.2176d02c5f58391fdef3.js 146 KiB 0 [emitted] [immutable] commons
js/commons.2176d02c5f58391fdef3.js.LICENSE.txt 51 bytes [emitted]
js/index.86114b711cd75fab8af8.js 72 bytes 1 [emitted] [immutable] index
js/webpack-runtime.21710be6279059296bda.js 1.46 KiB 2 [emitted] [immutable] webpack-runtime
[snowpack] ▶ Build Complete!
复制代码
功能
Snowpack 内置了对如下文件类型的支持:
JavaScript(.js,.mjs)
TypeScript(.ts,.tsx)
JSX(.jsx,.tsx)
CSS(.css)
CSS Modules(.module.css)
Images(.svg,.png,.jpg,等)
加载别名
// Instead of this:
import Button from `../../../../components/Button`;
// You can do this:
import Button from `@app/components/Button`;
复制代码
通过在 Snowpack配置文件中对别名的配置可以实现以别名的方式代替文件路径。
TypeScript 用户则通过 ts.config.json 配置文件中的paths配置。
环境变量
// `import.meta.env` - Read process.env variables in your web app
fetch(`${import.meta.env.SNOWPACK_PUBLIC_API_URL}/users`).then(...)
// Supports destructuring as well:
const {SNOWPACK_PUBLIC_API_URL} = import.meta.env;
fetch(`${SNOWPACK_PUBLIC_API_URL}/users`).then(...)
// Instead of `import.meta.env.NODE_ENV` use `import.meta.env.MODE`
if (import.meta.env.MODE === 'development') {
// ...
复制代码
import.meta.env 与过往的 process.env 行为相似,但从安全的角度考虑 Snowpack 只支持以 SNOWPACK_PUBLIC_*开头的环境变量。
可以通过 @snowpack/plugin-dotenv 插件可以实现以环境变量文件的方式设置环境变量,README。
热重载
热重载(Hot Module Replacement HMR)是一种以非刷新页面的方式更新 Web 应用的技术。
Snowpack 支持包括 CSS、CSS Modules 和 JSON 在内的 HMR。
不使用 CSA 的情况下可以使用一些插件或几行代码
请求代理
// snowpack.config.json
// Example: Proxy "/api/pokemon/ditto" -> "https://pokeapi.co/api/v2/pokemon/ditto"
{
"proxy": {
"/api": "https://pokeapi.co/api/v2",
}
}
复制代码
CSS Imports (@import)
/* Import a local CSS file */
@import './style1.css';
/* Import a local Sass file (Sass build plugin still needed to compile file contents) */
@import './style2.scss';
/* Import a package CSS file */
@import 'bootstrap/dist/css/bootstrap.css';
复制代码
Snowpack 支持原生@import语法
更多 Snowpack 功能可参见Snowpack features
插件
Snowpack 不仅是 JavaScript 的构建工具,还是整个网站的构建工具。 Babel,TypeScript,PostCSS,SVGR 和任何喜欢的构建工具都可以通过 1 行插件的方式直接连接到 Snowpack。
使用新的语言/框架支持(Svelte,Vue)自定义构建
使用新的构建工具(Babel,PostCSS)自定义构建
在构建和开发过程中运行 CLI 命令(TypeScript,ESLint)
创建项目特殊的自定义转换。
总结
随着浏览器的不断发展,越来越多的标准得以被实现,这些标准提高了前端开发的生产力。Snowpack 建立在 ECMAScript 中模块化标准的原生实现,让我们可以在开发环境中更加高效的调试前端工程。
评论