Carregando vários scripts adicionando uma tag só

Olá a todos,

Este é rapidinho, alguns de vocês não terão uso prático para isto porque… é muito específico. Na verdade é quase uma curiosidade, uma vez que as técnicas de “minifização” e junção de arquivos estão muito evoluídas. Ainda assim, eis o cenário:

Imagine que você tem um biblioteca javascript dividida em vários artefatos, mas você não quer obrigar os usuários da sua biblioteca a adicionar todos os arquivos. Você quer que eles adicionem um só e saiam usando.

A solução envolve adicionar um único script, mas este adicionará os outros dinamicamente. Mais ou menos assim:

/* arquivo bootstrap.js */
(function(d){
	var scripts = d.scripts;
	var path = "";
	for ( var i in scripts) {
		var cap = null;
		if (scripts[i].src)
			cap = scripts[i].src.replace(/.*(bootstrap.js)/, "$1");
		if ("bootstrap.js" == cap) {
			path = scripts[i].src.replace(/(.*)bootstrap.js/, "$1");
			break;
		}
	}
	// lista com todos os modulos
	var modules = [ "module1.js", "module2.js", "module3.js", "module4.js" ];
	for ( var i in modules) {
		var script = d.createElement("script");
		script.src = path + modules[i];
		d.head.appendChild(script);
	}
})(document);

Neste caso compreende-se que o bootstrap e os módulos estão em um mesmo diretório, por isso a lista de módulos possui somente o nome dos arquivos. Caso houvesse pastas, a lista teria nomes como “pastaX/moduloA.js” e tudo estaria certo.

Uma desvantagem séria é que se você precisar dos artefatos da biblioteca ainda na fase de carregamento da página eles ainda não estarão la. As tags de script ainda serão carregadas.

A versão abaixo procura corrigir este problema, mas vai obrigar-lhe a ter um “entrypoint” obscuro (facebook, é com você, ouviu?) e lá declarar tudo o que for preciso na fase de carregamento:

/* arquivo bootstrap.js */
(function(d){
	var scripts = d.scripts;
	var path = "";
	for ( var i in scripts) {
		var cap = null;
		if (scripts[i].src)
			cap = scripts[i].src.replace(/.*(bootstrap.js)/, "$1");
		if ("bootstrap.js" == cap) {
			path = scripts[i].src.replace(/(.*)bootstrap.js/, "$1");
			break;
		}
	}
	// lista com todos os modulos
	var modules = [ "module1.js", "module2.js", "module3.js", "module4.js" ];
	var loaded=0;
	function anotherLoad() {
		if(loaded == modules.length){
			// defina window.bootStrapMain=function(){} na sua fase de
			// carregamento, onde antes havia onloads e outras coisas.
			window.bootStrapMain();
		}
	}
	for ( var i in modules) {
		var script = d.createElement("script");
		script.onload = function() {
			loaded++;
			anotherLoad();
		};
		script.src = path + modules[i];
		d.head.appendChild(script);
	}
})(document);

Dessa forma você terá uma maneira simples de disparar o carregamento da aplicação encadeado ao carregamento da biblioteca.

Sem mais e até a próxima.

Deixe um comentário