Bootstrap: Like a boss

Customizando o framework Bootstrap sem perder o controle do código

Hoje em dia, ao criar as estruturas e estilos visuais para um sistema ou site, não faz mais sentido começar do zero.
Existem dezenas de frameworks disponíveis para facilitar as nossas vidas.

Entre as várias opções, eu escolhi o Bootstrap por alguns motivos:

  1. Por ser muito usado, ele é colocado à prova todos os dias em milhões de ambientes diferentes. Isso é um ótimo diferencial para qualquer framework, já que os erros são encontrados e corrigidos rapidamente;
  2. Ele é ativamente mantido e evoluído por uma comunidade enorme;
  3. Existe uma grande quantidade de documentação sobre ele; se você tiver alguma dificuldade, é muito provável que você não seja a primeira pessoa a passar esse aperto.;
  4. Com poucas linhas de código, é possível dar a ele a sua própria cara, sem perder suas vantagens.
  5. Não importa o seu gosto para pré-processadores, ele está disponível em versões LESS e SASS.

Porém, uma de suas maiores desvantagens é a de estimular o trabalho de uma forma não muito… sustentável. Se você baixar um pacote customizado e começar a trabalhar sobre ele, é bem capaz de que fique preso naquela versão indefinidamente, já que, ao atualizar sua instalação para a última versão, qualquer alteração que você tenha feito no CSS seria perdida.

Aqui está uma solução para criar seu próprio “sabor” do Bootstrap, mantendo seu código e sua sanidade em dia!

Baixando os pacotes

Para baixar os recursos necessários, eu usei o gerenciador de pacotes Bower.
Caso você ainda não o tenha instalado, siga as instruções do site.

Antes de começar, é interessante criar um arquivo bower.json.
Ele não é necessário, mas ajuda na hora de atualizar os pacotes.

Para isso, digite bower init no seu terminal e siga as instruções.

Após criar o arquivo base, vamos baixar o bootstrap na versão SASS:

bower install --save twbs-bootstrap-sass

O Bower vai, então, fazer o download dos códigos fonte do Bootstrap para a pasta bower_components, além de todas as suas dependências (nesse caso, apenas o Jquery).

Compilando

Para compilar o código, usaremos a ferramenta Gulp. Ele exerce a mesma função do famoso executador de tarefas Grunt, mas de uma forma muito mais rápida (e, na minha opinião, que faz muito mais sentido).

Para instalar, siga as instruções no GitHub.

Depois de instalado, vamos baixar os pacotes necessários para que ele funcione.

Assim como no bower, precisamos primeiro criar um arquivo que armazenará as configurações.
Digite npm init no seu terminal e siga as instruções.
Um arquivo chamado package.json será criado.

Para instalar todos os pacotes que usaremos, digite:

npm install --save gulp gulp-minify-css gulp-plumber gulp-rename gulp-sass

Em seguida, crie um arquivo chamado gulpfile.js. Nele nós iremos colocar o código responsável pela compilação em si. Apenas cole o código abaixo e não se preocupe com os detalhes por enquanto.

var gulp = require('gulp')
var rename = require('gulp-rename')
var plumber = require('gulp-plumber')
var sass = require('gulp-sass')
var minifyCss = require('gulp-minify-css')

// error handler for plumber function handleError (err) { console.log(err.toString()) this.emit('end') }

var sassPath = 'sass/**/*.s[ac]ss'

gulp.task('sass', function () { return gulp.src(sassPath) .pipe(plumber({ errorHandler: handleError, })) .pipe(sass({ style: 'expanded', includePaths: [ 'bower_components/twbs-bootstrap-sass/assets/stylesheets/' ], })) .pipe(gulp.dest('css')) .pipe(minifyCss()) .pipe(rename({ suffix: '.min' })) .pipe(gulp.dest('css')) }) gulp.task('watch', [ 'build' ], function () { gulp.watch(sassPath, [ 'sass' ]) })

// aliases gulp.task('build', [ 'sass' ]) gulp.task('default', [ 'build', 'watch' ])

Essa é a receita de bolo que está no arquivo acima: Pegue tudo que estiver na pasta sass, compile, jogue o resultado na pasta css, crie uma cópia de cada CSS gerado, adicione o sufixo .min ao nome do arquivo, minifique e grave na mesma pasta.

Agora, abra uma nova aba (ou janela) do ser terminal e navegue para a mesma pasta. Ao executar o comando gulp, ele recompilará o projeto em milissegundos.

Além disso, ele ficará monitorando a pasta sass. Ao alterar algum arquivo *.scss, ele recompilará o projeto automaticamente.
Para parar a execução, aperte CTRL+C no seu terminal.

Customizando

Crie uma pasta na raiz do seu projeto chamada sass. É nela que ficarão os códigos do seu projeto.

Vá até a pasta bower_components/twbs-bootstrap-sass/assets/stylesheets/ e copie os arquivos _bootstrap.scss e bootstrap/_variables.scss para a pasta sass na raiz do seu projeto.

Voltando para a pasta sass, altere a linha:

@import "bootstrap/variables";

Para:

@import "variables";

Isso fará com que ele use as variáveis locais (no nosso caso, o arquivo sass/_variables.scss) ao compilar o código.

Execute o comando gulp no seu terminal e veja o resultado na pasta css. Foram criados dois arquivos diferentes: um chamado bootstrap.css com o código expandido, útil para desenvolvimento e debug; e um chamado bootstrap.min.css, minificado, perfeito para produção.

Altere qualquer parâmetro do seu arquivo _variables.scss para ver o resultado imediatamente no CSS re-compilado!

Para criar suas próprias regras, altere o seu arquivo bootstrap.scss, após todos os @imports.

O importante é nunca alterar os arquivos originais na pasta bower_components. Assim é sempre possível atualizar o Bootstrap para a última versão sem perder as suas customizações.

Aparando as pontas

Esta é outra vantagem de compilar o seu próprio Bootstrap: Poder habilitar ou desabilitar partes do framework a qualquer momento.

Após deixar o Bootstrap com a sua cara, abra o seu arquivo bootstrap.scss e comente (com um //) todos os @imports que você ache que não usou no projeto.

Isso pode reduzir drasticamente o tamanho do CSS final.

Versionando

Para o versionamento, existem duas abordagens básicas: a purista e a pragmática.

Na abordagem purista, você deve apenas versionar os arquivos e pastas criados por você. Ou seja: bower.json, package.json, gulpfile.js e sass/.

Dessa forma, você cria um repositório mais limpo, leve e fácil de revisar (já que os diffs contém apenas código original). É a abordagem perfeita para projetos open source, onde o entendimento do código por todos é muito importante.

Por outro lado, é necessário instalar todos os componente em cada máquina de desenvolvimento e servidor, e re-compilar o projeto em cada servidor após cada deploy. A chance de erros e falhas humanas nessa abordagem é grande (>0).

Para este projeto, eu escolhi seguir a abordagem pragmática: o que importa é o resultado final.

Além da lista anterior, versione também os arquivos finais (css/), ignorando apenas as pastas node_modules/ e bower_components/. O código CSS estará pronto para funcionar assim que copiado para o servidor.

O projeto pode ficar um pouco mais sujo, porém com menos surpresas.