如何将多个JS文件代码引入主HTML文件且无需顾虑文件引入顺序与函数声明顺序?
兄弟我太懂你这种烦恼了!之前把所有JS堆在HTML里怎么写都没事,拆分文件后反而被顺序问题搞头大,尤其是用了defer还踩坑的情况,我来给你捋捋怎么彻底解决~
先说说你现在踩的坑到底在哪
你用defer标记外部脚本没问题,但内联的主脚本没有defer属性,浏览器遇到它就会立刻执行——这时候file1.js和file2.js只是下载完成了,还没开始执行,自然找不到里面的函数。就算给内联脚本加defer,它也会跟着外部脚本按HTML里的引入顺序执行,要是主脚本在前面,照样会先跑而报错。
给你几个省心的解决方案
方案一:把内联主脚本转成外部文件,统一用defer(简单粗暴)
把你原来写在<script>标签里的主代码存成main.js,然后调整HTML里的脚本顺序,把main.js放在最后:
<script defer src="file1.js"></script> <script defer src="file2.js"></script> <script defer src="main.js"></script>
所有带defer的脚本会在DOM加载完成后,严格按HTML里的引入顺序执行,main.js最后跑,就能稳稳用到前两个文件的函数。不过这个方案还是要保证main.js在最后,要是想彻底摆脱顺序束缚,往下看更彻底的办法。
方案二:用ES Modules(最推荐,彻底告别顺序焦虑)
这是现代前端的标准做法,ES模块天生支持依赖管理,完全不用管HTML里的脚本引入顺序。
首先给所有脚本加上type="module"属性:
<script type="module" src="file1.js"></script> <script type="module" src="file2.js"></script> <script type="module"> // 这里写你的主代码,直接用file1、file2里的函数就行 funcFromFile1(); funcFromFile2(); </script>
不过更规范的做法是显式导入依赖,这样哪怕HTML里的文件顺序乱了也没关系,浏览器会自动处理:
比如file1.js里导出了funcA,file2.js导出了funcB,主脚本可以这么写:
<script type="module"> import { funcA } from './file1.js'; import { funcB } from './file2.js'; // 随便调用,完全不用管HTML里file1和file2谁在前谁在后 funcA(); funcB(); </script>
这种方式下,浏览器会先去加载所有导入的依赖文件,等它们都准备好再执行主代码,顺序问题直接消失。
方案三:用DOMContentLoaded事件兜底(兼容旧环境)
如果暂时不想用ES模块,那就把主代码放到DOMContentLoaded事件回调里,这样所有defer脚本都已经执行完毕了:
<script> document.addEventListener('DOMContentLoaded', function() { // 这里写原来的主代码 // 此时file1.js和file2.js里的函数都已经定义好了 }); </script> <script defer src="file1.js"></script> <script defer src="file2.js"></script>
不过这个方案还是要注意file1.js和file2.js之间的依赖顺序(比如如果file2依赖file1,那file1得在前面引入),但至少解决了主代码和外部文件的顺序冲突。
总结
最省心的肯定是用ES Modules,既能明确依赖关系,又彻底不用管HTML里的脚本顺序,是现在前端开发的主流方式。
备注:内容来源于stack exchange,提问作者LUN

