ESM Wrapper 是适配非标准模块的核心方案:先识别CJS/UMD/全局变量格式,再分别编写导入重导出的包装文件;现代构建工具如Vite、Webpack、esbuild也内置自动转换能力。

ES Module(ESM)在 Node.js 或现代浏览器中默认只支持标准的 export / import 语法,而很多第三方库(尤其是较老或面向 CommonJS 生态的库)发布的是 UMD、IIFE 或 CommonJS(CJS)格式,没有原生 export。这时直接 import 会报错(如 Cannot use import statement outside a module 或 Module not found)。解决的核心思路是:**用 Wrapper 将非标准模块“适配”成合法 ESM**。
识别目标库的输出格式
在写 Wrapper 前,先确认库实际导出方式。常见情况有:
-
CJS 模块:导出为
module.exports = xxx或exports.xxx = ...,典型如早期 Lodash、Moment.js; -
UMD/IIFE 全局变量形式:在浏览器中挂载到
window(如window.Chart),无export,典型如 Chart.js v2、Three.js 旧版; -
无模块声明但含
this或globalThis绑定:需手动创建命名空间并导出。
为 CJS 库编写 ESM Wrapper
Node.js(v14.13+)和打包工具(Vite、Webpack、esbuild)都支持 import * as pkg from 'pkg' 自动转换 CJS,但若遇不兼容或需精确控制,可手写 Wrapper:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 新建
wrap-lodash.js文件,内容为:
import _ from 'lodash';
export default _;
export const { debounce, throttle, cloneDeep } = _; - 注意:不能直接
export * from 'lodash'(CJS 不支持),必须先import再解构/重导出; - 若库使用
require动态加载或有副作用(如修改全局),Wrapper 中需保留其初始化逻辑。
为 UMD/全局变量库编写 ESM Wrapper(浏览器环境)
适用于通过 CDN 引入或打包时未被解析的脚本(如 <script src="chart.js"></script>):
立即学习“Java免费学习笔记(深入)”;
- 新建
chart-wrapper.js:
// 确保 script 已加载(可用 loadScript 或检查 window.Chart)
const Chart = window.Chart;
export default Chart;
export const { Chart as defaultChart, registry } = Chart; - Vite/Webpack 中可通过
define或externals配置跳过打包,让 Wrapper 只负责桥接; - 若需按需加载,可在 Wrapper 内封装动态
import()+then提取属性,再统一导出。
利用构建工具自动处理(推荐优先尝试)
多数现代工具已内置 CJS→ESM 适配能力,无需手写 Wrapper:
-
Vite:默认启用
resolve.alias和optimizeDeps.include,对 CJS 库自动做静态分析与转换; -
Webpack 5+:启用
experiments.topLevelAwait: true并配合resolve.fullySpecified: false可更好兼容混合模块; -
esbuild:通过
--format=esm和插件(如esbuild-plugin-commonjs)实现运行时注入; - 遇到 “not an ESM file” 报错时,优先查
package.json的"type": "module"是否缺失,或尝试加.mjs后缀强制识别。

















