为啥需要 Vite

99 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情

伴随 Vue3 的推出,Vue3 的作者还开发了一个自己的构建工具 Vite,这个单词来自于法语,它的意思是快,也就意味着 Vite 这个工具比过去 webpack 的 更快。

那在介绍 Vite 之前,我们先来回顾一下浏览器中使用 ES Module 方式。

除 IE 之外的现代浏览器都已经支持 ES Module 语法,也就是使用 import 导入模块,使用 export 导出模块,在网页中可以直接通过下面的 script 的标签来导入模块。

<script type="module" src=""></script>

把 script 标签的 type 设置为module 的时候,就是导入模块。标记为 module 的 script 标签默认是延迟加载的,就类似于普通的 script 标签上加上 defer 属性。

type 等于 module 的 script 标签相当于省略了 defer。它是在当前文档解析完成,也就是 DOM 树生成之后,并且在 DOMCcontentLoaded 事件之前执行。

那下面我们来演示一下。

utils.js

export const forEach=(array,fn)=>{
    let i
    for(i = 0;i<array.length;i++){
        fn(array[i])
    }
}

export const some=(array,fn)=>{
    let result=true
    for(const value of array){
        result =result || fn(value)
            if (result){
                break
            }
        }
        return result
}

在这个模块中我们导出了两个函数,一个是 forEach,还有一个是 some。

那下面我们再来创建一个入口模块,来使用有 utils.js 中给我们提供的功能。我们在这里再来创建一个index.js。

import {forEach} from './utils.js'

const arr =[1,2,3]

forEach(arr,item=>{
    console.log(item)
})

那在这个文件中,我们先来导入 utils模块,直接使用 import。比如要使用 forEach 函数,那么我们这里边可以写 forEach 函数。注意,一定要加上后缀 .js,它是去加载这个文件。

模块导入之后,我们来测试一下这个 forEach,我们先来定义一个数组 arr。在调用这个 forEach 时,需要两个参数,第一个是我们的数组,第二个是回调函数。回调函数需要接收一个参数,就是我们遍历的数组中的每一项,然后我们把这个每一项给它打印出来。

到这儿这个模块儿我们就写完了,写完之后我们要测试,我们要测试之前需要先回到 index.html 里边,来导入入口模块儿。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="app">Hello World</div>
 
  <script type="module" src="./modules/index.js"></script>
</body>
</html>

使用 script 标签导入,type 等于 module,表示要加载的是一个模块,src 加载模块路径。

打开浏览器测试一下。

image.png

这里加载模块的script 的标签是延迟执行的,是在 DOM 树创建完毕,并且在 DOMCcontentLoaded 之前执行。

那我们来测试一下,那现在我们在导入模块之前来注册 DOMCcontentLoaded 事件。我们在它的上面写一个 script 的标签。


<script>
   window.addEventListener('DOMContentLoaded', () => {
     console.log('DOMContentLoaded')
  })
 </script>

通过 ddEventListener 来注册事件,直接打印相关。

我们看他什么时候执行,然后再在入口模块中获取页面上的 div 把它打印出来。我们看是先获取 div 还是先去执行这个事件。 在 index.js 添加获取页面 div 代码。

const app = document.querySelector('#app')
console.log(app.innerHTML)


打开浏览器来测试一下。

image.png

我们可以看到这里,先打印 hello word,也就是 div 中的内容,然后再去触发我们的 DOMCcontentLoaded 这个事件。是先执行的模块,在模块中先获取的这个 div,也就是 DOM 对象,然后输出它的内容,最后去触发的 DOMCcontentLoaded 的这个事件。

这里证明了加载模块并执行是在 DOM 树创建完毕之后,并且在 DOMCcontentLoaded 之前执行了。