有了 vite,还需要 webpack 么?

原创声明:本文首发于公众号:前端琐话(qianduansuohua),欢迎关注

前言

前两天尤大在 vue 3.0 beta 直播中提到了一个 vite 的工具,而且还发推表示再也回不去 webpack 了, 还引来了 webpack 核心开发人员肖恩的搞笑回复, 那就让我们一起来看一下 vite 到底有啥魔力?

有了 vite,还需要 webpack 么?_第1张图片

什么是 Vite?

github: https://github.com/vitejs/vite

Vite 是一个由原生 ESM 驱动的 Web 开发构建工具。在开发环境下基于浏览器原生 ES imports 开发,在生产环境下基于 Rollup 打包。

它主要具有以下特点:

  • 快速的冷启动
  • 即时的模块热更新
  • 真正的按需编译

那废话少说,我们先直接来试用一下。

$ npm init vite-app 
$ cd 
$ npm install
$ npm run dev

我们来看下生成的代码, 因为 vite 尝试尽可能多地镜像 vue-cli 中的默认配置, 所以我们会发现看上去和 vue-cli 生成的代码没有太大区别。

├── index.html
├── package.json
├── public
│   └── favicon.ico
└── src
    ├── App.vue
    ├── assets
    │   └── logo.png
    ├── components
    │   └── HelloWorld.vue
    ├── index.css
    └── main.js

那我们看下入口 index.html 和 main.js




  
  
  
  Vite App


  
// main.js // 只是引用的是最新的 vue3 语法,其余没有啥不同 import { createApp } from 'vue' import App from './App.vue' import './index.css' createApp(App).mount('#app')

发现主要的不同在于多了这么个东西

那下面我们就来看下这是个啥?

原理

ESM

script module 是 ES 模块在浏览器端的实现,目前主流的浏览器都已经支持

有了 vite,还需要 webpack 么?_第2张图片

其最大的特点是在浏览器端使用 exportimport 的方式导入和导出模块,在 script 标签里设置 type="module"

浏览器会识别添加 type="module"

变成了

import HelloWorld from '/src/components/HelloWorld.vue';

const __script = {
    name: 'App',
    components: {
        HelloWorld,
    },
};

import "/src/App.vue?type=style&index=0&t=1592811240845"
import {render as __render} from "/src/App.vue?type=template&t=1592811240845"
__script.render = __render
__script.__hmrId = "/src/App.vue"
__script.__file = "/Users/wang/qdcares/test/vite-demo/src/App.vue"
export default __script

这样就把原本一个 .vue 的文件拆成了三个请求(分别对应 script、style 和template) ,浏览器会先收到包含 script 逻辑的 App.vue 的响应,然后解析到 template 和 style 的路径后,会再次发起 HTTP 请求来请求对应的资源,此时 Vite 对其拦截并再次处理后返回相应的内容。

// App.vue?type=style
import { updateStyle } from "/vite/hmr"
const css = "\n#app {\n  font-family: Avenir, Helvetica, Arial, sans-serif;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  text-align: center;\n  color: #2c3e50;\n  margin-top: 60px;\n}\n"
updateStyle("7ac74a55-0", css)
export default css
// App.vue?type=template
import {createVNode as _createVNode, resolveComponent as _resolveComponent, Fragment as _Fragment, openBlock as _openBlock, createBlock as _createBlock} from "/@modules/vue.js"

const _hoisted_1 = /*#__PURE__*/
_createVNode("img", {
    alt: "Vue logo",
    src: "/src/assets/logo.png"
}, null, -1 /* HOISTED */
)

export function render(_ctx, _cache) {
    const _component_HelloWorld = _resolveComponent("HelloWorld")

    return (_openBlock(),
    _createBlock(_Fragment, null, [_hoisted_1, _createVNode(_component_HelloWorld, {
        msg: "Hello Vue 3.0 + Vite"
    })], 64 /* STABLE_FRAGMENT */
    ))
}

实际上在看到这个思路之后,对于其他的类型文件的处理几乎都是类似的逻辑,根据请求的不同文件类型,做出不同的编译处理。

实际上 vite 就是在按需加载的基础上通过拦截请求实现了实时按需编译

后语

到这里我们实际上就基本了解了 vite 的原理,虽然在目前的生态下,完全替代 webpack 还不可能,但毕竟是一种的新的解决方案的探索。
而实际上,除了 vite, 社区里类似的方案还有 snowpack, 有兴趣的可以去了解一下。


有了 vite,还需要 webpack 么?_第3张图片

你可能感兴趣的:(前端,vue.js,webpack,javascript,node.js)