如何让同一段Vanilla JS脚本同时支持脚本标签引入与ES6模块导出?
实现Vanilla JS脚本同时支持全局引入和模块导出
这个需求其实挺常见的——既要保留原来通过普通script标签引入自动执行的功能,又要能作为ES模块被webpack等工具导入调用。你的思路方向是对的,但有个关键问题:直接在普通脚本里写export default会导致浏览器报错,因为非模块类型的script标签不识别ES模块语法。
最稳妥的解决方案是采用**UMD(Universal Module Definition)**模式,它能同时兼容浏览器全局环境、CommonJS和AMD模块系统,完美适配你的两种使用场景。
完整的兼容代码
(function (root, factory) { // 适配AMD模块(比如RequireJS) if (typeof define === 'function' && define.amd) { define([], factory); } // 适配CommonJS模块(比如Node.js或webpack) else if (typeof module === 'object' && module.exports) { module.exports = factory(); } // 适配浏览器全局环境(普通script标签引入) else { root.MainFunction = factory(); // 判断DOM是否已加载,自动执行函数 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', root.MainFunction); } else { // DOM已就绪,直接执行 root.MainFunction(); } } // 全局对象适配:浏览器用self/window,Node用global }(typeof self !== 'undefined' ? self : this, function () { // 定义你的核心函数 function MainFunction() { // 这里写你的业务逻辑:检查特定DOM节点等 console.log('MainFunction 执行了'); } return MainFunction; }));
代码解释
- 立即执行函数(IIFE):包裹整个逻辑,避免污染全局作用域。
- 环境判断:
- 先判断是否是AMD环境(比如用RequireJS的场景),用
define导出函数。 - 再判断是否是CommonJS环境(比如webpack打包时会识别这种导出),用
module.exports导出。 - 最后是浏览器全局环境:把函数挂载到
window上,同时自动检测DOM状态,确保DOM就绪后执行函数。
- 先判断是否是AMD环境(比如用RequireJS的场景),用
- 核心函数封装:把
MainFunction放在factory函数里,确保在所有环境下都能正确返回。
使用验证
- 普通script标签引入:直接用
<script src="your-script.js"></script>引入,页面加载后会自动执行MainFunction。 - webpack模块导入:在你的打包文件里这样使用,完全没问题:
import MainFunction from 'myclassicscript'; // 按需调用 MainFunction();
你原来代码的问题
你尝试的写法里直接在末尾加export default,当用普通script标签引入时,浏览器会抛出语法错误,因为非模块脚本不支持export语句。UMD模式通过环境判断规避了这个问题,同时覆盖了所有你需要的使用场景。
内容的提问来源于stack exchange,提问作者tarponjargon
相关产品推荐
相关产品推荐

