Cap1 前言
在Nuxt.js打包时候发现vendors
文件实在是太大,看了官方文档发现新版又不支持老的Api,所以寻找一上午也没找到很好的方案,目前把一些类库文件抽取出来直接CDN加载就行,但原本以为这是很简单事情,可是中间又遇到不少问题,例如脚本和脚本直接的依赖关系等。
Cap2 HTML5
其实在HTML5也有相关的标签属性可以实现:
<script src="//code.jquery.com/jquery-1.11.0.min.js" async></script>
async 属性规定一旦脚本可用,则会异步执行。
注释:async 属性仅适用于外部脚本(只有在使用 src 属性时)。
注释:有多种执行外部脚本的方法:
- 如果 async="async":脚本相对于页面的其余部分异步地执行(当页面继续进行解析时,脚本将被执行)
- 如果不使用 async 且 defer="defer":脚本将在页面完成解析时执行
- 如果既不使用 async 也不使用 defer:在浏览器继续解析页面之前,立即读取并执行脚本
Cap3 编程方式
(function() {
var script = document.createElement("script");
script.type = "text/javascript";
script.async = true;
script.src = "//code.jquery.com/jquery-1.11.0.min.js";
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script);
})();
这种动态插入脚本的方法基本上主流写法。
Cap4 支持回调函数的编程方式
如果需要在插入脚本执行代码执行下一步操作:
function loadScript(url, callback) {
var script = document.createElement("script");
script.type = "text/javascript";
script.async = true;
if (script.readyState) {
script.onreadystatechange = function () {
if (script.readyState == "loaded" || script.readyState == "complete") {
script.onreadystatechange = null;
if (callback && typeof callback === "function") {
callback();
}
}
};
} else {
script.onload = function () {
if (callback && typeof callback === "function") {
callback();
}
};
}
script.src = url;
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script);
}
理论上这样写法满足大量的需求了,但是在我这里遇到一个问题:
如果一层一层回调下去,岂不是难以解读。所以还需要一个更优雅的写法:
Cap5 支持回调函数的ES8风格编程方式
async function loadScripts (scripts) {
function get (src) {
return new Promise(function (resolve, reject) {
var el = document.createElement("script");
el.async = true;
el.addEventListener("load", function () {
resolve(src);
}, false);
el.addEventListener("error", function () {
reject(src);
}, false);
el.src = src;
(document.getElementsByTagName("head")[0] || document.getElementsByTagName("body")[0]).appendChild(el);
});
}
const myPromises = scripts.map(async function (script, index) {
return await get(script);
});
return await Promise.all(myPromises);
}
到上面脚本来看,无论哪方面都可以满足了:
loadScripts([
"https://static.zinoui.com/1.5/compiled/zino.svg.min.js",
"https://static.zinoui.com/libs/jquery/jquery.min.js"
]).then(function () {
return loadScripts(["https://static.zinoui.com/1.5/compiled/zino.chart.min.js"]);
}).then(function () {
$("#chart").zinoChart(settings);
});