How to setup Foundation Sites 6 + Brunch + Phoenix app?

Hello, everyone!

I’m trying to setup Foundation 6 in my Phoenix app. Following this link I could make it work but I had to copy some files manually to the vender directory.

I also found this template in coffee script but this configuration didn’t worked for me :frowning2:

Here’s my packages.json:

{
  "repository": {},
  "license": "MIT",
  "scripts": {
    "deploy": "brunch build --production",
    "watch": "brunch watch --stdin"
  },
  "dependencies": {
    "foundation-sites": "^6.3.0-rc1",
    "motion-ui": "^1.2.2",
    "phoenix": "file:deps/phoenix",
    "phoenix_html": "file:deps/phoenix_html",
    "sass-brunch": "^2.7.0"
  },
  "devDependencies": {
    "babel-brunch": "~6.0.0",
    "brunch": "2.7.4",
    "clean-css-brunch": "~2.0.0",
    "css-brunch": "~2.0.0",
    "javascript-brunch": "~2.0.0",
    "uglify-js-brunch": "~2.0.1"
  }
}

And by brunch-config.js:

exports.config = {
  // See http://brunch.io/#documentation for docs.
  files: {
    javascripts: {
      joinTo: "js/app.js"

      // To use a separate vendor.js bundle, specify two files path
      // http://brunch.io/docs/config#-files-
      // joinTo: {
      //  "js/app.js": /^(web\/static\/js)/,
      //  "js/vendor.js": /^(web\/static\/vendor)|(deps)/
      // }
      //
      // To change the order of concatenation of files, explicitly mention here
      // order: {
      //   before: [
      //     "web/static/vendor/js/jquery-2.1.1.js",
      //     "web/static/vendor/js/bootstrap.min.js"
      //   ]
      // }
    },
    stylesheets: {
      joinTo: "css/app.css",
      order: {
        after: ["web/static/css/app.css"] // concat app.css last
      }
    },
    templates: {
      joinTo: "js/app.js"
    }
  },

  conventions: {
    // This option sets where we should place non-css and non-js assets in.
    // By default, we set this to "/web/static/assets". Files in this directory
    // will be copied to `paths.public`, which is "priv/static" by default.
    assets: /^(web\/static\/assets)/
  },

  // Phoenix paths configuration
  paths: {
    // Dependencies and current project directories to watch
    watched: [
      "web/static",
      "test/static"
    ],

    // Where to compile files to
    public: "priv/static"
  },

  // Configure your plugins
  plugins: {
    babel: {
      // Do not use ES6 compiler in vendor code
      ignore: [/web\/static\/vendor/]
    },
    sass: {
      options: {
        includePaths: [
          'node_modules/foundation-sites/scss',
          'node_modules/motion-ui/src',
        ]
      }
    }
  },

  modules: {
    autoRequire: {
      "js/app.js": ["web/static/js/app"]
    }
  },

  npm: {
    enabled: true,
    globals: {
      $: 'jquery',
      jQuery: 'jquery',
    }
  }
};

Also, my sass files in web/static/scss:

@import "settings";
@import "foundation";
@include foundation-everything;
@import "motion-ui";
@include motion-ui-transitions;

@import "custom";

This is the error that brunch watcher throws when trying to compile:

[info] Running Swarm.Endpoint with Cowboy using http://localhost:4000
02 Dec 15:53:35 - error: Compiling of web/static/scss/app.scss failed. File to import not found or unreadable: normalize
Parent style sheet: node_modules/foundation-sites/scss/foundation.scss 
02 Dec 15:53:35 - info: compiled 6 files into 2 files, copied 3 in 1.3 sec

Which is weird since I’m telling brunch to use foundation from node_modules.

I’m not a frontend developer, just want to make my app look a bit better :slight_smile:

Thank you!

1 Like

Well first of note, but is not related to this issue, you can put your “sass-brunch” line in the package.json file in the devDependencies section instead of dependencies, but that will not cause an issue regardless. :slight_smile:

Second, your file is including foundation.scss, successfully, but the foundation.scss is including this:

However, as you can see here:

There is no normalize-scss file in their repository. For note, normalize-scss is usually included by https://www.npmjs.com/package/normalize-scss, and by looking it seems they do have that set as a dependency:
https://github.com/zurb/foundation-sites/blob/develop/package.json#L20

However your sass include definitions is only this:

    sass: {
      options: {
        includePaths: [
          'node_modules/foundation-sites/scss',
          'node_modules/motion-ui/src',
        ]
      }
    }

You are not including the normalize-css modules, so you probably need to change it to this:

    sass: {
      options: {
        includePaths: [
          'node_modules/normalize-scss/sass',
          'node_modules/foundation-sites/scss',
          'node_modules/motion-ui/src',
        ]
      }
    }

So, does that work? :slight_smile:

3 Likes

Thanks for the tip :smiley:

Wow

Nice!

Yes!

I only had to use foundation-sites 6.2.0 instead of 6.3.0-rc1 because it was not working :smiley:

Thank you very much!

Awesome! Thanks for the follow-up! ^.^

I am trying to set up foundation sites 6 + Brunch + Phoenix App but I don’t why I am having this error.

 Running ESavings.Web.Endpoint with Cowboy using http://0.0.0.0:4000
Interactive Elixir (1.4.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 01:09:59 - info: compiled 8 files into 2 files, copied 290 in 2.1 sec
01:09:59 - error: Cannot read property 'verbose' of undefined
Stack trace was suppressed. Run with `LOGGY_STACKS=1` to see the trace. ^G

I have read through the post referenced here and the suggestions here.

This is brunch-config.js file

exports.config = {
  // See http://brunch.io/#documentation for docs.
  files: {
    javascripts: {
      joinTo: "js/app.js"
    },
    stylesheets: {
      joinTo: "css/app.css",
      order: {
        after: ["css/app.css"] // concat app.css last
      }
    },
    templates: {
      joinTo: "js/app.js"
    }
  },

  conventions: {
    // This option sets where we should place non-css and non-js assets in.
    // By default, we set this to "/assets/static". Files in this directory
    // will be copied to `paths.public`, which is "priv/static" by default.
    assets: /^(static)/
  },

  // Phoenix paths configuration
  paths: {
    // Dependencies and current project directories to watch
    watched: ["static", "css", "js", "vendor"],
    // Where to compile files to
    public: "../priv/static"
  },

  // Configure your plugins
  plugins: {
    babel: {
      // Do not use ES6 compiler in vendor code
      ignore: [/vendor/]
    },
    sass: {
      options: {
        includePaths: [
          'node_modules/normalize-scss/sass',
          'node_modules/foundation-sites/scss',
          'node_modules/motion-ui/src'
        ]
      }
    }
  },
  modules: {
    autoRequire: {
      "js/app.js": ["js/app"]
    }
  },
 npm: {
    enabled: true,
    globals: {
      $: 'jquery',
      jQuery: 'jquery',
    }
  }
};

I checked the priv/static/css folder, I am not seeing the foundation files include.

This is my package.json file

{
  "repository": {},
  "license": "MIT",
  "scripts": {
    "deploy": "brunch build --production",
    "watch": "brunch watch --stdin"
  },
  "dependencies": {
    "foundation-sites": "^6.3.1",
    "jquery": "^2.2.4",
    "motion-ui": "^1.2.2",
    "phoenix": "file:../deps/phoenix",
    "phoenix_html": "file:../deps/phoenix_html"
  },
  "devDependencies": {
    "babel-brunch": "6.0.6",
    "brunch": "2.10.7",
    "clean-css-brunch": "2.10.0",
    "copycat-brunch": "^1.1.0",
    "css-brunch": "2.10.0",
    "sass-brunch": "^2.10.4",
    "uglify-js-brunch": "2.1.1"
  }
}

Please help

1 Like

Some of your paths look different then mine.

Have a look at these config files. This project is configured to use Foundation, FontAwesome and Turbolinks.

For foundation you’ll still need to have the _custom.scss and _settings.scss files in web/static/scss, you can follow Foundation’s guides to know the proper way to use those files. And in your main app.scss you have to import foundation properly:

@import "settings";
@import "foundation";
@include foundation-everything;
@import "motion-ui";
@include motion-ui-transitions;
@import "font-awesome";
@import "custom";

The same goes for Foundation’s JS libraries. In your web/static/js/app.js file you have to init Foundation. In my app.js file I also start Turbolinks:

import "phoenix_html"
import "foundation-sites"
import Turbolinks from 'turbolinks';

Turbolinks.start();

Hope that helps.

1 Like

Thanks so much. I have followed the steps you outlined.

When I check the page source, I can see that the foundation and the turbolinks javascript files have been loaded.

However, the foundation styles are not loaded.

Here is my brunch-config.js

exports.config = {
  files: {
    javascripts: {
      joinTo: "js/app.js"
    },
    stylesheets: {
      joinTo: "css/app.css",
      order: {
        after: ["css/app.css"]
      }
    },
    templates: {
      joinTo: "js/app.js"
    }
  },
 
  conventions: {
    assets: /^(assets)/
  },
 
  paths: {
    watched: [ "static", "css", "js", "vendor"],
 
    public: "../priv/static"
  },
 
  plugins: {
    babel: {
      ignore: [/vendor/]
    },
    sass: {
      options: {
        includePaths: [
          'node_modules/normalize-scss/sass',
          'node_modules/foundation-sites/scss',
          'node_modules/motion-ui/src',
          'node_modules/font-awesome/scss'
        ]
      }
    },
    copycat: {
      "fonts": ["node_modules/font-awesome/fonts"],
      verbose: true,
      onlyChanged: true
    }
  },
 
  modules: {
    autoRequire: {
      "js/app.js": ["js/app"]
    }
  },
 
  npm: {
    enabled: true,
    globals: {
      $: 'jquery',
      jQuery: 'jquery',
    }
  }
};

and here is my app.js file

import "phoenix_html";
import "foundation-sites";
import Turbolinks from 'turbolinks';

Turbolinks.start();

Then this is my app.css

@import "../scss/app.scss";

I know there is something I am doing wrong. Thanks for your help.

1 Like

Have you started foundation in your layout file (in my case it is web/templaes/layout/app.html.eex)? Add this in right before the </body>

    <script>$(document).foundation();</script>
1 Like

If you are using SASS then you don’t need the app.css. Brunch will compile your app.scss :slight_smile:

1 Like

Thanks so much. But I am still lost. From the brunch-config.js, you saw where I stated that it should use sass to include foundation. I have installed sass-brunch. Is there something else I need to do? Do I need to specially install sass separately? Right now, I have a folder called scss that contains _settings.scss, _custom.scss, and app.scss. There is also a folder called css that contains app.css and phoenix.css. Please advice on what I should do next. Thank you so much for your help

1 Like

Finally, I think it is working now. This is the change That I made

I added scss folder to the list of the watched directories

paths: {
    watched: [ "static", "css", "js", "vendor", "scss"], 
    public: "../priv/static"
  },

Then I got the settings from [here] (https://raw.githubusercontent.com/zurb/foundation-sites/master/scss/settings/_settings.scss) which is the latest settings from foundation zurb site.

However, I am noticing a strange error.

Task #PID<0.374.0> started from Donations.Web.Endpoint terminating
** (stop) :watcher_command_error
    (phoenix) lib/phoenix/endpoint/watcher.ex:29: Phoenix.Endpoint.Watcher.watch/3
    (elixir) lib/task/supervised.ex:85: Task.Supervised.do_apply/2
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Function: &Phoenix.Endpoint.Watcher.watch/3
    Args: ["node", ["node_modules/brunch/bin/brunch", "watch", "--stdin"], [cd: "/home/smith/Documents/tutorials/nsblo
ggers/donations/assets"]]

What could be responsible?

1 Like

I checked my console, I noticed I am having this error

Uncaught Error: Cannot find module 'js/app' from '/'
    at require (app.js:62)
    at app.js:22309
1 Like

Well,

I made this small project to study Phoenix + Brunch a few months ago but it was private in my Github account (actually a forgot to delete it, haha). But since other people may stumble with the same problem in the future, I’ll make it available and keep it.

Civitas on Github

It uses FontAwesome, Foundation Sites 6 and Turbolinks.

I hope it helps!

2 Likes

I made a guide for setting up Zurb Foundation on a Phoenix app. The first half goes through a the installation steps which should be enough if you’ve used foundation before. The second half is just a demo some foundation functionality.

3 Likes

This thread has been super helpful with getting Foundation setup. SASS is working great, but I can’t get the JS to compile. With Foundation-Sites 6.4, I have the following brunch-config.js:

exports.config = {
  // See http://brunch.io/#documentation for docs.
  files: {
    javascripts: {
      joinTo: {
        "js/app.js": /^(web\/static\/js)|(node_modules)/,
        "js/ex_admin_common.js": ["web/static/vendor/ex_admin_common.js"],
        "js/admin_lte2.js": ["web/static/vendor/admin_lte2.js"],
        "js/jquery.min.js": ["web/static/vendor/jquery.min.js"]
      }
    },
    stylesheets: {
      joinTo: {
        "css/app.css": /^(web\/static\/css)/,
        "css/admin_lte2.css": ["web/static/vendor/admin_lte2.css"],
        "css/active_admin.css.css": ["web/static/vendor/active_admin.css.css"],
      },
      order: {
        after: ["web/static/css/app.css"] // concat app.css last
      }
    },
    templates: {
      joinTo: "js/app.js"
    }
  },

  conventions: {
    // This option sets where we should place non-css and non-js assets in.
    // By default, we set this to "/web/static/assets". Files in this directory
    // will be copied to `paths.public`, which is "priv/static" by default.
    assets: /^(web\/static\/assets)/
  },

  // Phoenix paths configuration
  paths: {
    // Dependencies and current project directories to watch
    watched: [
      "web/static",
      "test/static"
    ],

    // Where to compile files to
    public: "priv/static"
  },

  // Configure your plugins
  plugins: {
    babel: {
      // Do not use ES6 compiler in vendor code
      ignore: [/web\/static\/vendor/]
    },
    sass: {
      options: {
        includePaths: [
          'node_modules/normalize-scss/sass',
          'node_modules/foundation-sites/scss',
          'node_modules/motion-ui/src',
        ]
      }
    }
  },

  modules: {
    autoRequire: {
      "js/app.js": ["web/static/js/app"]
    }
  },

  npm: {
    enabled: true,
    globals: {
      $: 'jquery',
      jQuery: 'jquery',
    }
  }
};

And my app.js file:

// Brunch automatically concatenates all files in your
// watched paths. Those paths can be configured at
// config.paths.watched in "brunch-config.js".
//
// However, those files will only be executed if
// explicitly imported. The only exception are files
// in vendor, which are never wrapped in imports and
// therefore are always executed.

// Import dependencies
//
// If you no longer want to use a dependency, remember
// to also remove its path from "config.paths.watched".
import "phoenix_html"

import "foundation-sites"
// Import local files
//
// Local files can be imported directly using relative
// paths "./socket" or full ones "web/static/js/socket".

// import socket from "./socket"

When I try to build with brunch, I get the following error:

$ ./node_modules/.bin/brunch build
16 Jul 21:02:19 - error: undefined of node_modules/foundation-sites/dist/js/npm.js failed. rror: 'import' and 'export' may only appear at the top level (5:4)
16 Jul 21:02:19 - info: compiled 12 files into 7 files, copied 23 in 3.9 sec

I figured out that I had to push NPM modules through the babel-brunch compile by adding config.npm.compilers = ['babel-brunch']

Sorry, where did you add this declaration exactly?

For future Googlers, here’s how I got it working with Phoenix 1.3.0. Note that I did not have to download settings.scss from Foundation’s site like OP above. This appears to work as-is, using the foundation-sites npm package’s bundled SASS files.

brunch-config.js:

exports.config = {
  // See http://brunch.io/#documentation for docs.
  files: {
    javascripts: {
    joinTo: "js/app.js"
  },
  stylesheets: {
    joinTo: "css/app.css"
  },
  templates: {
    joinTo: "js/app.js"
  }
},

conventions: {
  // This option sets where we should place non-css and non-js assets in.
  // By default, we set this to "/assets/static". Files in this directory
  // will be copied to `paths.public`, which is "priv/static" by default.
  assets: /^(static)/
},

// Phoenix paths configuration
paths: {
  // Dependencies and current project directories to watch
  watched: ["static", "scss", "js", "vendor"],
  // Where to compile files to
  public: "../priv/static"
},

plugins: {
  babel: {
    // Turbolinks comes as minified ES5, so tell babel not to bother transpiling it or wrapping it in a module
    ignore: [/vendor/, /turbolinks/],
    // This is important! babel-preset-latest is being deprecated
    presets: [['env', {
      targets: {
        browsers: ['last 2 versions']
      }
    }]]
  },
  sass: {
    options: {
      includePaths: [
        'node_modules/foundation-sites/scss',
        'node_modules/motion-ui/src',
      ]
    }
  }
},

modules: {
  autoRequire: {
    "js/app.js": ["js/app"]
  }
},

  npm: {
    enabled: true,
    compilers: ['babel-brunch'], // for transpiling Foundation
    globals: {
      $: 'jquery',
      jQuery: 'jquery',
    }
  }
};

app.js:

import "phoenix_html"
import "foundation-sites"

// import socket from "./socket"
import Turbolinks from "turbolinks"

Turbolinks.start()

package.json:

{
  "repository": {},
  "license": "MIT",
  "scripts": {
    "deploy": "brunch build --production",
    "watch": "brunch watch --stdin"
  },
  "dependencies": {
    "foundation-sites": "^6.4.4-rc1",
    "motion-ui": "^1.2.3",
    "phoenix": "file:../deps/phoenix",
    "phoenix_html": "file:../deps/phoenix_html",
    "turbolinks": "^5.0.3"
  },
  "devDependencies": {
    "babel-brunch": "6.1.1",
    "babel-preset-env": "^1.6.1",
    "brunch": "2.10.9",
    "clean-css-brunch": "2.10.0",
    "sass-brunch": "^2.10.4",
    "uglify-js-brunch": "2.10.0"
  }
}

app.html.eex

</div> <!-- /container -->
    <script src="<%= static_path(@conn, "/js/app.js") %>"></script>
    <script>$(document).foundation();</script>
  </body>
</html>

app.scss

@import "settings";
@import "foundation";
@include foundation-everything;
@import "motion-ui";
@include motion-ui-transitions;
2 Likes

Any idea on how to make it work (Foundation 6.5.3) with the latest Phoenix (1.5.3) version that does not use Brunch any more but webpack ? Thank you.