首页 > 编程语言 >创建一个双模式跨运行时的 JavaScript 包

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

时间:2023-12-26 21:47:09浏览次数:46  
标签:npm Node 双模式 创建 JavaScript js base64 Deno

本文将指导你发布双模式、跨运行时的 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上找到。

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

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

添加脚本

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

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

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

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/[email protected]/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 构建的配置示例:

{
    /* ... 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 版本的代码,配置如下:

// 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。

// 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 目标所使用的。

// /src/base64.single.js
import base64 from "./base64.js";
export default base64;

package.json

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

{
  /* ... 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 库的工作原理将软件包发布到 deno.land/x

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

总结

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

标签:npm,Node,双模式,创建,JavaScript,js,base64,Deno
From: https://www.cnblogs.com/chuckQu/p/17929422.html

相关文章

  • C练习——不创建临时变量,交换两个数值
    该问题面试可能会问方法一(有缺陷,int型数值有上限,a+b可能超范围)//int型数值有上限,a+b可能超范围#include<stdio.h>intmain(){inta=2;intb=3;printf("交换前:%d%d\n",a,b);a=a+b;//3+2b=a-b;//3+2-3a=a-b;//3+2-2......
  • Flutter 创建一个交错效果的侧边栏菜单
    一、创建一个没有动画效果的菜单import'package:flutter/material.dart';classMenuextendsStatefulWidget{constMenu({super.key});@overrideState<Menu>createState()=>_MenuState();}class_MenuStateextendsState<Menu>{staticc......
  • oracle创建非容器数据库
    1、 Oracle19crpm安装后配置的示例数据库是容器数据库,大部分系统中使用的还是以前的非容器数据库。在安装完rpm包后,可以使用dbca根据自己的需要创建数据库了,创建之前,先删除已经创建的示例数据库./oracledb_ORCLCDB-19cdelete2、编辑一个dbca.rsp文件,用来生成数据库实例(文件......
  • ArcGIS API for JavaScript 4.x 免登录调用arcgis online私有服务
    APIkeys|ArcGISDevelopers 前言 本来以为普通用户调用服务只能依靠登录,仔细研究了一下可以通过key来实现免登录调用服务。背景最近在做一个BIM结合GIS的Demo,先通过arcgispro将.rvt文件配准到实际位置,然后打包成slpk文件,拖拽到arcgisonline发布出来,最后在前端加载。 ......
  • EMQX集群的创建和使用
    EMQX的安装Ubuntu本页将指导您如何在Ubuntu系统中下载安装并启动EMQX。通过Apt源安装EMQX支持通过Apt源安装,免除了用户需要手动处理依赖关系和更新软件包等的困扰,具有更加方便、安全和易用等优点。如希望通过Apt源安装EMQX,可参考如下步骤。1.通过以下命令配置EMQ......
  • 在 Python 中,​​?:​​​ 符号并不是一个有效的运算符。这个符号在其他一些编程语言
    在Python中,?:符号并不是一个有效的运算符。这个符号在其他一些编程语言中,如JavaScript或C,被称为条件(三元)运算符。然而,在Python中,我们使用if-else表达式来达到相同的目的。例如:x=10y=20print("xisgreater")ifx>yelseprint("yisgreater")在上述代码中,如果......
  • 关于SAP-DB-服务器组-创建SAPHanaTopology-资源报错-Unable to find agent SAPHanaTop
    SAPHanaTopology资源收集每个节点上的SAPHANA系统复制的状态和配置。为配置以下属性SAPHanaTopology。运行以下命令来创建SAPHANATopology资源:笔者在SAP-DB-服务器组-pacemaker集群中,创建SAPHanaTopology资源时,使用如下命令:[root@db01qq-5201351]#pcsresourcecreate......
  • Java,反射创建对象的两种方式
    跟着孙哥学Spring,b站:https://www.bilibili.com/video/BV185411477k/?spm_id_from=333.337.search-card.all.click在Java中,我们可以使用反射来创建对象。这里有两种主要的方式:1.使用Class.forName().newInstance()方法这种方式是使用默认的无参数构造函数来创建对象。如果......
  • C# 中使用 using 关键字和不使用 using 关键字创建 FileStream
    在C#中使用using关键字和不使用using关键字创建FileStream实例之间有一些区别。使用using关键字:using(FileStreamfileStream=newFileStream(filePath,FileMode.Open,FileAccess.Read)){//使用fileStream进行操作}using关键字用于创建FileStream......
  • JavaScript基础语句和window对象
    ifelse语句varsum=190varyouhuisum//赋予一个容器if(sum>=200){youhuisum=sum-10console.log(111)}else{//如果上面if不满足则都执行else语句......