JS `Bundless` `Development` (无打包开发):Vite / Snowpack 的原理

嘿,大家好!今天咱们来聊聊前端开发里的一个“新”玩意儿,其实也不算新了,已经流行一段时间了,那就是“Bundless Development”,也就是“无打包开发”。主要说说 Vite 和 Snowpack 这两个家伙,看看它们是怎么做到“不打包”也能让你的代码飞起来的。

开场白:告别漫长的等待

相信大家都有过这样的经历:改了一行代码,保存,然后…漫长的等待,看着打包工具吭哧吭哧地把整个项目重新打包一遍。这种感觉就像明明只是想换个灯泡,结果要把整个房子重新装修一遍一样,效率低得令人发指。

传统的打包工具,比如 Webpack,Parcel,它们的工作方式是“先打包,后运行”。它们会分析你的代码,把所有的依赖关系整理好,然后把所有的模块打包成一个或多个文件,最后浏览器再加载这些文件。这种方式在项目小的时候还好,一旦项目变大,打包的时间就会变得非常长,严重影响开发效率。

而 Vite 和 Snowpack 就不一样了,它们采用了“按需编译”的策略,也就是“先运行,后编译”。它们不会在一开始就把所有的代码都打包好,而是当你需要某个模块的时候,才去编译它。这种方式可以大大减少打包的时间,让你的开发体验更加流畅。

第一章:传统打包工具的困境

要理解 Vite 和 Snowpack 的优势,我们首先要了解传统打包工具的瓶颈在哪里。

特性 传统打包工具 (Webpack, Parcel) Vite / Snowpack
打包方式 先打包,后运行 先运行,后编译
启动速度
热更新速度
适用场景 大型项目,生产环境 中小型项目,开发环境
  • 启动速度慢: 每次启动项目,都需要把所有的代码都打包一遍,这个过程非常耗时。
  • 热更新速度慢: 每次修改代码,都需要重新打包,即使只修改了一行代码,也需要等待很长时间才能看到效果。
  • 复杂度高: 配置复杂,学习成本高。Webpack 的配置简直就是一门玄学,各种 loader、plugin 让人眼花缭乱。

第二章:Vite:ESM 的妙用

Vite 的核心思想是利用浏览器原生的 ESM (ES Modules) 能力。ESM 是 JavaScript 的官方模块化标准,它允许我们在浏览器中直接使用 importexport 语法来加载和导出模块。

2.1 ESM 的基本用法

先来看个例子:

// moduleA.js
export function sayHello(name) {
  console.log(`Hello, ${name}!`);
}

// moduleB.js
import { sayHello } from './moduleA.js';

sayHello('Vite'); // 输出:Hello, Vite!

在浏览器中,我们可以这样加载 moduleB.js

<!DOCTYPE html>
<html>
<head>
  <title>Vite Example</title>
</head>
<body>
  <script type="module" src="./moduleB.js"></script>
</body>
</html>

注意 script 标签的 type="module" 属性,它告诉浏览器这是一个 ESM 模块。

2.2 Vite 的工作原理

Vite 利用 ESM 的特性,将项目中的模块分成两类:

  • 依赖 (Dependencies): 指的是那些不会经常变动的第三方库,比如 React、Vue 等。
  • 源码 (Source Code): 指的是我们自己编写的代码,这些代码会经常变动。

对于依赖,Vite 会使用 esbuild 进行预构建 (pre-bundle),将它们打包成 ESM 格式的文件。esbuild 是一个用 Go 语言编写的打包工具,它的速度非常快,比 Webpack 快 10-100 倍。

对于源码,Vite 会直接使用 ESM 的方式加载它们。当你修改某个模块的代码时,Vite 只会重新编译这个模块,然后通过 HMR (Hot Module Replacement) 的方式更新浏览器中的代码,而不需要重新加载整个页面。

2.3 代码示例:Vite 的基本用法

  1. 安装 Vite:

    npm create vite@latest my-vite-project --template react
    cd my-vite-project
    npm install
    npm run dev
  2. 目录结构:

    my-vite-project/
    ├── index.html
    ├── src/
    │   ├── App.jsx
    │   ├── main.jsx
    │   └── ...
    ├── package.json
    ├── vite.config.js
    └── ...
  3. main.jsx

    import React from 'react'
    import ReactDOM from 'react-dom/client'
    import App from './App.jsx'
    import './index.css'
    
    ReactDOM.createRoot(document.getElementById('root')).render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
    )
  4. App.jsx

    import { useState } from 'react'
    import reactLogo from './assets/react.svg'
    import viteLogo from '/vite.svg'
    import './App.css'
    
    function App() {
      const [count, setCount] = useState(0)
    
      return (
        <div className="App">
          <div>
            <a href="https://vitejs.dev" target="_blank">
              <img src={viteLogo} className="logo" alt="Vite logo" />
            </a>
            <a href="https://reactjs.org" target="_blank">
              <img src={reactLogo} className="logo react" alt="React logo" />
            </a>
          </div>
          <h1>Vite + React</h1>
          <div className="card">
            <button onClick={() => setCount((count) => count + 1)}>
              count is {count}
            </button>
            <p>
              Edit <code>src/App.jsx</code> and save to test HMR
            </p>
          </div>
          <p className="read-the-docs">
            Click on the Vite and React logos to learn more
          </p>
        </div>
      )
    }
    
    export default App
  5. vite.config.js

    import { defineConfig } from 'vite'
    import react from '@vitejs/plugin-react'
    
    // https://vitejs.dev/config/
    export default defineConfig({
      plugins: [react()],
    })

运行 npm run dev 命令后,Vite 会启动一个开发服务器,然后你就可以在浏览器中访问你的项目了。当你修改 App.jsx 的代码时,Vite 会自动更新浏览器中的代码,而不需要重新加载整个页面。

第三章:Snowpack:拥抱原生 ESM

Snowpack 和 Vite 的思想类似,也是利用浏览器原生的 ESM 能力来实现无打包开发。但 Snowpack 的实现方式和 Vite 有一些不同。

3.1 Snowpack 的工作原理

Snowpack 会将你的项目中的每个模块都编译成 ESM 格式的文件,然后将这些文件存储在一个名为 web_modules 的目录中。当你需要某个模块的时候,Snowpack 会直接从 web_modules 目录中加载它,而不需要重新编译。

Snowpack 的这种方式可以让你在开发环境中完全摆脱打包工具,只需要使用浏览器原生的 ESM 能力就可以运行你的代码。

3.2 代码示例:Snowpack 的基本用法

  1. 安装 Snowpack:

    npm install --save-dev snowpack
  2. 配置 Snowpack:

    package.json 文件中添加以下配置:

    {
      "scripts": {
        "start": "snowpack dev",
        "build": "snowpack build"
      }
    }
  3. 目录结构:

    my-snowpack-project/
    ├── index.html
    ├── src/
    │   ├── index.js
    │   └── ...
    ├── package.json
    ├── snowpack.config.js
    └── ...
  4. index.html

    <!DOCTYPE html>
    <html>
    <head>
      <title>Snowpack Example</title>
    </head>
    <body>
      <h1>Hello, Snowpack!</h1>
      <script type="module" src="./src/index.js"></script>
    </body>
    </html>
  5. src/index.js

    import _ from 'lodash';
    
    console.log(_.join(['Hello', 'Snowpack'], ' '));
  6. snowpack.config.js

    module.exports = {
      mount: {
        public: { url: '/', static: true },
        src: { url: '/dist' },
      },
      plugins: [
        '@snowpack/plugin-dotenv',
        '@snowpack/plugin-optimize'
      ],
      packageOptions: {
        /* ... */
      },
      devOptions: {
        /* ... */
      },
      buildOptions: {
        /* ... */
      },
    };

运行 npm run start 命令后,Snowpack 会启动一个开发服务器,然后你就可以在浏览器中访问你的项目了。

第四章:Vite vs Snowpack:异同点分析

Vite 和 Snowpack 都是优秀的无打包开发工具,它们都利用了浏览器原生的 ESM 能力来提高开发效率。但它们在实现方式和适用场景上有一些不同。

特性 Vite Snowpack
核心依赖 esbuild (预构建) 无,依赖浏览器原生 ESM
打包方式 按需编译,依赖预构建 预编译所有模块到 web_modules
热更新 HMR HMR
插件机制 基于 Rollup 插件 Snowpack 插件
适用场景 中大型项目,需要快速启动和热更新 小型项目,追求极致的开发体验
学习成本 相对较低 相对较低
社区生态 更加活跃,插件更丰富 社区相对较小,但也在快速发展
  • 核心依赖: Vite 依赖 esbuild 进行预构建,而 Snowpack 则完全依赖浏览器原生的 ESM 能力。
  • 打包方式: Vite 采用按需编译的策略,只编译当前需要的模块,而 Snowpack 则会将所有的模块都预编译到 web_modules 目录中。
  • 插件机制: Vite 的插件机制基于 Rollup 插件,可以利用 Rollup 社区的资源,而 Snowpack 则有自己的插件机制。
  • 适用场景: Vite 更适合中大型项目,可以提供更快的启动速度和热更新速度,而 Snowpack 更适合小型项目,可以提供更极致的开发体验。

第五章:无打包开发的未来

无打包开发是前端开发的一个趋势,它可以大大提高开发效率,让开发者更加专注于代码本身,而不需要花费大量的时间在打包工具的配置上。

随着浏览器对 ESM 的支持越来越好,无打包开发将会越来越普及。未来,我们可能会看到更多的无打包开发工具出现,它们会提供更加强大的功能和更加便捷的使用方式。

总结:选择适合你的工具

Vite 和 Snowpack 都是优秀的无打包开发工具,它们各有优缺点,你可以根据自己的项目需求和个人喜好来选择适合你的工具。

如果你正在开发一个中大型项目,并且需要快速的启动速度和热更新速度,那么 Vite 可能是更好的选择。如果你正在开发一个小型项目,并且追求极致的开发体验,那么 Snowpack 可能是更好的选择。

无论你选择哪个工具,都可以让你摆脱漫长的打包等待,享受更加流畅的开发体验。

好了,今天的讲座就到这里。希望大家有所收获,下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注