Dev (Back & Front)ARTIGO

$script.js vs RequireJS: comparações do gerenciamento de dependência

À medida que o JavaScript se afasta mais e mais do playground de linguagem de programação que costumava ser, e é cada vez mais utilizado como núcleo para aplicações em larga escala, gerenciar o código começa a ficar extremamente difícil. Dividir o código em vários arquivos ajuda, embora também adicione mais complexidade de uma maneira diferente. Uma forma de combater essa nova complexidade é com as bibliotecas de gerenciamento de dependência, mas qual é a certa para você?

Script loading vs dependency management 

As duas bibliotecas mencionadas no título – $script.js e RequireJS – não são tecnicamente classificadas da mesma forma, porque, embora façam coisas semelhantes, elas possuem ênfases diferentes. $script.js é um carregador de script com gerenciamento de dependência, enquanto que o gerenciamento de dependência de RequireJS é muito mais poderoso e mais parecido com o que você usaria para importar classes em linguagens compiladas como Java. Você verá o que quero dizer em breve.

$script.js

Esta prática biblioteca foi criada por Dustin Diaz e Thornton Jacob e está hospedada no Github. É onde você vai encontrar a documentação sobre como usá-la, mas ainda vou mostrá-la um pouco aqui para dar uma ideia de como ela funciona.

Primeiro, vamos falar sobre o uso mais básico: o carregamento de um script.

$script('jquery.js');

Isso carrega jquery.js de forma assíncrona para a página. Porém não é mais útil do que apenas usar uma tag script normal. É ligeiramente menor, mas, uma vez que é carregado de forma assíncrona, o código logo após essa linha será executado antes que jquery.js seja carregada. Então também daremos a ela uma função callback que é executada após jquery.js ser carregada.

    $script('jquery.js', function() {
// do stuff with jQuery.
});

Agora, uma vez que jquery.js for carregado e executado, teremos a certeza de que podemos acessar os objetos e as funções que ela define. Há muito mais que você pode fazer com $script.js – incluindo dependências nomeadas -, mas isso lhe dá a essência de como usá-la. Com isso, definimos com sucesso uma dependência e garantimos que ela mesma seria carregada e executada antes que tentássemos usá-la. Utilizar algo como isso nos permite precisar usar somente duas tags script em nosso HTML (uma para carregar $script.js e outra para carregar o aplicativo principal). O resto dos scripts dos quais dependemos pode ser gerenciado com $script.js.

RequireJS

RequireJS é um projeto muito maior, com um projeto no Github e um site próprio. Você encontrará a documentação para RequireJS no segundo link, mas se quiser ler um pouco de história e uma introdução mais completa à RequireJS, você pode ler este artigo no Adobe Developer Connection.

RequireJS pode ser usado quase exatamente como $script.js para carregar arquivos javascript simples, mas é muito mais poderoso do que isso. Você pode definir os módulos, e então carregar as dependências deles sem expô-los globalmente, de modo que cada bit do seu código possa estar seguro em relação a scripts de terceiros. Dê uma olhada.

Primeiro, vamos definir um módulo que pode ser carregado como uma dependência.

    // This is just an object literal
define({
name: "Joe Zim",
gender: "male"
});

// Here's a constructor so you can create
// new objects, rather than just the one
// literal object
define(function() {
var Person = function( name, gender ) {
this.name = name;
this.gender = gender;
};

return Person;
} );

Você pode ver dois tipos diferentes de módulos lá. O primeiro é simplesmente definido como um objeto literal, que será o que é retornado para o script dependente, como você verá mais tarde. O segundo exemplo tem uma função, que será executada imediatamente quando o módulo estiver carregado como uma dependência e o valor que for retornado daquela função será o valor que é dado para o script dependente.

Agora, vamos criar um módulo que é dependente do mesmo que acabamos de definir. Vamos supor que o módulo acima é salvo como person.js. Aqui está como nós definimos outro módulo que é dependente do módulo que criamos nos bastidores.

    define( [
'person', 'list'
], function( Person, List ) {
var personList = new List(
new Person('Joe Zim', 'male');
);

return personList;
} );

Definimos o módulo exatamente como fizemos antes, mas desta vez enviamos um array como o primeiro parâmetro. O array apresenta strings de nomes de arquivos (sem o “.js”) dos módulos para buscar. Então, quando esses módulos estão totalmente carregados, eles são enviados como parâmetros para a função para o novo módulo que você está definindo. Como indicado acima, isso localiza os módulos de modo que não estejam acessíveis globalmente.

Agora, vamos escrever um pouco de código que é dependente do último módulo e do módulo person, mas não é a criação de um novo. Vamos assumir que o último módulo criado foi salvo como default-person-list.js.

    require( [
'default-person-list', 'person'
], function( list, Person ) {
var chuck = new Person( 'Chuck Norris', 'male' );
list.addItem( chuck );

list.forEach( function( item ) {
alert(item.name);
} );
} );

Isso é quase exatamente o mesmo que criar um módulo que é dependente de outro módulo, exceto por algumas coisas importantes:

  1. Nós não utilizamos mais a função define; em vez disso, usamos require (finalmente sabemos de onde vem o nome da biblioteca!).
  2. Não há necessidade de retornar nada da função. Uma vez que isso não está sendo definido como um módulo, basta executar do mesmo modo e, portanto, não há necessidade de devolver nada.

Essa é a essência de RequireJS, mas há mais uma coisa que é muito importante sobre ela. Ela vem com uma build tool que irá procurar através de todos os módulos e outros arquivos JavaScript e concatenar e diminuí-los, de modo que mesmo que você passe todo o tempo criando arquivos separados, isso não vai se tornar um problema de desempenho.

O que é certo para você?

Se você é um programador muito modular e gosta da ideia de manter os módulos localizados, então tomar a rota RequireJS é provavelmente uma ideia realmente boa para você. Se o seu aplicativo é relativamente simples ou você simplesmente não gosta de converter tudo em arquivos de módulos individuais, então, algo como $ script.js provavelmente seria um grande ajuste. Em última análise, cabe a você! Ambas são excelentes ferramentas. Enfim, isso é tudo por hoje. Happy coding e Deus te abençoe!

?

Texto original disponível em http://www.joezimjs.com/javascript/script-js-vs-requirejs-dependency-management-comparisons/

Joe ZimAutor

É desenvolvedor web e já trabalhou em várias frentes: HTML, CSS, JavaScript, jQuery, PHP, Joomla, WordPress, Node.js.

Ver perfil