如何在HTML中正确引入互相依赖的JavaScript文件(不合并文件)
解决JavaScript互相依赖文件的加载报错问题
问题说明
我需要引入两个互相依赖的JavaScript文件,直接按顺序引入会报错——source1.js需要source2.js里的内容,source2.js也依赖source1.js的内容。现在要在不合并文件(文件体积较大)的前提下,解决HTML中的正确引入问题。
相关代码示例:
HTML引入代码:
<head> <script src="source1.js"></script> <script src="source2.js"></script> </head>
source1.js代码:
function filtersomething() { // ... othersource.somefunction(); }
source2.js代码:
var columns = { text: filtersomething() }
可行解决方案
1. 异步加载+回调控制执行时机
通过动态创建script标签加载文件,监听加载完成事件,等两个文件都加载完毕后再执行依赖代码,避免加载时的未定义错误。
修改后的HTML代码:
<head> <script> let loadedCount = 0; const totalFiles = 2; // 所有文件加载完成后执行初始化 function initApp() { loadedCount++; if (loadedCount === totalFiles) { columns.text = filtersomething(); // 这里可以放入其他需要依赖两个文件的逻辑 } } // 加载source1.js const script1 = document.createElement('script'); script1.src = 'source1.js'; script1.onload = initApp; document.head.appendChild(script1); // 加载source2.js const script2 = document.createElement('script'); script2.src = 'source2.js'; script2.onload = initApp; document.head.appendChild(script2); </script> </head>
同时调整原JS文件,避免立即执行依赖代码:
source1.js保持函数定义不变source2.js改为先定义空对象:
var columns = {};
2. 使用ES模块语法
ES模块原生支持循环依赖处理,只需将两个文件改为模块,通过导入导出声明依赖关系。
修改source1.js:
import { somefunction } from './source2.js'; export function filtersomething() { // ... somefunction(); }
修改source2.js:
import { filtersomething } from './source1.js'; export const columns = { text: filtersomething() }; export function somefunction() { // ... }
然后新建一个入口模块main.js,在HTML中引入:
<head> <script type="module" src="main.js"></script> </head>
main.js内容:
import { columns } from './source2.js'; import { filtersomething } from './source1.js'; // 这里可以正常使用两个模块导出的内容,浏览器会自动处理依赖顺序
3. IIFE封装+延迟初始化
用立即执行函数把两个文件的内容封装起来,暴露全局变量,等所有文件加载完成后再执行依赖部分的代码。
修改source1.js:
window.source1 = (function() { function filtersomething() { // ... window.source2.somefunction(); } return { filtersomething: filtersomething }; })();
修改source2.js:
window.source2 = (function() { const columns = {}; function somefunction() { // ... } return { columns: columns, somefunction: somefunction }; })();
然后在HTML中添加初始化脚本:
<head> <script src="source1.js"></script> <script src="source2.js"></script> <script> // 两个模块都已加载完成,执行依赖赋值 source2.columns.text = source1.filtersomething(); </script> </head>
内容的提问来源于stack exchange,提问作者DavidDunham
相关产品推荐
相关产品推荐

