UMD 被淘汰了吗?不考虑的 UMD 的库如何在纯 UMD 前端项目中运行?

简介: UMD 被淘汰了吗?不考虑的 UMD 的库如何在纯 UMD 前端项目中运行?

背景:Hackathon


最近团队在参加一场国际 Hackathon 活动,虽然名义上我也是项目的成员,但我不是主要参加者,主要负责人是一位架构师大佬。

经过讨论后,我需要帮助大佬完成一些他不太擅长的前端工作。

这个项目模板是从一个开源 VR 项目中拉下来的。

我打开后,发现目录结构如下:

image.png

没有使用 node.js 和 npm,所以我称它是纯 umd 项目。

可能研究 VR 的大佬不怎么喜欢研究前端吧,或者对前端工程化完全不感兴趣。

在 index.html 中一堆包直接导入就好了。

image.png

这种用法一时间仿佛让我回到了十年前,但我不打算深究这个问题。

团队经常参加 Hackathon 活动来为我们的开源项目增加知名度,但是 Hackathon 项目一般都不会维护,开发完拿过去演示一下,基本上就再也不会碰了。所以我也没必要再去折腾它的前端工程化。

我现在要做的事,就是在 2 天之内为这个项目增加几个功能。

它的作用就是用 three 画个地板空间,空间的一端有两个屏幕。一个是老师的摄像头,一个是老师的屏幕。

学生会蹲在地板上听老师讲课。

image.png

和普通的直播项目不一样的是,你可以戴着 VR 参加直播。

image.png

虽然项目的前端看上去有些落后,可是技术含量一点儿都不低。

一切似乎很顺利。


问题出现了!


可是当我需要为项目引入两个包时,却碰到了问题。

  • nanoid:id 生成器。
  • presencejs:p2p 通信。

由于我必须生成唯一的 nanoid,所以要使用 nanoid 这个库。

可是 nanoid 的官网并没有介绍通过 umd 的方式使用,于是我查了下 issues。

果然有人碰到了和我一样的问题,但是 nanoid 的作者回复,说 umd 已老,我们不考虑支持 umd 了!

image.png


至于 presencejs,本来就是我维护的,v1 版本确实也不支持 umd。


umd 和 esm 混用!


那该怎么办呢?

两种选择:

  1. 折腾前端工程化,把项目用 npm 管理起来,通过打包工具构建项目。
  2. 通过 esm 的方式导入第三方库。

很明显后者成本更低,但它也有个问题,就是不支持老浏览器。

image.png

我立马询问了架构师这个项目的运行环境,是在最新版本的 Chrome 中运行。

那这个问题也不用考虑了。

具体用法就是在 esm 中把 umd 需要的 API 挂载到 window 对象上,伪代码:


<script type="module">
  import { nanoid } from "https://unpkg.com/nanoid@3.1.23/nanoid.js";
  window.nanoid = nanoid;
</script>

不过在 esm 和 umd 混合使用的过程中又碰到了些问题。


执行顺序问题


esm 是异步加载、异步执行。umd 是立即加载、立即执行。

如果 umd 依赖 esm 怎么办?

比如我加载一个 umd 文件,立马要通过 nanoid 生成一个 id。但是此时 nanoid 还没有加载出来。

umd 有一个 async 和 defer 属性,可以让 js 文件以异步或者延迟的方式加载。

但是仍然没有用,因为 esm 和 umd 都是异步执行,没办法保证哪个先执行哪个后执行。

这个问题也有两个办法可以解决:

  1. 把 umd 改造成 esm。
  2. 在 esm 中等第三方库加载结束再调用 umd。

因为项目中有大量的 umd 文件,第一种方案风险明显更高。

那么选择第二种方案,伪代码如下:

定义 import UMD 函数。


function importUMD(url) {
  return fetch(url)
    .then(response => response.text())
    .then(txt => eval(txt))
}


<script type="module">
  import { nanoid } from "https://unpkg.com/nanoid@3.1.23/nanoid.js";
  window.nanoid = nanoid;
  importUMD('./my.js')
</script>


依赖问题


解决了 nanoid 的问题之后,我又发现了另一个问题。

presencejs 又依赖了一些 peer 级别的库。

在 esm 文件的开头会有一堆导入:


import { interval, Subject } from 'rxjs';
import { distinctUntilChanged, filter, map, takeWhile } from 'rxjs/operators';
import { WebSocketSubject } from 'rxjs/webSocket';

解决方案就是导入 rxjs 的 umd CDN。


<script src="https://unpkg.com/rxjs@^7/dist/bundles/rxjs.umd.min.js"></script>

然后把 presencejs 的依赖项改为如下这种写法:


const { interval, Subject, operators, webSocket } = window.rxjs
const { distinctUntilChanged, filter, map, takeWhile } = operators
const { WebSocketSubject } = webSocket

所幸 presencejs 依赖的第三方库只有 rxjs 一个,如果依赖了很多 peer 级别的第三方库的话,那需要导入的内容就多了去了。


JavaScript 模块规范的发展


我发现最近这几年,越来越多的库都在渐渐不支持 UMD 规范。原因大致相同,大家都认为这种用法已经过时了,应该被淘汰,大家应该拥抱官方的 ESM 规范。

这种想法是对的,但是没有向后兼容。

一段 JavaScript 代码的运行环境有非常多种,比如浏览器脚本、浏览器模块、Nodejs、deno、bun 等。理想状态是我们编写一份代码,就可以在全平台运行。当然依赖某些平台特性的 API,比如浏览器的 DOM API、Nodejs 的 process 等除外。

但现实情况根本不现实,必须通过编译工具对代码进行编译,输出多份文件,分别对应不同的环境。

最初 UMD 就是为了解决上述问题而产生的规范,一份 UMD 的编译结果,可以在所有平台上运行,这也是被大家认可和接受的。但如今它似乎已经是一个即将被时代淘汰的过度品,社区越来越拥抱 ESM 了。



相关文章
|
9天前
|
前端开发 JavaScript 定位技术
一、前端高德地图注册、项目中引入、渲染标记(Marker)and覆盖物(Circle)
文章介绍了如何在前端项目中注册并使用高德地图API,包括注册高德开放平台账号、引入高德地图到项目、以及如何在地图上渲染标记(Marker)和覆盖物(Circle)。
24 1
|
2月前
|
前端开发 Java 编译器
【前端学java】java基础练习缺少项目?看这篇文章就够了!(完结)
【8月更文挑战第11天】java基础练习缺少项目?看这篇文章就够了!(完结)
34 0
|
2月前
|
JavaScript 前端开发 Java
SpringBoot + Vue 前端后分离项目精进版本
这篇文章详细介绍了一个基于SpringBoot + Vue的前后端分离项目的搭建过程,包括前端Vue项目的初始化、依赖安装、页面创建和路由配置,以及后端SpringBoot项目的依赖添加、配置文件修改、代码实现和跨域问题的解决,最后展示了项目运行效果。
SpringBoot + Vue 前端后分离项目精进版本
|
2月前
|
前端开发 JavaScript
在 Vue3 + ElementPlus 项目中使用 computed 实现前端静态分页
本文介绍了在Vue3 + ElementPlus项目中使用`computed`属性实现前端静态分页的方法,并提供了详细的示例代码和运行效果。
107 1
在 Vue3 + ElementPlus 项目中使用 computed 实现前端静态分页
|
2月前
|
前端开发 JavaScript 程序员
成功解决:尚硅谷中的谷粒商城前端项目运行依赖问题。【详细图解+问题说明+解决思路】
这篇文章介绍了如何解决尚硅谷谷粒商城前端项目中遇到的依赖问题,通过修改`package.json`和`package-lock.json`中的`node-sass`和`sass-loader`版本,成功解决了node版本与这些依赖的兼容性问题。
成功解决:尚硅谷中的谷粒商城前端项目运行依赖问题。【详细图解+问题说明+解决思路】
|
2月前
|
前端开发 Java 编译器
【前端学java】java基础练习缺少项目?看这篇文章就够了!(17)
【8月更文挑战第11天】java基础练习缺少项目?看这篇文章就够了!
28 0
【前端学java】java基础练习缺少项目?看这篇文章就够了!(17)
|
2月前
|
开发者 C# C++
揭秘:如何轻松驾驭Uno Platform,用C#和XAML打造跨平台神器——一步步打造你的高性能WebAssembly应用!
【8月更文挑战第31天】Uno Platform 是一个跨平台应用程序框架,支持使用 C# 和 XAML 创建多平台应用,包括 Web。通过编译为 WebAssembly,Uno Platform 可实现在 Web 上运行高性能、接近原生体验的应用。本文介绍如何构建高效的 WebAssembly 应用:首先确保安装最新版本的 Visual Studio 或 VS Code 并配置 Uno Platform 开发环境;接着创建新的 Uno Platform 项目;然后通过安装工具链并使用 Uno WebAssembly CLI 编译应用;最后添加示例代码并测试应用。
55 0
|
2月前
|
前端开发 JavaScript 开发者
JSF与WebSockets,打造实时通信魔法!让你的Web应用秒变聊天室,用户体验飞升!
【8月更文挑战第31天】在现代Web应用开发中,实时通信对于提升用户体验至关重要。本文探讨了如何在主要面向Web应用开发的JSF(JavaServer Faces)框架中引入WebSockets支持,以实现客户端与服务器之间的全双工通信。通过具体示例展示了在JSF应用中实现WebSockets的基本步骤:添加依赖、创建服务器端点以及在前端页面中嵌入JavaScript客户端代码。尽管这一过程中可能会遇到一些挑战,如复杂代码编写和额外配置需求,但借助AWS等云服务平台,开发者仍能高效地完成部署和管理工作,从而增强Web应用的实时通信能力。
33 0
|
2月前
|
前端开发 开发者 Apache
揭秘Apache Wicket项目结构:如何打造Web应用的钢铁长城,告别混乱代码!
【8月更文挑战第31天】Apache Wicket凭借其组件化设计深受Java Web开发者青睐。本文详细解析了Wicket项目结构,帮助你构建可维护的大型Web应用。通过示例展示了如何使用Maven管理依赖,并组织页面、组件及业务逻辑,确保代码清晰易懂。Wicket提供的页面继承、组件重用等功能进一步增强了项目的可维护性和扩展性。掌握这些技巧,能够显著提升开发效率,构建更稳定的Web应用。
76 0
|
2月前
|
前端开发 程序员 API
从后端到前端的无缝切换:一名C#程序员如何借助Blazor技术实现全栈开发的梦想——深入解析Blazor框架下的Web应用构建之旅,附带实战代码示例与项目配置技巧揭露
【8月更文挑战第31天】本文通过详细步骤和代码示例,介绍了如何利用 Blazor 构建全栈 Web 应用。从创建新的 Blazor WebAssembly 项目开始,逐步演示了前后端分离的服务架构设计,包括 REST API 的设置及 Blazor 组件的数据展示。通过整合前后端逻辑,C# 开发者能够在统一环境中实现高效且一致的全栈开发。Blazor 的引入不仅简化了 Web 应用开发流程,还为习惯于后端开发的程序员提供了进入前端世界的桥梁。
52 0
下一篇
无影云桌面