如何在HTML script标签中使用ES导出函数并兼容Jasmine单元测试?
解决ES模块函数在HTML全局脚本中无法访问的问题
为了给Jasmine单元测试提供可导入的add函数,我给它加上了export标记,但在HTML的普通<script>标签中调用该函数时,出现了Uncaught ReferenceError: add is not defined错误。
问题原因
当你用<script type="module">引入file.js时,它会以ES模块的方式运行——模块内部的变量和函数默认不会暴露到全局window对象中。而HTML里的普通<script>是在全局作用域运行的,自然找不到模块封装的add函数。
解决方案
方案1:将HTML中的脚本改为ES模块并导入函数
把页面里的普通<script>改成模块类型,导入add函数后,改用DOM方法绑定点击事件(模块内的函数不会自动挂载到全局,无法通过onclick属性直接调用):
修改后的index.html:
<!DOCTYPE html> <html lang="de"> <head> <meta charset="ISO-8859-1"> <title>Sample</title> </head> <body> <div> <input type="number" id="num1" placeholder="Erste Zahl"> <input type="number" id="num2" placeholder="Zweite Zahl"> <button id="addBtn">Addiere</button> <p id="additionResult"></p> </div> <script type="module"> import { add } from './file.js'; function addNumbers() { const num1 = parseFloat(document.getElementById('num1').value); const num2 = parseFloat(document.getElementById('num2').value); const result = add(num1, num2) document.getElementById('additionResult').innerText = `Ergebnis der Addition: ${result}`; } // 用DOM方法绑定点击事件 document.getElementById('addBtn').addEventListener('click', addNumbers); </script> </body> </html>
该方案保留了ES模块的特性,同时避免了全局污染。
方案2:在模块中将函数挂载到全局window对象
如果需要保留HTML原有结构(比如继续使用onclick属性),可以在file.js中把add函数同时挂载到window上,让全局作用域能直接访问:
修改后的file.js:
export function add(num1, num2) { const errorMessage = "Please enter a valid number"; if (isNaN(num1) || isNaN(num2)) { return errorMessage; } return num1 + num2 } // 将函数挂载到全局window对象 window.add = add;
这样HTML里的普通<script>能直接调用add函数,Jasmine测试也依然可以通过import导入该函数。
方案3:使用条件导出兼容模块和全局环境
如果需要兼顾多种运行环境,可以通过条件判断决定是否将函数挂载到全局:
修改后的file.js:
function add(num1, num2) { const errorMessage = "Please enter a valid number"; if (isNaN(num1) || isNaN(num2)) { return errorMessage; } return num1 + num2 } // 兼容模块和全局环境 if (typeof module !== 'undefined' && module.exports) { // Node.js或CommonJS模块环境 module.exports = { add }; } else if (typeof exports !== 'undefined') { // 其他模块环境 exports.add = add; } else { // 浏览器全局环境 window.add = add; } // 保留ES模块导出 export { add };
这种方式让add函数在模块环境和全局环境中都能正常使用,适合多场景复用的需求。
内容的提问来源于stack exchange,提问作者eXor420
相关产品推荐
相关产品推荐

