Laravel Elixir e Zurb Foundation, revisitado

Editado a 25 de Novembro de 2016: Vê o fundo do post para uma actualização relativa ao Elixir 6.

Na última vez que escrevi sobre como usar a framework Foundation com o Laravel Elixir disse que o pacote npm não instalava as dependências necessárias e, por isso, tínhamos que instalar via Bower. Não tenho certeza se era eu que estava errado ou se alguma coisa mudou depois desse post, mas agora isso já não é assim.

Além disso, entretanto, saiu uma nova versão da framework, Foundation for Sites 6. Logo, acho que é boa ideia reescrever o tutorial sobre como substituir o Bootstrap pela Foundation no Laravel Elixir.

0. Configurar

Antes de começar, certifica-te de que tens o Node.js, npm e gulp instalados e a funcionar. Na raiz do projeto, deves ser capaz de executar os comandos npm install e gulp sem erros.

Vê na documentação do Laravel Elixir mais informações.

1. Instalar a Foundation

1.1. Se ainda não o fizeste, instala as dependências do npm. Antes de executar o comando a seguir deves querer remover a linha do bootstrap-sass do ficheiro package.json, para que o Bootstrap não seja instalado

npm install

1.2. Se o Bootstrap já estiver instalado podes removê-lo com o seguinte comando.

npm rm bootstrap-sass --save

1.3. Instala a framework Foundation.

npm install foundation-sites --save

1.4. (opcional) A Foundation 6 traz o Motion UI, uma biblioteca Sass para criar animações e transições. Instala-a com o seguinte comando.

npm install motion-ui --save

Se não a quiseres usar, remove qualquer referência a ela nos ficheiros seguintes.

2. Criar os ficheiros sass

Agora, vais precisar de dois ficheiros, normalmente na directoria “resources/assets/sass”. Estes são os ficheiros que, posteriormente, vais editar.

2.1. Copia o ficheiro  “_settings.scss” da directoria “node_modules/foundation-sites/scss/settings” para a directoria “resources/assets/sass”. Este ficheiro contém todos os parâmetros dos vários componentes da Foundation que podemos personalizar.

2.2. Em “resources/assets/sass” cria um ficheiro chamado “app.scss” com o seguinte conteúdo. Este é o ficheiro principal, em que se fazem todos os imports / includes e escreves o teu próprio sass.

@charset 'utf-8';

@import 'settings';
@import 'foundation';
@import 'motion-ui';

@include foundation-global-styles;
@include foundation-grid;
@include foundation-typography;
@include foundation-button;
@include foundation-forms;
@include foundation-visibility-classes;
@include foundation-float-classes;
@include foundation-accordion;
@include foundation-accordion-menu;
@include foundation-badge;
@include foundation-breadcrumbs;
@include foundation-button-group;
@include foundation-callout;
@include foundation-close-button;
@include foundation-drilldown-menu;
@include foundation-dropdown;
@include foundation-dropdown-menu;
@include foundation-flex-video;
@include foundation-label;
@include foundation-media-object;
@include foundation-menu;
@include foundation-off-canvas;
@include foundation-orbit;
@include foundation-pagination;
@include foundation-progress-bar;
@include foundation-slider;
@include foundation-sticky;
@include foundation-reveal;
@include foundation-switch;
@include foundation-table;
@include foundation-tabs;
@include foundation-thumbnail;
@include foundation-title-bar;
@include foundation-tooltip;
@include foundation-top-bar;

@include motion-ui-transitions;
@include motion-ui-animations;

Aqui, aconselho a comentar todos os includes e apenas descomentar os que precisas e à medida que vão sendo precisos (de notar que o foundation-global-styles é basicamente sempre necessário).

3. Escrever as tarefas no Elixir

Escreve as tarefas que vão compilar o SCSS para CSS e copiar e concatenar os ficheiros de JavaScript.

elixir(function(mix) {

    // Sass
    var options = {
        includePaths: [
            'node_modules/foundation-sites/scss',
            'node_modules/motion-ui/src'
        ]
    };

    mix.sass('app.scss', null, options);

    // Javascript
    var jQuery = '../../../node_modules/jquery/dist/jquery.js';
    var foundationJsFolder = '../../../node_modules/foundation-sites/js/';

    mix.scripts([
       jQuery,
       foundationJsFolder + 'foundation.core.js',
       // Include any needed components here. The following are just examples.
       foundationJsFolder + 'foundation.util.mediaquery.js',
       foundationJsFolder + 'foundation.util.keyboard.js',
       foundationJsFolder + 'foundation.util.timerAndImageLoader.js',
       foundationJsFolder + 'foundation.tabs.js',
       // This file initializes foundation
       'start_foundation.js'
    ]);

});

Na tarefa referente ao JavaScript, copiamos e concatenamos os ficheiros necessários para o Foundation funcionar. No mínimo são necessários o “jquery.js” e o “foundation.core.js”. De seguida adicionamos os ficheiros necessários aos componentes que vamos usar (os ficheiros listados são apenas um exemplo). O ficheiro “start_foundation.js” inclui apenas o código necessário para inicializar a Foundation ($(document).foundation();).

4. Correr o gulp

Finalmente, estás pronto para correr os comandos gulp ou gulp watch (para executar automaticamente as tarefas sempre que algum ficheiro seja alterado). Isto vai gerar um ficheiro chamado “app.css” na directoria “public/css” e um ficheiro “all.js” na directoria “public/js” que depois pode ser incluídos nas views.

Nota: Se queres que os ficheiros sejam também minificados deves adicionar a flag –production  (gulp –production ou gulp watch –production).

Actualização para Elixir 6

Por alguma razão que eu não consigo entender, o Elixir 6 não suporta Babel. Agora só inclui rollup.js e webpack. Não sei se é possível usar algum destes bundlers com a Foundation, mas, até agora, ainda não o consegui fazer. Se souberes como, deixa um comentário.

Resolvi o problema instalando o Babel e as outras ferramentas necessárias, escrevendo uma tarefa nativa do gulp e chamando essa tarefa na função do elixir. Assim:

1. Instalar as ferramentas necessárias

npm install gulp-babel gulp-concat gulp-uglify --save-dev

E requerê-las no topo do gulpfile.js .

var babel = require('gulp-babel');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');

2. Escrever a tarefa do gulp

Escreve a tarefa do gulp, fora da função do elixir, que compila os ficheiros com o babel, concatena-os, minifica-os (com o uglify) e escreve o resultado no caminho desejado. De notar que os caminhos relativos, aqui, são diferentes, são relativos à raiz do projecto (onde está o gulpfile.js).

gulp.task('scripts', function() {

    var jQuery = 'node_modules/jquery/dist/jquery.js';
    var foundationJsFolder = 'node_modules/foundation-sites/js/';

    return gulp.src([
        jQuery,
        foundationJsFolder + 'foundation.core.js',
        // Include any needed components here. The following are just examples.
        foundationJsFolder + 'foundation.util.mediaquery.js',
        foundationJsFolder + 'foundation.util.keyboard.js',
        foundationJsFolder + 'foundation.util.timerAndImageLoader.js',
        foundationJsFolder + 'foundation.tabs.js',
        // This file initializes foundation
       'resources/assets/js/start_foundation.js'
    ])
    .pipe(babel())
    .pipe(concat('all.js'))
    .pipe(uglify())
    .pipe(gulp.dest('./public/js'));
});

3. Chama a tarefa a partir do elixir

Finalmente, na função do elixir, em vez de chamar mix.babel, chama a tarefa que escreveste. O primeiro parâmetro é o nome da tarefa e o segundo é o caminho onde observar alterações que devam activar a tarefa. Possivelmente, vais queres ajustar isto às tuas necessidades.

mix.task('scripts', 'resources/**/*.js');

Claro, também podes chamar a tarefa directamente a partir da linha de comandos com gulp scripts.

4. Sass

A compilação do sass funciona quase da mesma forma que anteriormente. A única diferença é que agora aceita quatro parâmetros, por isso deve ser chamada da seguinte forma:

mix.sass('app.scss', null, null, options);