Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >创建一个双模式跨运行时的 JavaScript 包

创建一个双模式跨运行时的 JavaScript 包

作者头像
chuckQu
发布于 2023-12-27 02:54:00
发布于 2023-12-27 02:54:00
18000
代码可运行
举报
文章被收录于专栏:前端F2E前端F2E
运行总次数:0
代码可运行

本文将指导你发布双模式、跨运行时的 JavaScript 包。了解如何创建与 ESM 和 CommonJS 以及 Node.js、Deno 和浏览器等不同运行时兼容的库。

随着 JavaScript 开发的不断发展,人们越来越需要能在多种环境中运行的强大依赖包。在本文中,我们将探讨如何发布跨运行时、双模式的 JavaScript 包。这些包弥补了 ESM 和 CommonJS 之间的差距,让开发人员可以在任何环境下使用相同的包和文档。

在深入了解之前,让我们先熟悉一些关键概念:

双模式包

双模式包旨在与多个 JavaScript 模块系统(尤其是 ES Modules (ESM) 和 CommonJS (CJS))配合使用。这确保了代码在各种环境中的可重用性和灵活性。创建双模式包有几个好处:

  • 「更广泛的兼容性」:并非所有项目都已过渡到使用 ESM。双模式确保你的包可以在仍然依赖于 CommonJS 的项目中使用。
  • 「无缝过渡」:随着 JavaScript 生态系统逐步转向 ESM,双模式包可确保用户实现无缝过渡,而无需更换包或重构代码库。
  • 「减少维护」:双模式包允许用户管理单一代码库,而无需分别维护 ESM 和 CJS 包。

不过,双模式并不能保证软件包在不同的运行环境下都能正常工作,这就带来了以下问题:

跨运行时包

跨运行时包可在 Deno、浏览器和 Node.js 等多种环境中运行。它们旨在为不同运行时提供一致的 API。一个全面的跨运行时包应同时支持 ESM 和 CJS,尤其是因为 Node.js 在很大程度上仍在使用 CommonJS。

如果我们忽略 Node.js 的传统限制(Node.js 严重依赖 CommonJS),我们可以只使用 ES 模块构建跨运行时包。这将简化包,但会限制其与旧版 Node.js 项目的兼容性。

Node还是Deno优先

你有两种主要方法:从 Deno 或 Node.js 开始。Deno 优先方法使用 Deno 的内置工具和 Deno 到Node工具(DNT)。另一方面,Node优先方法使用传统的构建工具来完成测试、检查和打包等任务。这种方法是转换现有 NPM 库的首选。

Deno优先方法

Deno优先方法依赖于DNT,你可以在GitHub[1]上找到。

该工具通过版本库中的自定义构建脚本使用。

第一步是建立一个基本的 Deno 库,准备发布到 deno.land/x。之后,你就可以使用 DNT 了。

「添加脚本」

Deno优先方法的核心是构建流程。下面这个名为 scripts/build_npm.ts 的脚本使用 DNT 创建一个 /npm 文件夹,其中包含一个完整的 NPM 包,可以随时发布。

该脚本将处理清除 NPM 目录、复制测试数据和构建软件包等任务。它还会创建一个完整的 package.json 文件。

让我们一起来看看吧,请务必阅读注释。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { build, copy, emptyDir } from "./deps.ts";

// Clear NPM directory
await emptyDir("./npm");

// (optional) Copy test data, if you have some
// await copy("tests/data", "npm/esm/tests/data", { overwrite: true });

// This assumes that the entrypoint of your module is ./mod.ts
await build({
  entryPoints: ["./mod.ts"],
  outDir: "./npm",
  shims: {
    deno: "dev",
  },
  /*
  mappings: {
    "<https://deno.land/x/zipjs@v2.7.17/index.js>": {
      name: "@zip.js/zip.js",
      version: "^2.7.17"
    },
  },
  */
  package: {
    // package.json template
    name: "my-library-name",
    version: Deno.args[0],
    description: "My library description.",
    license: "MIT",
    repository: {/* ... */},
    author: "You <your@mail>",
    /* Additional information */
  },
});

// (optional) post build steps, you might want to copy some files?
// ---------------------------------------------------------------
// Deno.copyFileSync("LICENSE", "npm/LICENSE");
// Deno.copyFileSync("README.md", "npm/README.md");

// (optional) Add .npmignore
// ---------------------------------------------------------------
// ensure the test data is ignored in the `.npmignore` file
// so it doesn't get published with your npm package, if relevant
/*
await Deno.writeTextFile(
  "npm/.npmignore",
  "esm/tests/data\nscript/tests/data\n",
  { append: true },
);
*/

现在,你只需运行 deno run -A scripts/build_npm.ts 0.0.1 来构建 0.0.1 版本的 npm 软件包。所有相关文件都将在 ./npm 中生成。

最后一步是导航到 ./npm 目录,然后运行 npm publish,就可以了!

「使用 deno.json 更新构建管道流」

要记录这一构建步骤,可以修改 deno.jsontask部分,将新的 NPM 构建步骤包括在内。下面是一个设置测试和 NPM 构建的配置示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
    /* ... existing configuration ... */
    "tasks": {
        "test": "deno test tests --allow-read",
        "build": "deno run -A scripts/build_npm.ts"
    }
}

现在,运行 deno task build 0.0.1 时将生成 npm 包。

Node优先方法

或者,你也可以选择Node优先的方法来创建跨运行时包。

第一步是确保你的项目同时支持 ESM 和 CommonJS。这既可以手动完成,也可以使用构建工具来处理。代码库最好是非转译的 javascript 或 typescript,以便 Rollup 或类似工具处理。

让我们以 @hexagon/base64 库为例进行分析。该库使用 Rollup 生成 ESM 和 CommonJS 版本的代码,配置如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// rollup.config.js
export default [
 {
  input: "./src/base64.single.js",
  output: {
   file: "dist/base64.cjs",
   format: "umd",
   name: "base64",
   exports: "default"
  }
 },
 { 
  input: "./src/base64.js",
  output: {
   file: "dist/base64.mjs",
   format: "es"
  }
 }
];

该库的源代码(/src/base64.js)是以各种方式导出 base64 对象的普通 ES JavaScript。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// src/base64.js
/* ...
   Library code making up the base64 object
   ... */

// Default export
export default base64;

// Named export
export { base64 };

Rollup 无法处理多重导出,因此我还创建了一个 /src/base64.single.js,默认情况下它只负责重新导出 base64 对象。这是 Rollup 配置的 UMD 目标所使用的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// /src/base64.single.js
import base64 from "./base64.js";
export default base64;

package.json

package.json 文件是设置双模式、跨运行时 JavaScript 包的关键。它决定了包在不同环境中的结构和行为方式。让我们来仔细看看其中的关键部分及其重要性:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{
  /* ... your metadata ... */

  "scripts": {
    /* ... your existing build steps ... */
    "build:dist": "rollup -c ./rollup.config.js",
  },

  "type": "module",

  "main": "./dist/base64.cjs",
  "browser": "./dist/base64.min.js",
  "module": "./src/base64.js",
  "types": "types/base64.single.d.ts",

  "exports": {
    ".": {
      "import": "./src/base64.js",
      "require": "./dist/base64.cjs",
      "browser": "./dist/base64.min.js"
    }
  }
}
  • 「"scripts"」 :该部分包含构建和管理包所需的脚本。在提供的示例中,"build:dist"用于触发 Rollup 打包过程。根据包的具体要求,你可能还需要其他脚本来进行测试、检查或执行其他任务。
  • 「"type"」 :该字段设置为"module",表示你的包是为使用 ESM(ES 模块)导入而设计的。
  • 「"main"」 :该字段指定了 CommonJS 环境(如 Node.js)的入口点。它指向包的 CommonJS 版本,通常位于 dist 目录中。
  • 「"browser"」 :该字段用于指定浏览器环境的替代入口点。它指向包的最小化版本,以增强与浏览器的兼容性。
  • 「"module"」 :与 "main"字段类似,该字段用于指定 ESM 环境的入口点。它指向软件包的 ESM 版本。
  • 「"types"」 :此字段指明软件包的 TypeScript 声明文件(.d.ts)的位置。这些文件为 TypeScript 用户提供了类型信息,改善了开发人员的体验。
  • 「"exports"」 :该字段是一项最新功能,允许你定义如何导入包。它为 ESM、CommonJS 和浏览器环境指定了不同的导入路径,确保了跨运行时的流畅兼容性。

根据包的具体需求和配置,你可能需要对 package.json 进行或多或少的修改。仔细调整和测试该文件以确保其在发布时正常运行至关重要。

跨运行时部分

前面提到的步骤主要是在 Node.js 中设置双模式兼容性。虽然 Deno 可以使用开箱即用的 npm 软件包,但要创建一个完整的跨运行时包,你还应该将其适配到 Deno。

这包括阅读 Deno 库的工作原理[2]、将软件包发布到 deno.land/x[3]。

还有就是,让你的软件包成为双模式软件也能帮助其他项目。

总结

创建双模式、跨运行时的 JavaScript 包是一种有益的体验。它能使你的代码具有可移植性和可重用性,让你在不同的 JavaScript 环境中接触到更多的用户。虽然会有一些障碍和注意事项,如管理兼容性以及与不同模块系统和运行时的配合,但利大于弊。

本文译自:https://hexagon.56k.guru/posts/dual-mode-cross-runtime-packages/

参考资料

[1]

GitHub: https://github.com/denoland/dnt

[2]

Deno 库的工作原理: https://deno.land/manual@v1.36.4/introduction

[3]

将软件包发布到 deno.land/x: https://deno.land/manual@v1.36.4/advanced/publishing

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-12-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端F2E 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Bun:不仅是新的JavaScript运行时,并且重塑了JavaScript工具链
从2022年 Bun 的 Beta 版本发布,就早已爆火,仅一个月内,就在 GitHub 上获得了超过两万颗 Star,成为年度最火的前端项目。在今年的 9 月 8 号,由 Jarred Sumner 开发的 Bun v1.0 正式发布。本文会重点介绍 Bun 的特性和性能的测试,并且分析 Bun 为什么这么快。
windseeker
2023/10/23
4.3K0
Bun:不仅是新的JavaScript运行时,并且重塑了JavaScript工具链
Deno 1.0,来了解一下
经过近两年的等待,官方正式宣布Deno 1.0将于5月13日发布。如今,API已经冻结,倒计时开始。
山月
2020/05/26
1.2K0
Deno 1.0,来了解一下
编写跨运行时的 JavaScript 程序
前端一年,人间三年,技术迭代之快,一般人还真的很难跟上。前端开发者似乎一直摆脱不了’兼容性‘、’跨平台‘、碎片化的这些话题。
_sx_
2023/10/23
3480
编写跨运行时的 JavaScript 程序
Deno不只是个Javascript运行时
Deno 是一个安全的 JavaScript 和 TypeScript 运行时,作者是 Ryan Dahl(也是 Node.js 的原作者)。Deno 的诞生之初是为了解决 2009 年首次设计 Node.js 时的一些疏忽。我认为这种改造动机很有道理,因为我相信每个程序员都希望有机会能重写他们已有 10 年历史的代码。
愧怍
2023/02/02
1.2K0
Deno不只是个Javascript运行时
Deno:现代化 JavaScript 和 TypeScript 运行时的深入解析
Deno 是一个现代化的 JavaScript 和 TypeScript 运行时,由 JavaScript 创始人 Ryan Dahl 于 2018 年发布。它的设计旨在解决传统运行时(例如 Node.js)存在的一些关键问题,同时引入更强大的功能与现代化的开发体验。Deno 的特点、设计理念以及应用场景使其在当代开发中逐渐受到关注。
编程小妖女
2024/12/22
1030
Deno:现代化 JavaScript 和 TypeScript 运行时的深入解析
如何将Node.js库转换到Deno
由于Node和Deno的一些差异,一个库要想同时支持Node和Deno是需要一些改造的
ACK
2022/05/29
2.4K0
如何将Node.js库转换到Deno
Deno 运行时入门教程:Node.js 的替代品
这几天假期,我学习了一下 Deno。它是 Node.js 的替代品。有了它,将来可能就不需要 Node.js 了。
ruanyf
2020/02/14
1.7K0
Deno 运行时入门教程:Node.js 的替代品
Node.js 12中的ES模块[每日前端夜话0x9E]
多年来,在 JavaScript 生态中出现了不同形式的模块化方案。开发人员使用了明确定义的规范(如 AMD 或 CommonJS)以及简单的编码模式(如通过揭示模块模式(revealing module pattern))来得到模块化解决方案的好处。
疯狂的技术宅
2019/07/30
1.8K0
Hello, Deno
Deno的创始人和Node的创始人是同一个人。把Node的前两个字母和后两个字母调换了下,destroy node,要用Rust重写js/ts的运行时,来解决设计Node.js之初的缺陷,并要在Deno中解决这些问题。
后端云
2022/11/25
5291
Hello, Deno
【学不动了系列】之 Deno 入门 什么是Deno安装DenoDeno运行时(Runtime)Deno标准库第三方模块
希望大家不要被标题吓到,纯属为了吸引眼球?。。根据笔者这两天的学习感受,Deno 比 Node 更容易入门,如果你有 Node 的基础那更简单了,很多东西都是可以类比的,学起来豪不费力。个人认为现在正
MudOnTire
2020/07/31
1.4K0
【学不动了系列】之 Deno 入门
                            什么是Deno安装DenoDeno运行时(Runtime)Deno标准库第三方模块
他来了!性能吊打 Node.js 和 Deno 的新一代 javaScript 运行时!
刚开源不到一个月就获得了 19.5k star!看起来马上就会成为 Node.js 和 Deno 的一大竞争对手了!
ConardLi
2023/01/09
9390
他来了!性能吊打 Node.js 和 Deno 的新一代 javaScript 运行时!
聊聊Deno的那些事
? 这是第 99 篇不掺水的原创,想要了解更多,请戳上方蓝色字体:政采云前端团队 关注我们吧~ 本文首发于政采云前端团队博客:聊聊Deno的那些事 https://www.zoo.team/arti
政采云前端团队
2021/06/15
1K0
聊聊Deno的那些事
使用 Rollup + TypeScript 编写库
其中,dist 目录一般是通过 Rollup 等打包器打包后的入口文件,一般具有多种格式,以不同后缀命令,如: index.cjs.js index.esm.js。lib 和 esm 目录可以是 TypeScript 编译后生成的文件,目录下的结构基本和原项目结构相同,只是后缀变为 js,lib 一般为 CommonJS 格式,esm 为 ESModule 格式。而这些是一个库最基本的需要发布的文件。
Innei
2021/12/28
2.4K0
创建现代npm包的最佳实践
技术一直在变化,我们的流程和做法也需要跟上这些变化。因此,虽然npm已经有12年的历史了,但围绕 npm 包创建的做法应该更现代。
前端小智@大迁世界
2022/10/27
2.1K0
只需5分钟,让你了解未来可能推翻Node的新轮子 Deno 1.0
最近Nodejs作者Ryan Dahl发布了Deno 1.0正式版,圈子一下沸腾起来了。或许你早在两年前就听说了这个东西,但是也有人不知道这个东西是什么,干什么用的,所以今天我将为大家来简单的聊一下这个将来可能会推翻Node的新轮子。
吴佳
2022/09/26
6450
【Bun1.0】使用 Bun.js 构建快速、可靠和安全的 JavaScript 应用程序
Bun 是一个现代的JavaScript运行环境,如Node, Deno。主要特性如下: 启动速度快。更高的性能。完整的工具(打包器、转码器、包管理)。
微芒不朽
2023/09/20
8801
【Bun1.0】使用 Bun.js 构建快速、可靠和安全的 JavaScript 应用程序
deno入门教程
Deno 是一个由 Node.js 的创始人 Ryan Dahl 开发的现代化 JavaScript/TypeScript 运行时环境。它旨在提供安全、简单和高性能的方式来构建 JavaScript 和 TypeScript 应用程序。
用户6297767
2023/11/21
4260
deno入门教程
Deno 环境下的 TypeScript 开发入门手册
在本文中,我会让你快速了解 Deno,并把它与 Node.js 进行比较,以此构建你的第一个 REST API。
疯狂的技术宅
2020/05/26
1.5K0
什么是Deno,它与Node.js有什么不同?[每日前端夜话0xA1]
Node.js 的创建者 Ryan Dahl 花了一年半的时间研究 Deno(https://deno.land/),这是一个新的 JavaScript 运行时环境,可以解决Node 的所有问题。
疯狂的技术宅
2019/08/02
2.2K0
什么是Deno,它与Node.js有什么不同?[每日前端夜话0xA1]
一个新的跨 JavaScript 运行时的 Socket API!
今天和大家来一起聊一个即将推出的跨 JavaScript 运行时的 Socket API 。
ConardLi
2023/10/09
2910
一个新的跨 JavaScript 运行时的 Socket API!
推荐阅读
相关推荐
Bun:不仅是新的JavaScript运行时,并且重塑了JavaScript工具链
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验