Como precompilar seus templates e partials de Handlebars com Gulp
Tags: javascript, handlebars, gulp, portugues
Published: 2021-04-22 18:11:00

**Leia em inglês: [aqui](https://dev.to/honatas/properly-precompile-handlebars-templates-and-partials-with-gulp-4g91)**

Caso você esteja usando o [Handlebars](https://handlebarsjs.com) como sua engine de templates no front-end da sua aplicação web, é interessante enviar os templates precompilados para o browser ao invés de deixar para o cliente o trabalho de ter que compilar cada template de que ele precisa.

Apresento aqui um script do [Gulp](https://gulpjs.com) que eu tenho usado já há algum tempo. Ele pega qualquer arquivo .hbs na sua pasta src, compila, e gera um único arquivo templates.js na sua pasta dist/js. Ele também pega qualquer arquivo que comece com _ e marca ele como um partial do handlebaras, de modo que ele possa ser incluído em outros templates (se lembre de omitir o caractere _ quando for incluir, ou seja, `_meuInclude.hbs` vira `{{>meuInclude}}`.

No seu código javascript, você vai recuperar o template assim:
`const stringTemplate = Hbs['nome_do_template'];`

Sem mais, segue o código:

```javascript
const { src, dest, series } = require('gulp');
const concat = require('gulp-concat');
const declare = require('gulp-declare');
const del = require('del');
const handlebars = require('gulp-handlebars');
const merge = require('merge2');
const path = require('path');
const rename = require('gulp-rename');
const wrap = require('gulp-wrap');

const target = 'dist/js';

function clean() {
  return del('dist');
}

function templates() {
  return src('src/**/*.hbs')
  .pipe(rename((path) => {
    if (path.basename.startsWith('_')) {
      path.basename = path.basename.substring(1);
    }
  }))
  .pipe(handlebars())
  .pipe(wrap('Handlebars.template(<%= contents %>)'))
  .pipe(declare({
    namespace: 'Hbs',
    noRedeclare: true,
  }));
}

function partials() {
  return src('src/**/_*.hbs')
  .pipe(handlebars())
  .pipe(wrap('Handlebars.registerPartial(<%= processPartialName(file.relative) %>, Hbs[<%= processPartialName(file.relative) %>]);', {}, {
    imports: {
      processPartialName: function(fileName) {
        return JSON.stringify(path.basename(fileName, '.js').substring(1));
      }
    }
  }));
}

function hbs() {
  return merge(templates(), partials())
    .pipe(concat('templates.js'))
    .pipe(dest(target));
}

exports.default = series(
  clean,
  hbs,
);
```
A pegadinha aqui está nos partials. Pro Handlebars, qualquer template pode ser um partial, mas pra isso o template precisa existir primeiro. O que esse script faz é precompilar todos os templates (inclusive os partials) e, pra cada arquivo que começa com _, marca ele como um partial.

Claro, se você está usando o Gulp pra fazer o build da sua aplicação, você não vai ter vários gulpfiles, então a melhor coisa a se fazer aqui é pegar alguns desses métodos e adicioná-los ao seu próprio gulpfile. O que eu costumo fazer nos meus gulpfiles é não gerar a saída em um arquivo de templates, mas sim juntar essa saída com o resto do meu javascript gerado e criar um único arquivo e, caso o build seja pra produção, minificar o resultado.

Espero que isso ajude acelerar a sua jornada pra se livrar dos frameworks da modinha. =)