0

0

使用 esmsh 无需捆绑程序即可进行捆绑

心靈之曲

心靈之曲

发布时间:2025-01-08 13:56:17

|

1084人浏览过

|

来源于php中文网

原创

使用 esmsh 无需捆绑程序即可进行捆绑

先前文章中,我分享了一些在现代 Web 项目中避免使用复杂开发者工具的技巧,其中包括如何利用 esm.sh 直接从浏览器导入包。

随着依赖项的累积,特别是当依赖项本身也依赖其他库(即传递依赖项)时,您可能会发现初始加载时间受到影响。当然,页面加载后,所有内容都会被有效缓存。但浏览器需要加载许多不同的文件(正如开发者工具的网络选项卡所示),加载完这些文件后,还需要加载另一批文件。

这就是捆绑器存在的意义!因此,最终您可能需要一个捆绑器。嗯,或许吧。但您无需自行运行它。esm.sh 提供一项实验性功能,可为您创建包含指定包的捆绑包。以下是我的使用方法。

假设我们正在构建的编辑器需要以下包:

<code class="javascript">import ts from "typescript";
import { tssync, tsfacet, tslinter, tsautocomplete } from "@valtown/codemirror-ts";
import { basicsetup, editorview } from "codemirror";
import { javascript } from "@codemirror/lang-javascript";
import { acceptcompletion, autocompletion } from "@codemirror/autocomplete";
import { compartment, stateeffect } from "@codemirror/state";
import { onedark } from "@codemirror/theme-one-dark";
import { indentwithtab } from "@codemirror/commands";
import { keymap, viewplugin } from "@codemirror/view";
import {
  createdefaultmapfromcdn,
  createsystem,
  createvirtualtypescriptenvironment,
} from "@typescript/vfs";</code>

使用导入映射

您可以将这些添加到 index.html 中的导入映射:

<code class="json">{
  "imports": {
    "typescript": "https://esm.sh/typescript",
    "@valtown/codemirror-ts": "https://esm.sh/*@valtown/codemirror-ts",
    "style-mod": "https://esm.sh/style-mod",
    "w3c-keyname": "https://esm.sh/w3c-keyname",
    "crelt": "https://esm.sh/crelt",
    "@marijn/find-cluster-break": "https://esm.sh/@marijn/find-cluster-break",
    "@lezer/": "https://esm.sh/*@lezer/",
    "@codemirror/": "https://esm.sh/*@codemirror/",
    "codemirror": "https://esm.sh/*codemirror"
  }
}</code>

*所有依赖项都被标记为外部依赖项,这是 esm.sh 的另一项功能。我还必须手动添加 codemirror 的所有依赖项。我发现这是必要的,因为不同 codemirror 包的解析依赖项版本略有不同,这会导致导入不同版本的传递依赖项并产生冲突。

此方法有效,但正如引言中提到的,初始加载时间会受到影响,因为浏览器需要下载大量文件,并且它无法预先知道需要下载哪些文件。

让 esm.sh 编译一个包

您可以使用此方法让 esm.sh 创建捆绑包,而无需自行使用捆绑器。我还会解释如何使类型正常工作。

首先,我创建了一个文件 /deps/editor.deps.js

<code class="javascript">import build from "https://esm.sh/build";

const ret = await build({
  dependencies: {
    "codemirror": "^6.0.1",
    "@valtown/codemirror-ts": "^2.3.1",
    "@codemirror/lang-javascript": "^6.2.2",
    "@codemirror/autocomplete": "^6.18.4",
    "@codemirror/state": "^6.5.0",
    "@codemirror/theme-one-dark": "^6.1.2",
    "@codemirror/commands": "^6.7.1"
  },
  source: `
  import ts from "typescript";
  import { tssync, tsfacet, tslinter, tsautocomplete } from "@valtown/codemirror-ts";
  import { basicsetup, editorview } from "codemirror";
  import { javascript } from "@codemirror/lang-javascript";
  import { acceptcompletion, autocompletion } from "@codemirror/autocomplete";
  import { compartment, stateeffect } from "@codemirror/state";
  import { onedark } from "@codemirror/theme-one-dark";
  import { indentwithtab } from "@codemirror/commands";
  import { keymap, viewplugin } from "@codemirror/view";
  import {
  createdefaultmapfromcdn,
  createsystem,
  createvirtualtypescriptenvironment,
} from "@typescript/vfs";

  export {
    ts,
    tssync,
    tsfacet,
    tslinter,
    tsautocomplete,
    basicsetup,
    editorview,
    javascript,
    acceptcompletion,
    autocompletion,
    compartment,
    stateeffect,
    onedark,
    indentwithtab,
    keymap,
    viewplugin,
    createdefaultmapfromcdn,
    createsystem,
    createvirtualtypescriptenvironment,
  };`
});

const {
  ts,
  tssync,
  tsfacet,
  tslinter,
  tsautocomplete,
  basicsetup,
  editorview,
  javascript,
  acceptcompletion,
  autocompletion,
  compartment,
  stateeffect,
  onedark,
  indentwithtab,
  keymap,
  viewplugin,
  createdefaultmapfromcdn,
  createsystem,
  createvirtualtypescriptenvironment,
} = await import(ret.bundleurl);

console.log({ret});

export {
  ts,
  tssync,
  tsfacet,
  tslinter,
  tsautocomplete,
  basicsetup,
  editorview,
  javascript,
  acceptcompletion,
  autocompletion,
  compartment,
  stateeffect,
  onedark,
  indentwithtab,
  keymap,
  viewplugin,
  createdefaultmapfromcdn,
  createsystem,
  createvirtualtypescriptenvironment,
};</code>

这里有很多重复代码。如果要更改导入,则需要在多个位置更新。这无疑是一件麻烦事。是否值得,由您决定。

Magic AI Avatars
Magic AI Avatars

神奇的AI头像,获得200多个由AI制作的自定义头像。

下载

无论如何,您都会看到导入此文件时 ret 会打印到控制台。以下是打印内容:

<code class="json">{
  ret: {
    bundleurl: "https://esm.sh/~e4d1ab3ba39fc16e6de014e6f19bd819605fdd95?bundle",
    id: "e4d1ab3ba39fc16e6de014e6f19bd819605fdd95",
    url: "https://esm.sh/~e4d1ab3ba39fc16e6de014e6f19bd819605fdd95"
  }
}</code>

bundleurl 是包含为我们创建的捆绑包的 esm.sh URL!我们使用动态 import() 导入它,然后重新导出它。

因此,您可以简单地从 /deps/editor.deps.js 导入所有内容:

<code class="javascript">import { ts } from "/deps/editor.deps.js";</code>

就完成了!

如果您想让

<code class="javascript">import { basicsetup, editorview } from "codemirror";</code>

正常工作,我们可以按如下方式更新导入映射:

<code class="json">{
  "imports": {
    "codemirror": "/deps/editor.deps.js"
  }
}</code>

这对于默认导出(如 typescript 包)不起作用。为此,我们可以创建一个 deps/editor.deps.d.ts 文件以使类型正常工作:

就是这样!无需捆绑器即可进行捆绑。我们可以称之为“无捆绑器”,因为它虽然仍然涉及服务器/捆绑器(就像无服务器一样),但您无需自行处理。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

47

2026.02.13

TypeScript全栈项目架构与接口规范设计
TypeScript全栈项目架构与接口规范设计

本专题面向全栈开发者,系统讲解基于 TypeScript 构建前后端统一技术栈的工程化实践。内容涵盖项目分层设计、接口协议规范、类型共享机制、错误码体系设计、接口自动化生成与文档维护方案。通过完整项目示例,帮助开发者构建结构清晰、类型安全、易维护的现代全栈应用架构。

194

2026.02.25

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

530

2023.06.20

js获取当前时间
js获取当前时间

JS全称JavaScript,是一种具有函数优先的轻量级,解释型或即时编译型的编程语言;它是一种属于网络的高级脚本语言,主要用于Web,常用来为网页添加各式各样的动态功能。js怎么获取当前时间呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

576

2023.07.28

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js是什么意思
js是什么意思

JS是JavaScript的缩写,它是一种广泛应用于网页开发的脚本语言。JavaScript是一种解释性的、基于对象和事件驱动的编程语言,通常用于为网页增加交互性和动态性。它可以在网页上实现复杂的功能和效果,如表单验证、页面元素操作、动画效果、数据交互等。

6208

2023.08.17

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

492

2023.09.01

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
TypeScript 教程
TypeScript 教程

共19课时 | 3.4万人学习

TypeScript——十天技能课堂
TypeScript——十天技能课堂

共21课时 | 1.2万人学习

TypeScript-45分钟入门
TypeScript-45分钟入门

共6课时 | 0.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号