UNPKG

h5-cli

Version:

hello

320 lines (267 loc) 8.1 kB
"use strict"; /** * The Sea.js plugin for concatenating HTTP requests */ var Module = seajs.Module; var FETCHING = Module.STATUS.FETCHING; var data = seajs.data; var comboHash = data.comboHash = {}; var comboSyntax = ["??", ","]; var comboMaxLength = 2000; var comboExcludes; var comboSuffix; seajs.on("load", setComboHash); seajs.on("fetch", setRequestUri); function setComboHash(uris) { var len = uris.length; if (len < 2) { return; } data.comboSyntax && (comboSyntax = data.comboSyntax); data.comboMaxLength && (comboMaxLength = data.comboMaxLength); data.comboSuffix && (comboSuffix = data.comboSuffix); comboExcludes = data.comboExcludes; var needComboUris = []; for (var i = 0; i < len; i++) { var uri = uris[i]; if (comboHash[uri]) { continue; } var mod = Module.get(uri); // Remove fetching and fetched uris, excluded uris, combo uris if (mod.status < FETCHING && !isExcluded(uri) && !isComboUri(uri)) { needComboUris.push(uri); } } if (needComboUris.length > 1) { paths2hash(uris2paths(needComboUris)); } } function setRequestUri(data) { data.requestUri = comboHash[data.uri] || data.uri; } // Helpers function uris2paths(uris) { return meta2paths(uris2meta(uris)); } // [ // "http://example.com/p/a.js", // "https://example2.com/b.js", // "http://example.com/p/c/d.js", // "http://example.com/p/c/e.js" // ] // ==> // { // "http__example.com": { // "p": { // "a.js": { __KEYS: [] }, // "c": { // "d.js": { __KEYS: [] }, // "e.js": { __KEYS: [] }, // __KEYS: ["d.js", "e.js"] // }, // __KEYS: ["a.js", "c"] // }, // __KEYS: ["p"] // }, // "https__example2.com": { // "b.js": { __KEYS: [] }, // _KEYS: ["b.js"] // }, // __KEYS: ["http__example.com", "https__example2.com"] // } function uris2meta(uris) { var meta = { __KEYS: [] }; for (var i = 0, len = uris.length; i < len; i++) { var parts = uris[i].replace("://", "__").split("/"); var m = meta; for (var j = 0, l = parts.length; j < l; j++) { var part = parts[j]; if (!m[part]) { m[part] = { __KEYS: [] }; m.__KEYS.push(part); } m = m[part]; } } return meta; } // { // "http__example.com": { // "p": { // "a.js": { __KEYS: [] }, // "c": { // "d.js": { __KEYS: [] }, // "e.js": { __KEYS: [] }, // __KEYS: ["d.js", "e.js"] // }, // __KEYS: ["a.js", "c"] // }, // __KEYS: ["p"] // }, // "https__example2.com": { // "b.js": { __KEYS: [] }, // _KEYS: ["b.js"] // }, // __KEYS: ["http__example.com", "https__example2.com"] // } // ==> // [ // ["http://example.com/p", ["a.js", "c/d.js", "c/e.js"]] // ] function meta2paths(meta) { var paths = []; var __KEYS = meta.__KEYS; for (var i = 0, len = __KEYS.length; i < len; i++) { var part = __KEYS[i]; var root = part; var m = meta[part]; var KEYS = m.__KEYS; while (KEYS.length === 1) { root += "/" + KEYS[0]; m = m[KEYS[0]]; KEYS = m.__KEYS; } if (KEYS.length) { paths.push([root.replace("__", "://"), meta2arr(m)]); } } return paths; } // { // "a.js": { __KEYS: [] }, // "c": { // "d.js": { __KEYS: [] }, // "e.js": { __KEYS: [] }, // __KEYS: ["d.js", "e.js"] // }, // __KEYS: ["a.js", "c"] // } // ==> // [ // "a.js", "c/d.js", "c/e.js" // ] function meta2arr(meta) { var arr = []; var __KEYS = meta.__KEYS; for (var i = 0, len = __KEYS.length; i < len; i++) { var key = __KEYS[i]; var r = meta2arr(meta[key]); // key = "c" // r = ["d.js", "e.js"] var m = r.length; if (m) { for (var j = 0; j < m; j++) { arr.push(key + "/" + r[j]); } } else { arr.push(key); } } return arr; } // [ // [ "http://example.com/p", ["a.js", "c/d.js", "c/e.js", "a.css", "b.css"] ] // ] // ==> // // a hash cache // // "http://example.com/p/a.js" ==> "http://example.com/p/??a.js,c/d.js,c/e.js" // "http://example.com/p/c/d.js" ==> "http://example.com/p/??a.js,c/d.js,c/e.js" // "http://example.com/p/c/e.js" ==> "http://example.com/p/??a.js,c/d.js,c/e.js" // "http://example.com/p/a.css" ==> "http://example.com/p/??a.css,b.css" // "http://example.com/p/b.css" ==> "http://example.com/p/??a.css,b.css" // function paths2hash(paths) { for (var i = 0, len = paths.length; i < len; i++) { var path = paths[i]; var root = path[0] + "/"; var group = files2group(path[1]); for (var j = 0, m = group.length; j < m; j++) { setHash(root, group[j]); } } return comboHash; } function setHash(root, files) { var copy = []; for (var i = 0, len = files.length; i < len; i++) { copy[i] = files[i].replace(/\?.*$/, ''); } var comboPath = root + comboSyntax[0] + copy.join(comboSyntax[1]); if (comboSuffix) { comboPath += comboSuffix; } var exceedMax = comboPath.length > comboMaxLength; // http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url if (files.length > 1 && exceedMax) { var parts = splitFiles(files, comboMaxLength - (root + comboSyntax[0]).length); setHash(root, parts[0]); setHash(root, parts[1]); } else { if (exceedMax) { throw new Error("The combo url is too long: " + comboPath); } for (var i = 0, len = files.length; i < len; i++) { comboHash[root + files[i]] = comboPath; } } } function splitFiles(files, filesMaxLength) { var sep = comboSyntax[1]; var s = files[0]; for (var i = 1, len = files.length; i < len; i++) { s += sep + files[i]; if (s.length > filesMaxLength) { return [files.splice(0, i), files]; } } } // // ["a.js", "c/d.js", "c/e.js", "a.css", "b.css", "z"] // ==> // [ ["a.js", "c/d.js", "c/e.js"], ["a.css", "b.css"] ] // function files2group(files) { var group = []; var hash = {}; for (var i = 0, len = files.length; i < len; i++) { var file = files[i]; var ext = getExt(file); if (ext) { (hash[ext] || (hash[ext] = [])).push(file); } } for (var k in hash) { if (hash.hasOwnProperty(k)) { group.push(hash[k]); } } return group; } function getExt(file) { var p = file.lastIndexOf("."); return p >= 0 ? file.substring(p) : ""; } function isExcluded(uri) { if (comboExcludes) { return comboExcludes.test ? comboExcludes.test(uri) : comboExcludes(uri); } } function isComboUri(uri) { var comboSyntax = data.comboSyntax || ["??", ","]; var s1 = comboSyntax[0]; var s2 = comboSyntax[1]; return s1 && uri.indexOf(s1) > 0 || s2 && uri.indexOf(s2) > 0; } // For test if (data.test) { var test = seajs.test || (seajs.test = {}); test.uris2paths = uris2paths; test.paths2hash = paths2hash; }