如何打一个既支持cjs,又支持esm的npm包?

死磕Node模块兼容性,ESM和CJS我全都要! 在Node版本13.2.0(2019年)之前,我们一般使用CJS(CommonJS)模式在代码中引入包,它的加载是同步的,在整个模块加载完成后,才会执行后续代码。而ESM(ECMAScript Modules)最早在2015年就被使用在浏览器中,在script标签中增加type="module"这个属性,然后引入模块进行使用。在Node 13.2版本后,Node也支持使用ESM进行导入模块的操作,那么如何对其二者进行一个兼容?请接着往下看。 阅读详情

模块化是一个老生常谈的问题了,打包工具层出不穷。

那么,如何利用这些打包工具去打出既支持cjs,又支持esm的npm包呢。

这篇文章不涉及概念,是一些打包实测。

demo repo: https://github.com/FrankKai/npm-bundle-demo

可以clone下来,本地构建测试。

  • tsc
  • rollup
  • webpack
  • esbuild

tsc

  • tsconfig.json
  • tsconfig-esm.json
  • package.json
cjs

tsconfig.json

{
  "compilerOptions": {
    "target": "ES2015",
    "module": "commonjs",
    "outDir": "./dist/cjs",
    "esModuleInterop": true,
    "moduleResolution": "node"
  }
}
esm

tsconfig-esm.json

{
  "extends": "./tsconfig.json",

  "compilerOptions": {
    "target": "es2015",
    "module": "es2015",
    "outDir": "./dist/esm",
    "moduleResolution": "node"
  }
}
package.json
{
  "main": "./dist/cjs/index.js",
  "module": "./dist/esm/index.js",
  "scripts": {
    "build": "rm -rf dist && tsc -p tsconfig.json && tsc -p tsconfig-esm.json"
  },
}

rollup

  • rollup.config.js
  • package.json
rollup.config.js
export default [
  {
    input: "src/index.js",
    output: [
      { file: "dist/index.cjs.js", format: "cjs" },
      { file: "dist/index.esm.js", format: "es" },
    ],
  },
];
package.json
{
  "main": "dist/index.cjs.js",
  "module": "dist/index.esm.js",
  "scripts": {
    "build": "rollup -c",
  },
}

webpack

  • webpack.config.js
  • package.json
webpack.config.js
const path = require("path");

module.exports = {
  mode: 'none',
  entry: {
    "index.cjs": {
      import: './src/index.js',
      library: {
        type: 'commonjs2',
      },

    },
    "index.esm": {
      import: './src/index.js',
      library: {
        type: 'module',
      },
    },
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: "[name].js",
    clean: true,
  },
  experiments: {
    outputModule: true
  }
};
package.json
{
  "main": "dist/index.cjs.js",
  "module": "dist/index.esm.js",
  "scripts": {
    "build": "webpack",
  },
  "devDependencies": {
    "webpack": "^5.38.1",
    "webpack-cli": "^4.7.2"
  }
}

esbuild

  • package.json
{
  "main": "dist/index.cjs.js",
  "module": "dist/index.esm.js",
  "scripts": {
    "esbuild:cjs": "esbuild ./src/index.js --bundle --outfile=dist/index.cjs.js --format=cjs",
    "esbuild:esm": "esbuild ./src/index.js --bundle --outfile=dist/index.esm.js --format=esm",
    "build": "npm run esbuild:cjs && npm run esbuild:esm"
  },
  "devDependencies": {
    "esbuild": "^0.14.49"
  },
}
ESM、CJS与UMD模块格式的深度对比与实战选型指南 本文深度对比了ESM、CJS与UMD三大JavaScript模块格式的核心特性与适用场景。ESM作为官方标准,支持静态分析和Tree Shaking,是现代前端开发的首选;CJS动态加载,在Node.js生态中根深蒂固;UMD则提供广泛的兼容性。文章提供了实战选型指南,帮助开发者根据项目类型、目标环境及工具链做出最佳决策。 阅读详情

相关推荐

如何创建一个同时支持 CommonJS(CJS)和 ECMAScript 模块(ESM)的 npm 包?

CJS 是 Node.js 默认的模块系统,而 ESM 是在浏览器和现代 JavaScript 运行时环境中广泛使用的模块系统。需要注意的是,为了使你的包能够在浏览器环境中正常工作,你可能还需要在构建过程中进行其他的优化和转换。通过以上步骤,你的 npm 包将同时支持 CJS 和 ESM 模块系统。用户可以根据他们使用的环境选择适当的模块导入方式来使用你的包。接下来,安装一些必要的依赖项来帮助你在构建过程中处理模块系统的差异。的文件夹,并将你的源代码文件(例如。的文件,并在其中编写你的代码。

EuForth的博客 359

nodejs中cjs和esm模块相互操作(记录)

注:现在有了类似rollup类的打包工具,可以在开发源码时完全使用纯esm规范写,而打包时选择生成cjs规范的包。

柒君的博客 1604

哨兵一号数据snap预处理_利用SNAP软件进行Sentinel-1A卫星微波影像的预处理

利用SNAP软件对雷达影像进行预处理,主要包括热噪声去除、轨道文件校正、辐射定标、滤波校正、多普勒地形校正,最终获得入射角和后向散射信息。数据:本次实验所用数据为哨兵一号(Sentinel-1A)干涉宽幅模式(Interferometric Wideswath,IW)下经过多视处理和地距转换的GRD格式产品一般处理流程如下:0 SNAP软件安装软件安装:安装成功后打开SNAP后如图所示:1 数据...

weixin_30000407的博客 1万+

vue报错 运行npm run dev报cjs.js缺失

vue 运行 npm run dev 或者npm run serve 报core-js/modules/es6.array.find in ./node_modules/_cache-loader@2.0.1@cache-load,这是因为当前模块没有升级,或者下载掉包, 只要重新下载安装就可以了,执行 npm install core-js@2 //更新版本 以下是报错部分内容 ...

csz_12345的博客 7392

卡方检验的隐藏逻辑:为什么正态分布的平方和如此重要?

本文深入探讨了卡方检验的核心逻辑,揭示了正态分布平方和在统计检验中的重要性。通过分析卡方分布与伽马分布的关系,以及实际应用案例,帮助读者理解卡方检验的原理、局限及高级应用场景,为数据分析提供有力工具。

3a9bq4r8t2y的博客 208

BioEmu:微软黑科技炸场!生成式AI重构蛋白质模拟:千倍效率碾压传统计算,新药研发周期砍半

BioEmu 是微软推出的生成式深度学习系统,可在单个 GPU 上每小时生成数千种蛋白质结构样本,支持模拟动态变化、预测热力学性质,并显著降低计算成本。

士多啤梨先生の博客 1098

webpack打包前端Vue

webpack是一个现代JavaScript应用程序的静态模块打包器(module bundler) 。需要安装 npm install webpack -g npm install webpack-cli -g 在项目根目录下创建 webpack.config.js 配置文件 本项目打包所需配置 var path=require('path') module.exports={ entry: path.join(__dirname, 'src/main.js'), // 入口文件 output

qq_49785669的博客 155

小米路由器安装Misstar tools 和MIXBOX

1.该教程适用于如下路由器: 小米路由器1代硬盘版(R1D) 小米路由器mini(R1CM) 全新小米路由器硬盘版(R2D) 小米路由器3(R3) 小米路由器3G(R3G) 小米路由器Pro(R3P) 小米路由器HD(R3D) 2.Misstar2.0在线安装 方法如下: 1.根据路由器对应文件解压文件,把解压目录(比如小米3路由器为R3)和offline_install.sh到U盘根目录,并插入路由器 2.ssh登录后,cd到U盘的目录,比如小米3路...

wybarcelona的博客 2万+

Deep-Live-Cam:单张照片本地实时换脸完整教程(免费开源)

Deep-Live-Cam 是一款免费的本地实时换脸工具:一张正脸照片即可替换摄像头或视频里的人脸,不经过任何在线服务。按本文步骤操作,你可以跑通摄像头实时换脸预览,并掌握高频命令行参数。 ## 效果速览 先给结果:选一张照片、选一个摄像头,预览里的人脸就被换成源照片上的脸;同一条流水线也适用于整段视频。首次加载模型约需 10–30 秒,无独显的纯 CPU 环境在 480p–720p 下也能勉

gitblog_00328的博客 775

基于Flink的风控系统

可以使用Flink-Stream进行实时数据流的检测和处理,或者使用Flink-Kafka集群进行数据转发和存储,然后使用Flink-Table进行数据表的查询和分析。在Flink中,可以使用Flink-Stream进行数据流的处理,或者使用Flink-Kafka进行Kafka数据流的消费和处理。Flink的运行时本身也支持迭代算法的执行。可以使用Flink-Stream进行实时数据流的检测和处理,或者使用Flink-Kafka集群进行数据转发和存储,然后使用Flink-Table进行数据表的查询和分析。

m0_68231587的博客 1875

C++游戏开发入门:从环境配置到第一个完整项目

C++ 作为游戏开发领域的关键语言,其学习路径常因语法枯燥而令初学者却步。以项目驱动的方式学编程,能帮助学习者将变量、循环、函数、指针等基础概念融入实际游戏逻辑中,获得即时反馈与完整项目经验。掌握合适的开发环境是高效实践的前提,例如在 Windows 下使用 VS Code 搭配 MinGW-w64 编译器,配合调试器与构建脚本,即可搭建轻量可扩展的 C++ 游戏开发工作流。此类课程通常面向无基础人群,从控制台小游戏逐步过渡到带游戏循环的完整作品,过程中还需关注性能观察、素材授权与版本管理。无论你是刚接触编

weixin_30621959的博客 541

基于MCP协议的NPM智能分析引擎:为AI编程助手赋能深度依赖管理

在现代前端与Node.js开发中,依赖管理是工程实践的核心环节,涉及包选择、安全审计、版本兼容性及性能影响评估等多个维度。其原理在于通过自动化工具对NPM生态的元数据进行结构化查询与分析,将分散的包信息、漏洞数据库、捆绑包指标等整合为可操作的决策依据。这项技术的核心价值在于实现“安全左移”与“效率提升”,将依赖评估环节前置到开发工作流中,通过实时、多维度的分析,帮助开发者在引入依赖前识别风险、对比方案。典型的应用场景包括技术栈升级的路径规划、新包引入的尽职调查、日常开发中的即时兼容性检查等。本文聚焦的`al

weixin_30635053的博客 370

点云中概念:匹配、配准、融合

匹配,是寻找与一幅图相似的图像(不对寻找到的图像做矫正)。 配准,是寻找相似图像但是变形后的图像(需要做一些旋转之类的校正变换)。 融合,是多幅图像连接成一幅大图,视频集成中用的比较多。 1)匹配: 2)配准: 比如由于固定式激光雷达受测量方式的限制和被测物体集合形状的限制,固定的话一次只能扫描被测物体有限范围的点云数据(比如一个面??),这需要在多个视角下进行多次扫描(就是将激光雷达前后左右四个面都扫一下??对的),然而每个视角下得到点云数据都具有独立的坐标系,无法直接进行拼接(拼接就是将四个面

m0_37957160的博客 1万+

Vite 6 升级指南:CJS 和 ESM 的爱恨情仇

如果说 CJS 是 JavaScript 模块化的“老干部”,那么 ESM 就是新时代的“带头大哥”。Vite 6 的升级彻底向前迈了一步,把 CJS 甩在了身后,给前端开发带来了更快的启动、更好的兼容性和更清爽的代码。今天我们就来聊聊这俩模块规范的区别,以及如何在 Vite 6 的“强制迁移令”下,优雅地抛弃 CJS,投入 ESM 的怀抱。所以,与其挣扎着想办法让 CJS 继续活下去,不如早早投靠 ESM,跟上 Vite 6 的节奏,让你的项目跑得更快更顺畅!好消息是,这些改动让前端环境更清爽、更高效。

常备不懈 1593

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

详解ESM和CJS

ESM(ECMAScript Modules,ES 模块)和 CJS(CommonJS)是 JavaScript 中两种主流的模块系统。CJS:诞生于 ES6 之前(2009 年),是 Node.js 的默认模块系统,主要为服务器端(Node.js)设计,适用于同步加载场景(因为服务器文件存储在本地,同步加载开销低)。浏览器原生不支持 CJS,需通过 Webpack 等工具转译。

ningsheng的博客 949

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

npm-esm-vs-cjs 项目教程

npm-esm-vs-cjs 项目教程 项目介绍 npm-esm-vs-cjs 是一个开源项目,旨在收集和分析公共 npm 注册表中 ESM(ECMAScript 模块)和 CJS(CommonJS)的使用情况。该项目通过爬取高影响力 npm 包的最新发布版本,分析其 package.json 文件,生成关于 ESM 和 CJS 使用情况的统计数据。 项目快速启动 克隆项目 首先,克隆项目到本地:...

gitblog_00843的博客 871

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

从0到发布:以specificity为例的TypeScript ESM/CJS双格式npm包完整指南

这是一份面向初学者的实战教程。我们以开源项目 **specificity** —— 一个用于计算 CSS 选择器特异性(权重)的 JavaScript 模块 —— 为例,手把手带你搭建、测试并发布一个同时支持 ESM 与 CommonJS 双格式的 TypeScript npm 包,覆盖从工程配置到 npm publish 的全流程。 ## 为什么 npm 包要做 ESM / CJS 双格式?

gitblog_00013的博客 347

npm-esm-vs-cjs 使用指南

npm-esm-vs-cjs 使用指南 本指南将带你深入了解 npm-esm-vs-cjs 这一开源项目,它分析并记录了公共 npm 仓库中 ESM(ECMAScript 模块)与 CJS(CommonJS)模块的使用比例。这个项目对于关注 Node.js 生态系统从 CJS 向 ESM 转型的开发者尤其有用。 1. 项目目录结构及介绍 项目遵循简洁明了的组织结构,以下是一些关键目录和文件的说明:...

gitblog_00075的博客 455

Midway validation-* 包构建产物测试实战:从 test:dist 到捕获 ESM/CJS 互操作 Bug

本文以 Midway 开源仓库中 `openspec/changes/archive/2026-01-25-add-validation-dist-tests` 的实施方案为主线,完整还原为 `@midwayjs/validation-zod`、`@midwayjs/validation-zod4`、`@midwayjs/validation-joi`、`@midwayjs/validation-

gitblog_00468的博客 998

node-postgres 的 ESM/CJS 双模块导出兼容性测试实践:深入 pg-esm-test 内部测试包

node-postgres 采用 monorepo 架构,`pg` 主包及其周边库(`pg-pool`、`pg-cursor`、`pg-protocol`、`pg-native`、`pg-cloudflare` 等)需要同时支持 ESM(`import`)与 CommonJS(`require`)两种模块体系,而这正是 npm 生态中最容易踩坑的"双包"问题。`pg-esm-test` 就是 no

gitblog_00075的博客 898

Node.js 模块简史:cjs、打包工具和 esm

作者:@Marco Gonzalez原文:https://dev.to/marcogrcr/nodejs-a-brief-history-of-cjs-bundlers-and-esm-2nlb点击上方程序员成长指北,关注公众号 回复1,加入高级Node交流群背景Node.js 作为现代 Web 开发的核心技术之一,其模块系统经历了从 CommonJS(cjs)到 ECMAScript 模块(e...

程序员成长指北 458

Node.js 模块系统:CJS 与 ESM 详解

Node.js模块系统差异与使用规范总结 Node.js支持CommonJS(CJS)和ESM两套模块系统,主要区别如下: CommonJS(CJS) 默认使用,文件后缀为.js或.cjs 语法:require()/module.exports 路径要求:本地文件必须带./前缀,后缀可省略 动态加载,运行时执行 ESM 需设置package.json中"type":"module"或使用.mjs后缀 语法:import/export 路径要求:必须带./前缀和完整后缀名(.js不能省略) 静态加载,支持tr

weixin_42174823的博客 274

NPM 包开发与优化全面指南

Hey, 我是Immerse系列文章首发于【Immerse】,更多内容请关注该网站转载说明:转载请注明原文出处及版权声明!UMD 是一种允许模块在多种环境(CommonJS、AMD、全局变量)中工作的模式。// AMD} else {// 浏览器全局变量});

Immerse的 Blog 1431

使用 pkgroll 编译发布 tsx 项目中的 npm 包:从 tsconfig 到 dist 的完整构建指南

tsx 是一款让 Node.js 直接运行 TypeScript 文件的运行时工具,但它**并不负责**把 TypeScript 编译成可发布的 JavaScript 产物。本文以 tsx 官方文档的 Compilation 章节为主线,系统讲解如何用官方推荐的打包器 **pkgroll** 完成 npm 包的编译发布,覆盖入口声明(`exports`/`main`/`bin`)、双模块(CJS

gitblog_00191的博客 1082
上一篇: 浅谈业务中台前端设计
下一篇: 轻松在本地搭建DeepSeek:Ollama + deepseek-r1:7b + anythingLLM
趁你还年轻233
博客等级 码龄9年 49粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

趁你还年轻233

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值