Meet Metroplex!


Like many front-end developers, I’ve found that I could actually harness the power of my computer to actually do stuff for me. Not just write code, tell software to do some tasks, then validate the results and start all over again. About a year ago, I came across this tool called Grunt.JS. It seemed like everybody was using it but I really felt like I didn’t need any of the features it provided. Granted, I wasn’t using Sass/Compass at the time or relying on a lot of stuff which I do today.

Ever since I started working with the Metropoly team, I found myself using the same tools and frameworks over and over again. I quickly started realizing: “Man, I need some sort of template tool to kickstart my projects. I lose so much time everytime I start something new“. I did some Googling and quickly I came full circle when Grunt.JS showed up again. Specifically for this task: Grunt-init showed up.

Grunt-init is a tool to deploy Grunt-templates when starting a project. Grunt-templates are actually just a set of files which you can use to bootstrap your project (which is powered by Grunt.JS).  The thing is: you don’t really need to use Grunt to actually use Grunt-init. However, I got caught up in the process of developing my perfect template for the job and I quickly ended up with a Grunt-setup that uses Grunt.JS anyway.  Funny how that goes, right?

It comes preloaded with Compass support, Twitter Bootstrap, a simple webserver, an icon-font that we use on just about any project, a build-system and an FTP upload command. I’ve had this setup for almost 2 months now and I have been tweaking and adapting it with every project I did. The current setup is pretty solid and does about 95% of what I need during every project.

I’ve decided to share this Grunt-init setup with you. However, I needed to get rid of the icon font in this version (as it was a premium thing which we bought but cannot be shared (BOOHOO). So I just tore that icon-font out of the setup and shared the remaining setup on Github.

You can check it out here.

Why is it called Metroplex?

screenshot_ 2014-06-28 at 21.41.51

Metroplex is a tool that grew naturally during my time working with Metropoly. It’s the result of a partnership between Metropoly team-members and IO Art Factory. 2 dev-geek-teams coming together and building something incredibly powerful and beautiful.

Cool, tell me more tech-geek-stuff about this!

For some more in-depth info: read on. For those of you who don’t care too much about this stuff: It’s okay to stop reading here 😉

Twitter Bootstrap

Everybody likes Twitter Boostrap, right? (If you don’t, I don’t care. I do :-p ) So I included the entire Twitter Bootstrap framework in this. And I mean the SCSS files, not the compiled CSS files. That means any Bootstrap mixins are ready to use. I only embedded the Bootstrap Grid as that’s the only one I actively use for now. But if you’re like me and like to explore that stuff some more, no problems there. (I just realized, I haven’t included any of the Bootstrap JS files… Oops.)


The default Grunt task runs a watch for JS file changes and .scss file changes. More about the JS later. The .scss files get compiled using Compass. I love Compass since it has so many great mixins that come with it to facilitate life.

JS Compiler

There we go: I bet many of your are wondering which of the many JS dependency management tools I use… ComponentJS? RequireJS? The answer is: NONE. Honestly, I investigated a few of them but they all dicated the way I had to code my projects. Everything needs to be in modules and stuff. Then I need to use their JS framework to get things started… Nah-ah.

So I basically wrote a super-simple JS compilation task that opens the src/js_src folder and takes all .js files in there and concatenates them into a single app.js file. In order to make sure your files are concatenated in the right order, it has some rules. First it looks for all filenames that start with an underscore (e.g.: _utils.js, _class.product.js), then it looks for all other files except app.js (e.g.: forms.js, sidebar.js) and lastly it appends the app.js file to it and saves that compiled file in js/app.js. 

So basically there’s 3 levels of file-importance

  1. Underscore files: I usually put classes and util-functions in there. Least important files. Get included first.
  2. Named files. These can hold page dependant code or split up some of the functionality in your site/app.
  3. app.js: Most important file. This is where I usually set up events, handlers and asign tasks/variables for the actual site to work. At this point all your dependencies are loaded, so it’s safe to call all of your stuff. Get’s included last.

I can feel how people are frowning just thinking about the idea of this setup, however this is all I ever needed. I’m not building enterprise-sized Javascript applications. I’m building interactions that work on websites and dashboards. For this purpose, this setup will do just fine and gives me complete freedom in developing in whatever way I want.

Build tool

There are 2 build types in this setup. DEV and RELEASE. Dev is just compilation of the CSS and the JS files without minimizing them. Minimizing is only done in the build version. This comes in handy when you want to debug some files while running on the site itself.

FTP upload

While I develop on my local machine and host a local testing server, from time to time, the website files need to be uploaded to a server where the team / client can review the current state. Because of all the additional files that are in this Grunt-setup, it can be quite a tedious task to upload this to the server. You don’t need your Gruntfile.js to be on your server. Or the .gitignore file. Or the config.rb file. Or the uncompiled .scss and .js files.

So what we do is we call the deploy task which creates a dev/release build (in the build folder) and then just uploads the contents of that folder to an FTP server of your choice. If you haven’t setup your FTP settings for this project yet, Grunt actually prompts you with a UI that asks your for the FTP credentials and remote path and saves those settings in a ftp_config.json file. So the next  time you run the deploy command it builds the newest version and then resorts to that config-file to upload it to your FTP.

If you’re like me and you use the same FTP settings over and over again but only need to set the remote path on the FTP where the files will be uploaded, you can even setup a defaults.json in your Grunt-init template folder. It’s ignored by the .gitgnore file in the template and the Metroplex repo, so your defaults.json will never be added to your GIT commits (ftp_config.json on the other hand IS NOT ignored by .gitignore). This file will propose FTP credentials during the FTP setup when deploying for the first time. Just hit enter in the prompt and the default will be used.

Testing Server

If you’re like me, you run a lot of tiny projects. What I do is I make a new folder on my computer’s Desktop, install the Metroplex Grunt-init template and I’m up and running with my testing project in mere seconds. However if I then try to run my experiment in the browser, I usually need to head into MAMP and set up a temporary server to test this.

No more of this with grunt server. This runs the same watch tasks as the default task does but it also adds a basic HTTP webserver that serves static files just fine on localhost:13337 . That way I can now start an experiment, run and test it and then clean it up when I’m done. Since everything is in one single place, I don’t end up with files, settings, testing servers all over the place. Brilliant, right?

All of the tasks are explained on the Github repo overview page. Check it out!

That’s it! Let me know if you use it, how it becomes or if you have suggestions.


view all posts

Ronny is a freelance frontend developer with a wild passion for creativity and a relentless hate against flat design. Ronny spent years as a Flash developer before moving to HTML5 and rediscovering fun and happiness.

0 Comments Join the Conversation →

Leave a Reply

Your email address will not be published. Required fields are marked *