Como criar um projeto Open Source em JavaScript

Muitos desenvolvedores, tanto iniciantes quanto avançados, ficam na dúvida de como criar (e publicar) um projeto Open Source usando JavaScript. Nesse post vou mostrar o passo-a-passo de como fazer uma lib bem simples em AngularJS, e como publicá-la seguindo as melhores práticas usando GitHub, Bower, NPM e Gulp.

NPM, Bower e Gulp

Obs.: Se você não entende muito de AngularJS, não fique preocupado. O foco desse post não é o Angular em si e suas características, mas sim o passo-a-passo de como publicar um projeto Open Source em JavaScript. Se você quiser saber mais sobre AngularJS, dê uma olhada nesse outro post.


  1. Começando o projeto

O projeto se chamará ngLib e não fará nada demais. Será apenas uma diretiva que terá um console.log dentro.

Primeiramente vamos criar uma pasta, onde ficará o projeto ngLib:

$ mkdir ng-lib
$ cd ng-lib/

Agora precisamos usar o Bower para adicionar as dependências do projeto e também para que futuramente outras pessoas possam utilizar a lib.

$ sudo npm install -g bower
$ bower init

O Bower irá agora fazer algumas perguntas para auxiliar na criação do bower.json. Eu prefiro simplesmente aceitar todos os defaults e depois ir diretamente no arquivo e modificá-lo.

Após aceitar os defaults, seu arquivo ficará mais ou menos assim:

{
name: 'ng-lib',
version: '0.0.0',
authors: [
'Seu Nome <seu@email.com>'
],
license: 'MIT'
}

Então agora vamos editar diretamente o arquivo e deixá-lo assim:

{
'name': 'ng-lib',
'version': '0.0.0',
'authors': [
'Seu Nome <seu@email.com>'
],
'description': 'Uma lib open source bem simples em AngularJS',
'main': 'app.js',
'keywords': [
'AngularJS',
'Directive'
],
'license': 'MIT',
'homepage': 'https://github.com/seu-usuario/ng-lib',
'dependencies': {
'angular': '^1.2.x'
}

}

Repare na linha em negrito acima. Como é um projeto em AngularJS, uma das dependências do projeto é o próprio Angular. Pode parecer óbvio, mas muitos desenvolvedores se esquecem desse detalhe.

Agora precisamos iniciar o git no projeto para podermos hospedá-lo futuramente no GitHub:

$ git init
$ git commit -am 'First commit'

Agora basta adicioná-lo no GitHub. Se você ainda não sabe como fazer isso, use esse tutorial.

GitHub logo

Para que possamos iniciar o desenvolvimento da nossa diretiva, precisamos baixar as dependências que colocamos no Bower (no caso, apenas o próprio AngularJS, como falado anteriormente):

$ bower install

Esse comando irá gerar uma pasta chamada bower_components dentro do projeto. É uma boa prática que essa pasta não esteja versionada no git. Então vamos criar o arquivo .gitignore para que a pasta não seja considerada nos commits.

$ touch .gitignore

Agora adicione a seguinte linha no arquivo .gitignore:

bower_components/

Pronto, agora é só commitar essa mudança e pushar para o GitHub:

$ git commit -am 'Adicionando bower_components no gitignore'
$ git push origin master

2. Criando a Diretiva

Já temos a estrutura mínima montada, então podemos enfim colocar a mão na massa e criar nossa diretiva:

$ touch app.js

Vamos entrar no arquivo que acabamos de criar e preencher com o código:

(function() {
'use strict';
    angular
.module('ngLib', [])
.directive('ngLib', ngLib);
    function ngLib() {
return {
restrict: 'E',
link: function ($scope, $attrs, $element) {
console.log('Funciona!');
}
};
}
})();

Com isso feito, já temos uma primeira versão funcional do nosso projeto. Falta apenas atualizar nosso bower.json, indicando uma mudança na versão:

{
'name': 'ng-lib',
'version': '0.0.1',
'authors': [
'Seu Nome <seu@email.com>'
],
'description': 'Uma lib open source bem simples em AngularJS',
'main': 'app.js',
'keywords': [
'AngularJS',
'Directive'
],
'license': 'MIT',
'homepage': 'https://github.com/seu-usuario/ng-lib',
'dependencies': {
'angular': '^1.2.x'
}
}

E também, precisamos registrar a aplicação no index de busca do Bower, para que outros desenvolvedores consigam procurar e utilizar nossa lib. É bem simples fazer isso, basta digitar o comando:

$ bower register ng-lib git://github.com/seu-usuario/ng-lib.git

Ou então seguir esse tutorial.

Bower logo

Pra fechar vamos commitar essas mudanças e adicionar uma tag do projeto no GitHub:

$ git commit -am 'Adicionando diretiva'
$ git tag 0.0.1
$ git push origin --tags
$ git push origin master

3. Refinando o projeto

Apesar de o projeto estar funcional, ele ainda pode ser otimizado. Uma boa prática é minificar os arquivos para que os usuários tenham uma renderização mais efetiva, da nossa lib, no browser.

Vamos fazer todo esse processo utilizando o Gulp.
Uma pequena observação: se você já utiliza o Grunt e está acostumado com ele, não se sinta forçado a mudar para o Gulp. Ambas são excelentes tools. Inclusive há um grupo que prega o uso do próprio NPM como ferramenta de build, que também tem bons argumentos. O meu ponto é: não fique entrando em brigas religiosas pela tecnologia X ou Y. Tente aprender com todas.

O Gulp pode (e deve) ser obtido através do NPM. Para isso vamos criar um package.json, de uma forma bem semelhante a que criamos o bower.json:

$ npm init

Da mesma forma, aceite todos os defaults e vamos mudar diretamente o arquivo package.json, para que fique parecido com isso:

{
'name': 'ng-lib',
'version': '0.0.1',
'description': 'Uma lib open source bem simples em AngularJS',
'main': 'app.js',
'repository': {
'type': 'git',
'url': 'git+https://github.com/seu-user/ng-lib.git'
},
'keywords': [
'AngularJS',
'Directive'
],
'author': 'Seu Nome',
'license': 'MIT',
}

Agora sim podemos instalar o Gulp (e de quebra, alguns plugins dele):

$ npm install --save-dev gulp gulp-autoprefixer gulp-notify gulp-rename gulp-uglify

Se verificarmos novamente o package.json nós poderemos notar que ele foi atualizado automaticamente levando em consideração as novas dependências do Gulp:

{
'name': 'ng-lib',
'version': '0.0.1',
'description': 'Uma lib open source bem simples em AngularJS',
'main': 'app.js',
'repository': {
'type': 'git',
'url': 'git+https://github.com/seu-user/ng-lib.git'
},
'keywords': [
'AngularJS',
'Directive'
],
'author': 'Seu Nome',
'license': 'MIT',
'devDependencies': {
'gulp': '^3.9.0',
'gulp-autoprefixer': '^3.0.2',
'gulp-notify': '^2.2.0',
'gulp-rename': '^1.2.2',
'gulp-uglify': '^1.4.1'
}

}

Podemos agora rodar o Gulp, já que ele está instalado.

Vamos usá-lo para:
1. Pegar o conteúdo da diretiva e minificá-lo
2. Renomear para ng-lib.min.js (que é uma convenção)
3. Enviar esse arquivo para a pasta dist/ (outra convenção)
4. No final do processo notificar no terminal que tudo deu certo.

Gulp logo

Primeiro vamos criar o gulpfile:

$ touch gulpfile.js

Agora vamos modificá-lo para fazer todos os passos citados anteriormente:

var gulp = require('gulp'),
autoprefixer = require('gulp-autoprefixer'),
uglify = require('gulp-uglify'),
rename = require('gulp-rename'),
notify = require('gulp-notify');

gulp.task('default', function() {
return gulp.src('app.js')
.pipe(uglify())
.pipe(rename('ng-lib.min.js'))
.pipe(gulp.dest('dist/'))
.pipe(notify({ message: 'Build finalizado!' }));
});

Agora basta rodar:

$ gulp

Se você conseguiu visualizar a mensagem ‘Build finalizado!’ no terminal, então você poderá observar que foi criada uma pasta dist/ e dentro dela o arquivo ng-lib.min.js com o conteúdo da diretiva minificado.


Agora só falta criar um README.md que é o ponto de entrada da nossa lib para que os desenvolvedores possam entender melhor como instalar e a usar. Você pode tomar como exemplo esse README que eu usei num projeto meu.

Chegamos agora num ponto bom o suficiente para publicarmos nossa lib para que qualquer desenvolvedor possa usá-la (sim, testes unitários poderiam ser adicionados, mas isso vai ficar para um post futuro).


Se você gostou do post não se esqueça de dar um ❤ aqui embaixo!
E se quiser receber de antemão mais posts como esse,
assine nossa newsletter.

JSCasts

É difícil encontrar conteúdo bom e atualizado em português. Com isso em mente criamos o JSCasts, onde você vai se manter em dia com o JavaScript e todo o seu ecossistema de forma fácil e interativa.

Cursos:

Obrigado por ler! ❤