首页
学习
活动
专区
工具
TVP
发布

Snowpack - 更快的前端构建工具

最近在用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

运行

安装成功以后,我们启动本地调试服务器

  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中模块化标准的原生实现,让我们可以在开发环境中更加高效的调试前端工程。

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/9969140083b8f30509c69c573
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券