避免三方 js 文件被重复加载

更新日期: 2018-01-15 阅读次数: 5309 分类: Javascript

问题

想在 web 统一模板中引入 jquery 和 vuejs,但是部分页面之前已经引入了。 如果想引入这两个库,但是又不影响已存在的页面使用。例如,对 ajax 请求统一修改了 header 加入了 csrf token, 但是如果再次引入 jquery, 就会导致配置被重置。

思路

判断一个库是否已经引入,如果引入了,就不再引入。

实现

<script>
if (condition) {
    document.write('<script src=\"https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js\" type=\"text/javascript\"><\/script>');
}
</script>

condition 就是判断是否已经载入

if (typeof someObject != "undefined") {
   // do something
}

但是,document.write 引起了 console 报错

A Parser-blocking, cross site (i.e. different eTLD+1) script, https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js, is invoked via document.write. The network request for this script MAY be blocked by the browser in this or a future page load due to poor network connectivity. If blocked in this page load, it will be confirmed in a subsequent console message.See https://www.chromestatus.com/feature/5718547946799104 for more details.

https://stackoverflow.com/questions/39610829/a-parser-blocking-cross-origin-script-is-invoked-via-document-write-how-to-ci

Use asynchronous script loading, using <script src="..." async> or element.appendChild(),

document.write 被阻止的原因, document write 会阻塞页面 parser。

https://developers.google.com/web/updates/2016/08/removing-document-write

If your provider gives you a snippet that includes the document.write(), it might be possible for you to add an async attribute to the script element, or for you to add the script elements with DOM API's like document.appendChild() or parentNode.insertBefore() much like Google Analytics does.

<script>
var s=document.createElement('script');
s.src='someScript.js';
document.body.appendChild(s);
</script>

而 appendChild 不会,但是需要注意的是,这样引入的 js 文件相当于异步加载,无法保证执行顺序。

所以,当我需要顺序引入 jQuery, VueJS, 以及我自己的 js 文件时,这个加载顺序就非常不好保证。

最终方案

我决定修改后台架构,将已引入 js 的页面,做规范化。即,强制规范 js 的引入顺序。类似 wordpress 的实现方案。

通用 js 在 Laravel blade 模板中提前引入,自定义 js 滞后引入。不允许页面中随意引入 js。

测试 VueJS

已加载 VueJS 的页面

> typeof Vue
"function"

未加载 VueJS 的页面

> typeof Vue
"undefined"

测试 jQuery

已加载 jQuery 的页面

> typeof Vue
"function"

未加载 jQuery 的页面

> typeof Vue
"undefined"

爱评论不评论

近期节日

2019年07月23日 大暑
2019年07月30日 非洲妇女日
2019年08月01日 八一建军节
2019年08月06日 国际电影节
2019年08月07日 七夕
2019年08月08日 立秋
2019年08月15日 日本投降日
2019年08月15日 中元节
2019年08月23日 处暑
2019年09月03日 抗日胜利纪念日
2019年09月08日 白露
2019年09月08日 国际扫盲日
查看更多节日