Laravel Elixir and Zurb Foundation, revisited

Edited on 25 November 2016: Check the bottom of the post for an Elixir 6 update.

Last time I wrote about using the Foundation framework in Laravel Elixir I said that the npm package didn’t install the needed dependencies and, because of that, we had to use the Bower package. Not sure if I was wrong or if that changed after I wrote it but that’s not the case now.

Not only that, but we now have a new version of the front-end framework, Foundation for Sites 6. So, I think it’s a good idea to rewrite the tutorial to replace Bootstrap with Foundation in Laravel Elixir.

0. Set up

Before we start, make sure you have Node.js, npm and gulp (as a global package) installed and working. In the root of your project you should be able to run the npm install and gulp commands without errors.

Check the Laravel Elixir documentation for more info.

1. Install Foundation

1.1. If you haven’t yet, install the npm dependencies. Before you run the following command you may want to remove the bootstrap-sass line from the package.json file, so it doesn’t install the Bootstrap framework.

npm install

1.2. If the Bootstrap framework is already installed, you can remove it with the following command.

npm rm bootstrap-sass --save

1.3. Install the Foundation framework.

npm install foundation-sites --save

1.4. (optional) Foundation 6 comes with a new Motion UI, a Sass library for creating flexible UI transitions and animations. Install it with the following command.

npm install motion-ui --save

If you don’t want to use it, just remove any references to Motion UI in the following files.

2. Create sass files

Now, you’ll need two files, usually in the “resources/assets/sass” folder. These are the files that you’re going to edit.

2.1. Copy the “_settings.scss” file from “node_modules/foundation-sites/scss/settings” to “resources/assets/sass”. This file contains all the parameters of the various elements of Foundation that you can customize.

2.2. In “resources/assets/sass” create a file called “app.scss” with the following content. This is the main file, where you do all the imports / includes and write your own 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;

My advice is to comment all the includes and only uncomment the ones you need, as you need them (note that the foundation-global-styles seems to be pretty much always needed).

3. Write the Elixir tasks

Now, you have to write the Elixir tasks that will compile the SCSS to CSS and copy and concatenate the JavaScript files.

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.babel([
       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'
    ]);

});

In the JavaScript task, we copy and concatenate the needed files to Foundation work properly. At a minimum, we need “jquery.js” and “foundation.core.js”. Then we add the files for the components that we’ll use (the files listed are only an example). The “start_foundation.js” file includes only the code to initialize Foundation ($(document).foundation();).

4. Run gulp

Finally, you are ready to run gulp  or gulp watch (to run the tasks automatically every time something changes). Doing that will generate a file called “app.css” in “public/css” and a file called “all.js” in “public/js” that you can include in your view files.

Note: If you want the created files to also be minified you must add the flag –production  (gulp –production or gulp watch –production).

Update to Elixir 6

For some reason that I can’t understand Elixir 6 doesn’t support Babel anymore. Now it only includes rollup.js and webpack. I don’t know if its possible to use any these bundlers with Foundation, but I haven’t been able to make them work so far. If you know how let me know in the comments.

I solved this issue by installing Babel and the other tools needed, making a gulp native task and then calling that task from the elixir function. This is how:

1. Install the needed tools

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

And require them at the top of the gulpfile.js .

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

2. Write the gulp task

Write a gulp task, outside the elixir function, that compiles the files with babel, concatenates them, minifies them (with uglify) and outputs the result to the desired path. Notice that the relative paths are different here, they are relative to the project root (where the gulpfile.js is).

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. Call the task from elixir

Finally, inside the elixir function, instead of calling mix.babel call the task that you wrote. The first parameter is the name of the task and the second is the path to watch for changes that should trigger the task. You may want to adjust this to your needs.

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

Of course, you may also call the task directly from the command line with gulp scripts .

4. Sass

The sass compilation works almost the same way as before. The only difference is that it now takes four parameters, so you should call it like this:

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