Ultimamente tem se falado muito em melhoras no workflow. Cada desenvolvedor tem o seu método de trabalhar. Mas todos possuem algo em comum: acham um saco ter que copiar os arquivos de um lado para o outro para ter que criar um novo projeto. É neste momento que entram os generators.
Yeoman e Boilerplates
Foi pensando nisso que nos últimos anos (2~3) passaram a surgir vários boilerplates e generators, esse ultimo mais especificamente utilizando o Yeoman. Sim, nossa vida melhorou muito. Cada projeto que iniciamos sempre possui uma estrutura inicial padrão, e agora você não precisa mais copiar e colar arquivos de um lado para o outro.
Se você ainda não conhece o Yeoman, ele é uma stack client-side feito em NodeJS que permite que você crie generators de várias aplicações web, utilizando as mais diversas tecnologias. Atualmente a comunidade já criou quase 700 generators, além dos official generators e também dos que não aparecem em nenhumas dessas listas.
O Yeoman utiliza do Grunt para fazer o scaffolding e do Bower para baixar as dependências dos projetos.
Apesar dos muitos generators, criar um generator exige muito cuidado, além de ler um pouco a documentação do Yeoman.
Com o surgimento do GulpJS, um task runner, assim como o Grunt, foi criado o Slush, um generator que utiliza o Gulp, ao invés do Grunt, além de ter um proposta mais simples.
Começando com o Slush
O Slush depende apenas do GulpJS e de seus plugins. Para quem já mexeu com o Gulp, não terá muita dificuldade. Se você ainda não mexeu com o Gulp, aconselho o artigo do Leonardo Souza, Bye bye Grunt.js, hello Gulp.js!.
Instalando o Slush
Para instalar o Slush, basta ter o NodeJS instalado na sua máquina. Se você já tem, basta instalar o Slush de modo global:
$ [sudo] npm install -g slush
Criando seu primeiro generator
Como exemplo, nosso projeto irá gerar um scaffolding para trabalhar com a stack MEAN. Todo generator para Slush deve ter o prefixo slush-. Então vamos criar uma pasta chamada slush-mean e entrar nela:
$ mkdir slush-mean && cd slush-mean
Criação do arquivo package.json
Então primeiro vamos criar um arquivo chamado package.json, parecido com esse:
{
"name": "slush-mean",
"version": "0.1.0",
"description": "Generate a simple web project using M.E.A.N. stack",
"main": "slushfile.js",
"keywords": [
"slushgenerator",
"mean",
"express",
"mongo",
"node",
"angular"
],
"dependencies": {
"gulp": "~3.5.6",
"gulp-template": "~0.1.1",
"gulp-install": "~0.1.1",
"gulp-conflict": "~0.1.1",
"gulp-rename": "~1.2.0",
"underscore.string": "~2.3.3",
"inquirer": "~0.4.1"
},
"author": "Seu Nome",
"license": "MIT"
}
Vale ressaltar dois pontos/linhas importantes nesse arquivo:
- No main devemos colocar o slushfile.js, pois assim como o Grunt e o Gulp, o Slush utiliza um arquivo de configuração próprio. Além do mais, o main é utilizado pelo npm para executar esse arquivo quando o módulo for instalado (veremos isso a seguir).
- Nas keywords é importante o uso da palavra-chave slushgenerator para que seu gerador apareça na lista “oficial”, lá no site do Slush.
Instalar as dependências
Depois que o arquivo package.json foi criado, vamos instalar as dependências:
$ [sudo] npm install
Criar arquivo slushfile.js
Vamos agora criar um arquivo chamado slushfile.js na raiz, junto com seu package.json. O arquivo explica-se por si só, mas depois dele vou colocar algumas observações:
/*
* slush-mean
* https://github.com/seu-nome/slush-mean
*
* Copyright (c) 2014, Seu Nome
* Licensed under the MIT license.
*/
'use strict';
var gulp = require('gulp');
var install = require('gulp-install');
var conflict = require('gulp-conflict');
var template = require('gulp-template');
var rename = require('gulp-rename');
var _ = require('underscore.string');
var inquirer = require('inquirer');
gulp.task('default', function(done) {
var prompts = [{
name: 'appName',
message: 'What the name of project?'
}, {
name: 'appDescription',
message: 'What the description?'
}, {
name: 'appVersion',
message: 'What the version?',
default: '0.1.0'
}, {
name: 'appAuthor',
message: 'Name of author?'
}, {
name: 'appEmail',
message: 'Author e-mail?'
}];
inquirer.prompt(prompts,
function(answers) {
if (!answers.appName) {
return done();
}
answers.appNameSlug = _.slugify(answers.appName)
answers.appAuthorSlug = _.slugify(answers.appAuthor)
gulp.src(__dirname + '/templates/**')
.pipe(template(answers))
.pipe(rename(function(file) {
if (file.basename[0] === '_') {
file.basename = '.' + file.basename.slice(1);
}
}))
.pipe(conflict('./'))
.pipe(gulp.dest('./'))
.pipe(install())
.on('end', function() {
done();
});
});
});
Alguns pontos a serem observados:
- Na linha onde tem /templates/ **, é nessa pasta que irá ficar os arquivos a serem “extraidos”
- Note que nas perguntas, existe a opção de colocar uma resposta “default” quando o cara só der ENTER
Criando os arquivos a serem gerados
Essa parte é simples. Coloque dentro da pasta templates tudo que irá ser extraído. E agora vem a parte boa. Quando você quiser “printar” o valor de uma resposta, simplesmente coloque <%= nomeDaVariavelResposta %>
nos arquivos.
Por exemplo, crie eum arquivo chamado package.json
dentro da pasta templates
:
{
"name": "<%= appNameSlug %>",
"description": "<%= appDescription %>",
"version": "<%= appVersion %>",
"author": {
"name": "<%= appAuthor %>",
"url": "<%= appEmail %>"
}
}
Um ponto importante, é que os arquivos lá da pasta templates que começam com .
, como por exemplo o .gitignore
você deverá substituir por _
, ficando assim _gitignore
. Mas não se preocupe, na hora que ele é gerado/compilado, ele se é renomeado para .gitignore
. Isso é feito pelo gulp-rename
para que os arquivos de configuração que começam com o .
, não tenham seu comportamento padrão.
Quando o generator for utilizado, o Slush/Gulp nada mais irá fazer que extrair tudo que está na pasta templates para a raiz e deletar os arquivos que ali estavam (slushfile.js, package.json, …).
Estrutura de arquivos
slush-mean/
├── templates/
│ ├── gulpfile.js
│ ├── package.json
│ └── ...
├── slushfile.js
└── package.json
Testando e Publicando no NPM
Para você testar seu gerador, utilize o comando npm link .
, isso irá criar um alias no seu npm/node. Agora você já pode testar seu generator. Crie outra pasta fora dessa estrutura e rode o comando slush mean
. Para publicar nos registros oficias do NPM, utilize o comando npm publish
. Se tiver dúvidas de como publicar um módulo, consulte o próprio site do NPM.
Conclusão
Vimos que com apenas dois arquivos conseguimos construir um generator like a Yeoman, só que bem mais simples. Eu mesmo criei um generator que irei explicar em outro post como foi feito, bem como o modo de usar.
Esse artigo parte do princípio de que você já tenha alguma familiariada com Node, NPM, Task Runner, Terminal entre outras coisas.
Qualquer dúvida, fique a vontade para publicar seu comentário!