面红耳赤!Vite竟然使用这种方式来解决模块化打包!

1,269 阅读2分钟

这是我参与更文挑战的第2天,活动详情查看: 更文挑战

我的困扰

我是从2017年接触前端的,关于模块化接触的是commonJSAMDRequireJS等等。在浏览器支持模块化之前,我们以打包模块化生成项目的静态资源。

随着在职时间变长,项目引入的模块越来越多,编写的页面越来越杂,对我的开发效率产生了巨大的打击。

对于我维护的angular项目,虽然angular自有的"打包"、"热更新"功能非常优秀,但是因为包含着巨大的代码量,它现在修改代码后的热更新差不多要20秒才能成功,打包甚至需要将近十几分钟的时间。

为什么Vite将所有代码视为原生ES模块?

随着web页面上的JavaScript程序越来越复杂,浏览器开始原生支持模块功能。浏览器能够最优化加载模块,使它比使用库更有效率:使用库通常需要做额外的客户端处理。

Vite正在尝试用原生ES模块解决上述的问题。 WechatIMG695.png

在源码中Vite使用esbuild转换其他模块化(cjs,amd,require)的模块至esm模块。在这个过程中,Vite自行分析模块将转换为ESM的模块分为入口模块和依赖模块,并缓存至node_modules/.vite文件夹中。

之后访问页面时,只import当前路由所需的模块并将依赖模块进行强缓存。例如我访问A页面加载了axios(需要获取后端老哥给我的数据),而我访问B页面时,同事也需要用到axios,这时会直接使用已经加载完成的模块。

当我们进行热更新时,Vite提供了一套原生ESM的HMR API,在编辑文件时,通过API通过原生ESM直接替换。

image.png

JavaScript Modules

ESM依赖于importexport,并且需要在script标签内把type设为module

<script type="module" src="index.js"></script>

示例

我们使用原生ES模块来写一个例子。

目录中的index.html中引入了typemodule的js文件index.js

// ./index.html

<body>
    <div id="test-div"></div>
    <script type="module" src="./index.js"></script>
</body>

ESM依赖于importexport,我们使用这两个语法来引入一些方法和变量。

code文件夹中的edit.js,使用export导出一个名为editName的方法,作用于修改页面中的内容。

// ./code/edit.js
export const editName = (eleId, name) => {
        document.querySelector(`#${eleId}`).innerHTML = name
}

code文件夹中的name.js,使用export导出一个变量name

// ./code/name.js
export const name = 'Kev1nzh'

最后在引入的index.js文件中,连接导出的变量和方法并运行。

// ./index.js 

import {name} from './code/name.js'
import {editName} from './code/edit.js'

console.log(name)

editName('test-div', name)

打开后已经能看到修改后的页面了。

最后

介绍下阅读Vite源码的记录项目,点我本站跳转

查看线上文档体验更佳 查看文档 Powered by dumi

看完有帮助的可以进入github给我一个🌟小星星 谢谢!