广告位联系
返回顶部
分享到

no-bundle构建原理浅析

web2.0 来源:互联网 作者:佚名 发布时间:2022-08-16 17:56:33 人浏览
摘要

为什么需要构建工具? 处理其他类型文件使其能被浏览器正常加载 许多其他类型的文件需要编译处理为 ES6 模块才能被浏览器正常加载(JSX、Vue、TS、CSS、Image 等)。 解决引用路径的问

为什么需要构建工具?

  • 处理其他类型文件使其能被浏览器正常加载 —— 许多其他类型的文件需要编译处理为 ES6 模块才能被浏览器正常加载(JSX、Vue、TS、CSS、Image 等)。
  • 解决引用路径的问题 —— 许多第三方依赖包在通过第三方 URL 引用时,不仅过程烦琐,而且往往难以进行灵活的版本控制与更新,因此需要构建工具来解决这类问题。
  • 为开发提供辅助工具 —— 对于现实中的项目开发而言,一些便利的辅助开发技术,例如热更新、sourceMap 等还是需要由构建工具来提供。

什么是无包构建

它的构建方式是:

  • 在构建时只需处理模块的编译而无须打包,把模块间的相互依赖关系完全交给浏览器来处理。
  • 浏览器会加载入口模块,分析依赖后,再通过网络请求加载被依赖的模块。

这种通过浏览器原生的模块进行解析的方式又称为 Native-ESM(Native ES Module)。

1

2

3

4

5

6

7

8

9

10

//./src/index.html

...

<!-- 注意: type="module" -->

<script type="module" src="./modules/foo.js"></script>

...

//.src/modules/foo.js

import { bar } from './bar.js'

import { appendHTML } from './common.js'

...

import('https://cdn.jsdelivr.net/npm/lodash-es@4.17.15/slice.js').then((module) => {...})

基于浏览器的 JS 模块加载功能

HTML 中的 Script 引用注意点:

  • 入口模块文件在页面中引用时需要带上 type="module" 属性。
  • 带有 type="module" 属性的 script在浏览器中通过 defer 的方式异步执行(异步下载,不阻塞 HTML,顺次执行),即使是行内的 script 代码也遵循这一原则(而普通的行内 script 代码则忽略 defer 属性)。
  • 带有 type="module" 属性且带有 async 属性的 script,在浏览器中通过 async 的方式异步执行(异步下载,不阻塞 HTML,按该模块和所依赖的模块下载完成的先后顺序执行,无视 DOM 中的加载顺序),即使是行内的 script 代码,也遵循这一原则(而普通的行内 script 代码则忽略 async 属性)。
  • 即使多次加载相同模块,也只会执行一次。

模块内依赖的引用

  • 只能使用 import ... from '...' 的 ES6 风格的模块导入方式,或者使用 import(...).then(...) 的 ES6 动态导入方式,不支持其他模块化规范的引用方式(例如 require、define 等)。
  • 导入的模块只支持使用相对路径('/xxx', './xxx', '../xxx')和 URL 方式('https://xxx', 'http://xxx')进行引用,不支持直接使用包名开头的方式('xxxx', 'xxx/xxx')。
  • 只支持引用MIME Type为 text/javascript 方式的模块,不支持其他类型文件的加载(例如 CSS 等)。

无包构建工具的介绍:

Vite

Vite 是 Vue 框架的作者尤雨溪最新推出的基于 Native-ESM 的 Web 构建工具。

在开发环境下基于 Native-ESM 处理构建过程,只编译不打包,在生产环境下则基于 Rollup 打包。

Vite对导入模块的解析

对 HTML 文件的预处理

启动 Vite 时,会通过 serverPluginHtml.ts 注入 /vite/client 运行时的依赖模块,该模块用于处理热更新,以及提供更新 CSS 的方法 updateStyle。

对外部依赖包的解析

  • resolver.ts 负责找到对应在 node_modules 中的真实依赖包代码(Vite 会在启动服务时对项目 package.json 中的 dependencies 做预处理读取并存入缓存目录 node_modules/.vite_opt_cache 中)。
  • serverPluginModuleRewrite.ts 负责把源码中的 bare modules 加上 /@module/ 前缀。
  • serverPluginModuleResolve.ts 负责解析加上前缀后的模块。

对 Vue文件的解析

对 Vue 文件的解析是通过 serverPluginVue.ts 处理的,分离出 Vue 代码中的 script/template/style 代码片段,并分别转换为 JS 模块,然后将 template/style 模块的 import写到script 模块代码的头部。

对 CSS 文件的解析

对 CSS 文件的解析是通过 serverPluginCSS.ts 处理的,解析过程主要是将 CSS 文件的内容转换为下面的 JS 代码模块,其中的 updateStyle 由注入 HTML 中的 /vite/client 模块提供

1

2

3

4

import { updateStyle } from "/vite/client"

const css = "..."

updateStyle(""..."", css) // id, cssContent

export default css

Vite 中的其他辅助功能

  • 多框架:除了在默认的 Vue 中使用外,还支持在 React 和 Preact 项目中使用。
  • 热更新(HMR) :默认提供的 3 种框架的脚手架模板中都内置了 HMR 功能,同时也提供了 HMR 的 API 供第三方插件或项目代码使用。
  • 自定义配置文件:支持使用自定义配置文件来细化构建配置,配置项功能参考 config.ts。
  • HTTPS 与 HTTP/2:支持使用 --https 启动参数来开启使用 HTTPS 和 HTTP/2 协议的开发服务器。
  • 服务代理:在自定义配置中支持配置代理,将部分请求代理到第三方服务。
  • 模式与环境变量:支持通过 mode 来指定构建模式为 development 或 production。相应模式下自动读取 dotenv 类型的环境变量配置文件(例如 .env.production.local)。
  • 生产环境打包:生产环境使用 Rollup 进行打包,支持传入自定义配置,配置项功能参考 build/index.ts。

Vite 的使用限制

  • 面向支持 ES6 的现代浏览器,在生产环境下,编译目标参数 esBuildTarget 的默认值为 es2019,最低支持版本为 es2015(因为内部会使用 esbuild 处理编译压缩,用来获得最快的构建速度)。
  • 对 Vue 框架的支持目前仅限于最新的 Vue 3 版本,不兼容更低版本。

Snowpack

  • 从整体功能来说和上述 Vite工具提供的功能大致相同。
  • Snowpack 在生产环境下默认使用无包构建而非打包模式。

与 Vite 相同的功能点

两者都支持各种代码转换加载器、热更新、环境变量(需要安装 dotenv 插件)、服务代理、HTTPS 与 HTTP/2 等。

与 Vite 的差异点

  • 相同的功能,实现细节不同: 例如对 Bare Module 的处理,除了转换后前缀名称不同外(Vite 使用 /@module/ 前缀,而 Snowpack 使用 /web_modules/ 前缀)
  • 工具稳定性
  • 插件体系: 除了版本差异外,Snowpack 提供了较完善的插件体系,支持用户和社区发布自定义插件。
  • 打包工具:在生产环境下,Vite 使用 Rollup 作为打包工具,而 Snowpack 则需要引入插件来实现打包功能,官方支持的打包插件有 @snowpack/plugin-webpack 和 @snowpack/plugin-parcel,暂未提供 Rollup 对应的插件。
  • 特殊优化:Vite 中内置了对 Vue 的大量构建优化,因此对 Vue 项目而言,选择 Vite 通常可以获得更好的开发体验。

无包构建 VS 打包构建

无包构建的优点

  • 初次构建启动快: 无包构建流程中,模块依赖分析与编译都是在浏览器渲染页面时异步处理的
  • 按需编译:在浏览器渲染时,根据入口模块分析加载所需模块,编译过程按需处理,因此相比之下处理内容更少,速度也会更快。
  • 增量构建速度快:rebuild 过程中,只需处理编译单个模块。

无包构建的缺点

  • 浏览器网络请求数量剧增: 无包构建最主要面对的问题是,它的运行模式决定了在一般项目里,渲染页面所需发起的请求数远比打包构建要多得多,使得打开页面会产生瀑布式的大量网络请求,将对页面的渲染造成延迟。这也是 Vite 在开发环境下才使用无包构建,在生产环境下则仍旧使用打包构建的原因吧。
  • 浏览器的兼容性:


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。

您可能感兴趣的文章 :

原文链接 : https://juejin.cn/post/7132120567410327566
相关文章
  • no-bundle构建原理浅析

    no-bundle构建原理浅析
    为什么需要构建工具? 处理其他类型文件使其能被浏览器正常加载 许多其他类型的文件需要编译处理为 ES6 模块才能被浏览器正常加载(
  • web2.0中流行的设计元素:颜色
    颜色的变化跟人类的智慧一样,是无穷的,每个阶段都会有流行的色彩,有属于一个时代的颜色!WEB2.0是一个概念,它宣扬,定位了一些东西,以用户
  • cypress测试本地web应用方法介绍

    cypress测试本地web应用方法介绍
    cypress测试本地web应用 在之前的cypress介绍里曾提到过,cypress虽然也可以测试部署好的应用,但是它最大的能力还是发挥在测试本地应用上。
  • HTML5 WebSocket技术使用介绍
    WebSocket WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。 现很多网站为了实现即时通讯,所用的技术都是轮询
  • Web移动端Fixed布局的解决方案

    Web移动端Fixed布局的解决方案
    移动端业务开发,iOS 下经常会有fixed元素和输入框(input元素)同时存在的情况。 但是fixed元素在有软键盘唤起的情况下,会出现许多莫名其妙
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计