编写可同时作为ES6模块与普通script标签使用的JS库是否可行?
JS库同时适配传统script引入与ES Module导入方案
完全可以仅编写一套核心代码,通过环境判断逻辑自动适配两种引入方式,无需分别维护两份代码。
核心实现思路
在库的入口位置增加运行环境识别逻辑,针对不同的加载场景把库的暴露内容挂载到对应位置:
- ES Module加载场景下,通过标准
export语法导出内容 - 传统
<script src>直接引入的浏览器场景下,把库内容挂载到window全局对象上 - 还可以额外兼容CommonJS、AMD等其他模块规范,覆盖更多使用场景
手写兼容示例
以下是一个最小实现示例,你可以直接套用在自己的库中:
// 你的库核心业务代码 function method() { console.log('库方法被调用') } const myLib = { method } // 环境适配逻辑 if (typeof module !== 'undefined' && module.exports) { // 适配CommonJS环境(Node.js、webpack等打包工具场景) module.exports = myLib } else if (typeof define === 'function' && define.amd) { // 适配AMD规范(require.js等场景) define(() => myLib) } else if (typeof window !== 'undefined') { // 适配传统script引入场景,挂载到全局window window.myLib = myLib } // 适配ES Module导入场景 export { method }
工程化自动生成兼容包
如果你使用Rollup、Vite等现代前端构建工具,无需手写上述适配逻辑,只需正常编写ES Module格式的源码,在构建配置中指定输出UMD格式并声明全局变量名,构建工具会自动生成兼容所有场景的产物。
以Vite配置为例:
// vite.config.js import { defineConfig } from 'vite' export default defineConfig({ build: { lib: { entry: 'src/index.js', // 库的入口文件路径 name: 'myLib', // 传统script引入时挂载到window上的全局变量名 formats: ['umd'] // UMD格式天然兼容ES Module、script引入、CommonJS等所有场景 } } })
使用效果验证
- 传统script引入方式:
<script src="https://你的库地址"></script> <script> // 直接调用全局挂载的方法 myLib.method() </script>
- ES Module引入方式:
<script type="module"> import { method } from "https://你的库地址" // 直接使用导入的方法 method() </script>
内容的提问来源于stack exchange,提问作者Vlad
相关产品推荐
相关产品推荐

