Skip to content

Instantly share code, notes, and snippets.

@qiansen1386
Last active December 19, 2016 04:44
Show Gist options
  • Save qiansen1386/7270195d541e091ed63b449e275c9d0b to your computer and use it in GitHub Desktop.
Save qiansen1386/7270195d541e091ed63b449e275c9d0b to your computer and use it in GitHub Desktop.
Advanced version of script injection script
// a. CDN like jsdelivr.com can load multiple script with one url
// b. predicate condition can be omit
var scripts2Load = [{ 'name': name, url: "", 'predicate': () => true }];
// Example:
//var scripts2Load = [{ 'name': 'Lodash',
//url: 'https://cdn.jsdelivr.net/g/lodash@4(lodash.min.js+lodash.fp.min.js)',
//'predicate': () => window._ }];
((window) => {
// Change it if you want.
const timeout = 2000;
// Helper
const logger = msg => msg && console.log(msg);
const injector = url => {
const tag = document.createElement('script');
tag.src = url;
window.document.getElementsByTagName('head')[0].appendChild(tag);
};
// Turn scripts2Load to Promises
const promisify = toLoad => {
return new Promise((resolve, reject) => {
logger(`Now injecting ${toLoad.name}...`);
injector(toLoad.url);
const defer = time => {
if (toLoad.predicate()) {
resolve(toLoad);
} else {
setTimeout(() => {
logger(`Detecting ${toLoad.name}\t Wait:${time}`);
if (time < timeout) defer(time + 50);
}, 50);
}
reject(toLoad);
};
defer(0);
});
};
Promise.all(scripts2Load.map(promisify))
.then(toLoads => toLoads.map(toLoad => logger(`Lib ${toLoad.name} is loaded sucessfully!`)))
.catch(console.error);
})(window);

Intro

A advanced version of Inject Lo-dash FP or Ramda to browser, see more there.

Features

  • Allows u inject many libs concurently.
  • Also handle all the callbacks using "promise".

Disclaimer

  1. Check whether your browser supports ES6 features or not first.
  2. I hornestly don't know if I implement "Promise" correctly or not. It turns out that I am still handling all the timeout / detection myself. Despite the functional programming tactics are very helpful, I reckon my implementation is still verbose and ugly. Especially the recursion of defer() function! That is my limitation. I am kean to see if there is a better solution:smile:!
  3. Because this script will almost always runs on 3rd-party pages, we cannot rely on any fancy polyfill dependency. (Like bluebird.js)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment