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

更新日期: 2018-01-15 阅读次数: 6897 分类: 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"

关于作者

我是来自山东烟台的一名开发者,喜欢瞎折腾,顺便记记笔记。有敢兴趣的话题,欢迎加微信 zhongwei 聊聊。 白天工地搬砖,晚上哄熊孩子,可能回复有点慢,见谅。 查看更多联系方式

相关文章

爱评论不评论

近期节日

2020年02月24日 第三世界青年日
2020年02月24日 龙抬头
2020年02月28日 世界居住条件调查日
2020年03月01日 国际海豹日
2020年03月03日 全国爱耳日
2020年03月05日 学雷锋日
2020年03月05日 惊蛰
2020年03月08日 三八妇女节
2020年03月12日 植树节
2020年03月14日 白色情人节
2020年03月15日 消费者权益日
2020年03月17日 国际航海日
查看更多节日