<![CDATA[David Bashford]]>Mimosa.]]>http://127.0.0.1:2368/Ghost v0.4.0Mon, 03 Nov 2014 20:23:28 GMT60<![CDATA[Enhanced Ember Mimosa tooling and a New Ember Skeleton]]>TL;DR

I'm going to talk through a few new Mimosa modules that solve some tooling gaps with Ember, and then I'll quickly discuss a new Mimosa skeleton that brings it all together. You can, though, skip the jibber-jabber and get straight to the new Ember skeleton and check out the result of all of this coming together.

Mimosa and Ember

In January of this year we made the switch from Backbone to Ember. We needed the power up and the team was ready to move on after two years writing a lot of boilerplate. After the initial, expected, much talked about learning curve was conquered the productivity boosts and code reduction we expected have arrived. When we were getting going, the tooling was already in place for Ember developers to use Mimosa to build their apps.

Several modules catered to doing Ember work.

There were also several skeleton apps to get you started with Ember. They usually also include tasks like application packaging and CSS/JS transpiling:

Tooling Gaps

I hesitated to attempt to solve any other Ember-specific tooling problems until we had a chance to really get going with a big Ember project. After awhile, we began to see some big gaps that could be filled with some smart modules.

The two big problems that needed module solutions were application wiring and Ember-specific testing support.

Wiring Up an Ember App

It is common to assign your Ember.Application instance to a global variable, and then define all of the framework factory classes (controllers, routes, views, etc.) as properties of this object:

window.App = Ember.Application.create();  
App.PostsRoute = Ember.Route.extend();  
App.PostsController = Ember.ArrayController.extend();  

Ember will be able to use the right components of your application at the right time. For instance, when you visit /posts, Ember will resolve the corresponding route, controller, view, and template by looking them up on the App namespace.

To achieve this in a modular web application, you can choose to attach your Ember assets from within each individual module, or you can choose to bring all the modules together in one place and attach them all at once.

Bringing the App to the Modules

views/post_view.js

var App = require('app');  
App.PostView = Ember.View.extend(...);  

In this case we're bringing the Ember application (Ember.Application.create()) to the PostView module.

But this option is semantically wrong. A small component of an an application doesn't depend on the larger application. The application depends on it. And something still needs to require/import this view. What would do that?

Bringing the Modules to the App

A better approach is to create an application manifest file (of sorts) where the application and its modules are brought together and wired up. When solving this problem, we created a modules.js file that pulled together all the various Ember assets in one place and attached them to App. Doing this results in individual assets that know nothing about the larger application and are therefore more modular.

views/post_view.js

var PostView = Ember.View.extend(...);  
export default PostView;  

Here, rather than attaching to App, the view just exports itself. Now anything that needs it (multiple apps? test harness?) can import it without needing the app.

Here's the modules.js file where we pull the application together.

modules.js

import App from 'app';

import PostView from 'views/post_view';  
App.PostView = PostView;

import PostController from 'controllers/post_controller';  
App.PostController = PostController;

import Post from 'models/post';  
App.Post = Post;  
...

All the wiring of the various Ember assets occurs in a single place. No bringing the app in as a dependency to every Ember asset.

But, boilerplate much?

Our production app's modules.js has around 600 lines and counting. Whenever a developer creates a new asset, they have to remember to go add it to that file. It's not a huge hurdle, but given how boilerplate it is, it begs for a tooling solution...

mimosa-ember-module-import

mimosa-ember-module-import was developed to solve the problem of module "manifest" creation. With a trivial amount of config (6 lines in the skeleton's case) you can include this module and get your manifest file autogenerated during mimosa build and mimosa watch.

The module will output a manifest file in AMD format by default, but it also supports spitting out CommonJS. Here's an example manifest file in AMD.

define( function( require ) {  
  var _0 = require('./views/post_view');
  var _1 = require('./controllers/post_controller');
  var _2 = require('./models/post');

  var modules = {
    PostView: _0 && (_0['default'] || _0),
    PostController: _1 && (_1['default'] || _1),
    Post: _2 && (_2['default'] || _2),
  };
  return modules;
});

This file can then be imported and used by Ember during app creation a few different ways.

import modules from 'modules';  
import App from 'app'; // class not instance  
App.createWithMixins(modules);  

...or...

import modules from 'modules';  
var App = Ember.Application.extend(modules);  

Supports Multiple Apps

Something that is lacking with other tools is an ability to support multiple apps in the same project. We have that case so it was important all the tooling solutions supported it. mimosa-ember-module-import supports multiple applications within a single project with a small tweak to the config.

Config with one app

emberModuleImport: {  
  apps: [{
    namespace: "blogger",
    manifestFile: "modules",
    additional: ["router"]
  }]
}

Config with two apps

emberModuleImport: {  
  apps: [{
    namespace: "blogger",
    manifestFile: "blogger-modules",
    additional: ["router"]
  }, {
    namespace: "admin",
    manifestFile: "admin-modules",
    additional: ["router"]
  }]
}

It should be easy to see, adding more applications is as simple as adding another entry to the array.

Testing an Ember App

mimosa-testem-require and its fork mimosa-testem-qunit both solve a lot of problems that come with writing browsers tests. The goal of both is to allow you to Just Write Tests. No need to waste time figuring out how to wire tests up and get the running.

With Ember apps though, there's some additional work to do that is currently beyond those modules' capabilities.

mimosa-ember-test

mimosa-ember-test was created to double the support provided by the modules created before it.

An important note, this module assumes require.js usage. This module is about wiring together not only Ember's tests and testing support, but doing so in a require.js/AMD application.

Below are some of the features of mimosa-ember-test.

Continued from Previous Modules

The previous Mimosa testing modules included:

  1. Support for running tests during build and watch
  2. Built on Testem, a first-class test runner.
  3. Automatic wiring of testing assets into the .mimosa directory, far from your application's code.
  4. Automatic detection and inclusion of tests
  5. Built-in support for Sinon, Require.js (and QUnit in this module's case)
  6. Command, mimosa testscript, to autogenerate script to run Testem interactive client
  7. testem ci support

mimosa-ember-test continues all of this and builds onto it.

ember-qunit

An increasingly popular library to help you unit test your Ember apps is the aptly named ember-qunit. It introduces helper functions which make writing Ember tests easier. Any top notch Ember testing support needs to include ember-qunit, so any module we created to support Ember testing needed to include ember-qunit in its testing scaffolding.

mimosa-ember-test includes ember-qunit in its test scaffolding and makes its functions globally available.

Built-in Bower Support for Testing Assets

We wanted to make sure it was easy to update testing assets. Previous modules would require you to either update specific test assets (like QUnit or Sinon) if you needed newer versions or submit pull requests to the module repo to update assets.

mimosa-ember-test can, when configured (it is by default), utilize the functionality provided by mimosa-bower to Bower in your test assets. Toss the required dependencies in your bower.json and you are ready to go.

"devDependencies": {  
  "qunit": "1.14.0",
  "requirejs": "2.1.14",
  "sinonjs": "1.10.2",
  "ember-qunit":"0.1.8"
}

If Bower isn't your thing, then mimosa-ember-test does come with its own versions of the test assets. Turn Bower-ing of assets off (bowerTestAssets:false) and mimosa-ember-test will copy in the assets it has. Biggest downside to this is that the ember-test module may, over time, fall slightly out of date.

As with previous modules, you can copy in your own assets and tell mimosa-ember-test to not overwrite them.

Multiple Apps

As with the module-import module above, mimosa-ember-test supports multiple apps. It will partition all test assets and scaffolding by app and will run each application's tests separately. Additionally, the mimosa testscript will kick out scripts capable of running interactive tests for specific apps.

Pulled Together: Ember Skeleton

To show off some of the work we've done and to give ourselves a good starting point for our Ember development, we put together an Ember Skeleton.

Get the Skeleton setup

Just a few steps.

mimosa build will pull in all the Mimosa modules not already in Mimosa.

Module Manifest

mimosa build will generate a modules.js file for the app that is configured. Here's that output:

define( function( require ) {  
  var _0 = require('./controllers/post_controller');
  var _1 = require('./helpers/helpers');
  var _2 = require('./router');
  var _3 = require('./routes/post_route');
  var _4 = require('./routes/posts_route');

  var modules = {
    PostController: _0 && (_0['default'] || _0),
    Helpers: _1 && (_1['default'] || _1),
    Router: _2 && (_2['default'] || _2),
    PostRoute: _3 && (_3['default'] || _3),
    PostsRoute: _4 && (_4['default'] || _4)
  };
  return modules;
});

The skeleton is also all wired up to use the modules.

require(['common'], function() {  
  require(['app', 'blogger/modules'], function(App, modules) {
    window.Blogger = App['default'].createWithMixins(modules);
  });
});

Tests

The skeleton app comes with some tests already written. mimosa build not only runs a full build of the app, it also, by default, executes the tests CI-style. Here's the messaging from the tests.

17:48:08 - Success - 4 of 4 tests passed for .mimosa/emberTest/tests/testem.json.  
ok 1 PhantomJS 1.9 - Acceptances - Posts: displays all recent posts  
ok 2 PhantomJS 1.9 - Unit - PostController: #init  
ok 3 PhantomJS 1.9 - Unit - PostController: #edit  
ok 4 PhantomJS 1.9 - Unit - PostController: #doneEdit

1..4  
# tests 4
# pass  4
# fail  0

# ok

If you run mimosa testscript, you can get a script generated that when run will execute the interactive Testem UI.

Testem UI

About require.js

One of the biggest gripes about require.js is the syntax. I hope to address this in a future blog post, but this skeleton is an example of being able to use the best of require.js without a lot of the cruft.

  • You aren't coding AMD. It's pure ES6.
  • Mimosa understands require.js so that in many cases you do not. This isn't more true than with an Ember app with its very simple dependency tree
  • require.js allows you to only concatenate when you build. You can develop with individual assets. It doesn't matter how far source maps have come along, developing with optimized assets just isn't ideal.
  • Mimosa manages configuration for concatenation for you. It can figure out most of the configuration. In the case of the skeleton, it just needs a little help to swap in the production version of ember.js

Everything Else, Ember and Not

This skeleton includes plenty of other modules, some of which enable Ember, some which do not. I won't run down them all, but here are the highlights.

  • It incorporates ember-handlebars template compilation which, like all Mimosa template compilers, will concatenate all the templates into a single file. Multiple file support is just a few config params away
  • The es6-module-transpiler is included and most modules are coded using ES6 module syntax which is compiled to AMD.
  • Bower support is included and all vendor and test assets are Bower-ed in.
  • JavaScript is hinted and the .jshintrc is already set up to expect all of QUnit and ember-qunit's global variables.
  • SASS!
  • An Express server complete with a module that will bounce that server when server code changes. (A server isn't necessary, just included)
  • Live Reload with no browser plugins
  • Concatenation of vendor CSS
  • Minification of JS, CSS and images.
  • Packaging support, build your application with deployment in mind.

And this is just what is included in this starter skeleton. Mimosa has plenty of other modules available.

So Little Config

If Ember is your thing, then so are conventions. By sticking to a few simple conventions you can wire your app up with very little configuration. The skeleton has all of 93 lines of config and 30 of it is a very spaced out/commented array. For what this skeleton can do, that's a tiny amount of configuration.

Why Mimosa for Your Ember Application?

Besides the support listed above, in general, why Mimosa?

General Purpose but Customizable

I mentioned we moved from Backbone to Ember. That was a big change for our team. One thing that remained constant after the transition was Mimosa. Before making the switch ourselves, plenty of folks had been using Mimosa for their Ember apps, so all the support we needed to get going was already available.

Mimosa is multi-purpose. It doesn't have anything to do with Ember, but modules can be built to solve any problem set, including Ember's.

A Single Tool

If you need to add Grunt to your Mimosa app, it isn't because Mimosa isn't capable of doing what you need, it is because the module you need hasn't been built. (Try filling the gap? Or bring up your need?)

Stable and Supported

Mimosa may be new to you, but Mimosa isn't new. It predates many of the other tools. And I'm not going anywhere!

Try it out!

If you have any feedback, hit me up.

If you have any ideas about how Mimosa's Ember support could be better, hit me up.

Thanks!

Special thanks to Estelle DeBlois for her help building the above modules and giving this post a thorough sanity check. Her help has been invaluable!

And thanks to my team at Berico for patiently waiting on the above modules to land!

]]>
http://127.0.0.1:2368/enhanced-ember-mimosa-tooling-and-a-new-ember-skeleton/6349b9a4-ce46-40a6-a84f-1253deff0794Mon, 03 Nov 2014 20:17:24 GMT
<![CDATA[Bumping require.js to latest, but not in Mimosa, yet]]>Earlier today I released version 3.0.0 of mimosa-require, but I will not be including that version as a default dependency of Mimosa yet.

The version of mimosa-require included with Mimosa by default is 2.2.2. The only significant difference between 2.2.2 and 3.0.0 is the version of require.js inside those modules. 3.0.0 = require.js 2.1.14, 2.2.2 = require.js 2.1.6.

The story is long and complicated, but to keep it short, I won't be updating Mimosa to use require.js 2.1.14 by default until this bug is fixed: https://github.com/jrburke/r.js/issues/629. That bug prevents users of Mimosa who take advantage of mimosa-require's require.optimize.modules config from running optimized builds. Running optimized builds with require.optimize.modules would result in require.js erroring out. A minority of Mimosa users likely use that config, but I want to keep Mimosa's defaults at versions that don't break apps.

The latest require.js, 2.1.14, contains all sorts of improvements over the version Mimosa is currently stuck at, 2.1.6, including wrapShim. If you are not using the require.optimize.modules config, I highly recommend updating your project to use mimosa-require 3.0.0.

"What should I do?"

Not using require.optimize.modules? Then you should upgrade to 3.0.0. Using a specific version of a Mimosa module is easy. Simply update your mimosa-config.js modules array to point at the new version.

In your modules array, update "require" to "require@3.0.0". Here's an example from the Ember skeleton: https://github.com/dbashford/MimosaEmberSkeleton/blob/master/mimosa-config.js#L26

The next time you start up mimosa watch or mimosa build Mimosa will install version 3.0.0 of mimosa-require local to your project. Give that a shot: make the update and then re-run your optimized build to verify it still works.

]]>
http://127.0.0.1:2368/bumping-require-js-but-not-for-mimosa-yet/7884ccd2-42da-4982-9af9-01039d349013Sat, 06 Sep 2014 14:09:30 GMT
<![CDATA[Mimosa 2.3 Released]]>Today I released Mimosa 2.3. After 21 point releases on 2.2, this marks the first non-patch release in awhile. Here's a quick rundown of what to expect.

Fix for Chrome + CSS Live Reload

Mimosa's live reload module is capable of updating CSS without needing to reload the page. It does this by altering the URL to force a reload of the asset from the server. When the asset is loaded the new CSS is reevaluated and the page is repainted.

Some months back there were changes to how and when Chrome loaded, evaluated and repainted the page when CSS assets were updated. Chrome loads the updated CSS when expected, evaluates it, but does not affect a repaint unless the browser window has focus. If you have the browser behind your editor or on another monitor, you'd need to wave your mouse over Chrome to see the change happen. That is better than no live reload at all, but not not quite the same.

It took a couple stabs at it before finally coming up with the right hack to get this back to normal. Previously a query parameter was tweaked to force the CSS to reload. With the latest version of mimosa-live-reload the query parameter was not cutting it.

Now, just in Chrome (other browsers never stopped working) the CSS URLs are outright broken and then fixed. That convinces Chrome to do the repaint regardless of focus.

The small downside of this is you'll see a 404 in your debugger for the split second. But the net effect is the instant updating live reload you'd expect.

Updates for mimosa new

Since before 1.0 was released, very little has been changed for the mimosa new command. It went through a minor refactor that didn't result in any functionality or behavior changes, but that's it.

This release sees big updates to the servers you can get from mimosa new.

Getting Hapi

Hapi has been added as a server option. I've been playing around with Hapi myself and have enjoyed working with it. Now with mimosa new you can get a Hapi server delivered and ready to go for any of the 6 server templating options mimosa new supports.

Additionally a new skeleton has been created that incorporates Hapi along with Angular.js and Browserify.

Updating Express

The existing Express server received a huge overhaul. It's now up to date with the latest Express 4.7.2 after being stuck at 3.4 for awhile. Additionally all of the other dependencies have been updated to the latest and any required code changes as a result of those updates have been included.

Adding Express + Socket.io

New with 2.3 is an Express server that comes with Socket.io. Some of the most frequent questions I get are how to get socket.io set up with Mimosa such that Mimosa's live reload uses it. This new server option comes with that already set up.

New RPM Packaging Module

mimosa-rpm-package works much like the popular web-package module, but uses easy-rpm to create an RPM archive of an application.

server-reload Fixed Up

mimosa-server-reload, which will restart your node server when server assets change, has been plagued with timing issues going back to when it was created. Like with the live-reload issue above, it took a few hacks to get it right, but the timing issue has been addressed.

Across the Board Library Updates

Virtually every module (that I am responsible for) has had its dependencies updated. Additionally those modules, like those responsible for mimosa new and the template compilers, now deliver the latest versions of client libraries and server assets.

Also, from 2.2.20

A few patch releases ago a small change to mimosa-require -- the module responsible for providing support for AMD/RequireJS applications (like optimization of assets, validation of paths) -- resulted in a 20% - 50% performance improvement for large (100+ file) applications. Performance improvements will vary a bit depending on the sort of hardware you work with.

Up Next?

In the near-term:

  • A few skeletons on the way including ones for Marionette and Ember, from myself and some others.
  • A module for managing delivery of features via feature flags
  • A module for managing ember.js module imports, a build-tool "resolver" of sorts, that will determine what files need to be required for your Ember application and make sure you do not have to manage pulling them all in yourself
  • Tests for existing modules.
]]>
http://127.0.0.1:2368/mimosa-2-3-released/4d2988e3-d471-4c68-bb5d-948fab51c0f8Wed, 13 Aug 2014 00:22:06 GMT
<![CDATA[Mimosa vs Gulp/Cake/Grunt/Broccoli?]]>@mycozycloud put together a blog post a few days back that compared Grunt vs Cake vs Gulp vs Broccoli. It filled up my Twitter feed yesterday. JavaScript Daily posted it. It blew up more.

The winner? Broccoli. Why?

It’s the most flexible tool and the more concise one.

How does Mimosa stand up?

It wins!

Here's a repo with the example app.

This is the config.

exports.config = {  
  "modules": ["coffeescript", "coffeelint", "jshint"]
}

3 actual lines. 2 real lines. It compiles the CoffeeScript file and tosses in inline source maps for free.

Extra Credit

It will also run CoffeeLint on the CoffeeScript and JSHint on the compiled JavaScript. Go ahead, add a really long line of CoffeeScript and watch CoffeeLint tell you it doesn't care for it: CoffeeLint: Line exceeds maximum allowed length. Then add foo['bar'] = baz and watch JSHint chide you: ['bar'] is better written in dot notation.

And with the extra functionality, the config stays shorter than all the others.

Extra Extra Credit

Want to minify it?

Add minify-js to the list of modules. Run mimosa build -m.

Problem

It was a verrrrrrrrrrrry simple, unrealistic test case that was used to compare the various tools.

Conclusion

All this really proves is that given a very poor example, Mimosa blows away the competition for ease of use. The last thing I'm interested in doing is poking at the other tools based on this naive example.

But still, no matter the use case, I think this makes it clear that Mimosa is a contender and is worth consideration.

]]>
http://127.0.0.1:2368/mimosa-vs-the-others/731934ce-f8f5-4a87-9dad-78a338c81bdfSat, 21 Jun 2014 19:53:06 GMT
<![CDATA[Adhoc Modules: Custom Tasks & Baby Steps Towards Publishing Modules]]>The adhoc-module Mimosa module is real easy to use and makes adding custom build behavior a piece of cake. It is also a great gateway to learning how to build Mimosa modules that you wish to deploy to NPM for community use.

Need Truly Custom Behavior in Your Build?

Need some really specific functionality built into your Mimosa build? Maybe you need to do some install-time code manipulating. Or maybe you need to be able to swap out values of JavaScript properties based on your target environment. Possibly you have a deployable product and you need each deploy to vary slightly (different skin?) and you'd love Mimosa to handle that for you.

Until recently, you had three options:

  1. You could hope the task you need to perform was available as a module already. Most modules, though, are meant to be general in their function. So you might strike out quickly here.
  2. You could create your own module and stick it in NPM. That may not be desirable for you, though. You may not want to have to maintain it, and you may not want to expose any of what you might be doing at work in the form of a module.
  3. You could create a module locally, in your project or within your company's code repos, and mimosa mod:install it. This introduces another build step, though. Now all your developers have to make sure to mod:install a specific piece of code. And it means you may have another repo to manage.

Enter the Adhoc Module

The adhoc-module was released recently and it allows you to create modules within your code base and require them right into your project.

This module has a dead simple config:

adhocModule: {  
  modules: []
}

The modules array should contain required in stripped-down mimosa modules.

You would include adhoc modules like this:

adhocModule: {  
  modules: [
      require('./scripts/perform-transforms'),
    require('./scripts/deploy-to-heroku')
  ]
}

The paths above point at node code in the ./scripts directory. That code must expose a registration function that serves the exact same function as the registration function of any module you have plugged into your project.

In the case above, two modules are included. You can add as many as you wish.

What is registration?

For a complete rundown of how registration works, check the blog post on creating modules. That post is much larger in scope, though, so you may just want to keep reading, I'll cover it here in brief.

The registration function exposed by your adhoc modules is called as Mimosa is first starting up. It is a Mimosa module's (and adhoc module's) means to associate the execution of some code with a specific step in a Mimosa build.

The registration function is passed the mimosaConfig which contains the full configuration for your project's Mimosa process, including anything you've included in your own mimosa-config.js/coffee. The registration function is also passed a register function which when executed with the right parameters will notify Mimosa that it needs to call your code at a given point in Mimosa's processing.

register takes 4 parameters and when executed it plugs your code into the right place in Mimosa's processing.

  • The 1st parameter tells Mimosa during which build workflow the passed callback (3rd parameter) should be executed. The Mimosa web site covers all the various build workflows. Workflows include add/update/remove, buildFile, buildDone, and so on.
  • The 2nd parameter tells Mimosa what step during the workflow to execute the callback. Each workflow has a set of steps like beforeRead, afterCompile, and package. The complete set of workflow/steps can be seen by checking out the code.
  • The 3rd parameter is the callback. This should be a reference to a JavaScript function that contains the code you want to execute at the specific build workflow and build step. The callback is passed the mimosaConfig, an options object that contains information any files being currently processed, and a callback that is to be called when the module has finished its task.
  • The 4th parameter is optional. If your adhoc module is meant to process individual files, like JavaScript files, this parameter is your chance to make sure that your callback is only called with the right files. This parameter is an array of file extensions. Ex: ['html','htm'].

Using registration

At my day job we use adhoc modules extensively. Here's a quick registration function for one of our adhoc modules.

var _execute = function( mimosaConfig, options, next ) {  
  // do something
  next();
};

var _clean = ...

exports.registration = function( mimosaConfig, register ) {  
  if ( mimosaConfig.isBuild && mimosaConfig.isPackage ) {
    register( ["postBuild"], "beforeInstall", _execute );
  }
  register( ['preClean'], 'init', _clean );
};

You can see the registration function is only concerned with executing its code if the current process is a build (mimosa build) and if the --package flag has been used. In this case the _execute function is called during the beforeInstall step. This particular module (code omitted) performs transformations on server templates prior to deployment. Server-side code isn't usually in Mimosa's wheelhouse, but there's nothing stopping a Mimosa module from reading from the file system, making changes and writing back.

This particular module also registers for the preClean step during which any assets it may have been responsible for writing during the postBuild step can be cleaned up.

Use it to Learn How to Build Modules!

Using adhoc-modules locally is a great way to learn how to build larger modules that you may intend to distribute. It's super easy to get started.

Just toss some code in a directory in your app, add adhoc-module to your node modules, wire up the config and you are off and running. The hardest part to master is determining when to run your code. A little trial-and-error, printing out the options object will help out there.

]]>
http://127.0.0.1:2368/adhoc-modules/24ff5c36-b6b0-499e-ac3b-6541509b5923Tue, 27 May 2014 22:13:06 GMT
<![CDATA[Using React with Backbone/Require.js/Bower/Mimosa, 1 line of config]]>This week I rolled out a React compiler for Mimosa. To show off how well the Mimosa and React play together, and how easy it is to get started, I put a demo Todo app together, because, lets face it, its not a thing unless there's a Todo app.

The demo Todo app is a Backbone project that uses React for views, Require.js for module loading and Bower for dependency management. That is all managed by Mimosa, the build tool, which also kicks in server support, live reload, JSX compiling, JSHinting, concatenation and minification.

Backing up, React

I was in attendance at JSConf 2013 when React was introduced. It was immediately ripped apart by the folks in the room. Twitter was red with the blood of a fresh new UI framework victim. The critiques can be boiled down to "Is that... XML embedded within JavaScript? OMG, die".

Since then, React has not gone away. It's gathered together over 5000 stargazers on GitHub and the buzz has increased.

So, why? Facebook threw up a blog post on "why react", and one of the key reasons is...

Speed, Baby, Speed

Rather than screw up an explanation, here's the important part from the "why react" blog post.

When your component is first initialized, the render method is called, generating a lightweight representation of your view. From that representation, a string of markup is produced, and injected into the document. When your data changes, the render method is called again. In order to perform updates as efficiently as possible, we diff the return value from the previous call to render with the new one, and generate a minimal set of changes to be applied to the DOM.

It's the diff that is the win. And at least until HTMLBars comes out, it seems to be the big speed winner.

And its just the View

Again, quoting React:

Lots of people use React as the V in MVC. Since React makes no assumptions about the rest of your technology stack, it's easy to try it out on a small feature in an existing project.

React blends nicely with your existing stack as the View, especially if your UI stack doesn't place a hard dependency on its View layer. Like, for instance, if you are using...

Backbone

Backbone needs no introduction, but unlike some of the other leading client-side frameworks, Backbone places no limitation on your templating language. Underscore, Dust, Handlebars, whatever.

What you lose is tight integration and data-binding for free (unless you are using, say, Ractive for your templating solution).

Backbone's loose coupling and React play together nicely. Instagram is, for instance, "a 'single page' web app built entirely with React and Backbone.Router."

The popular TodoMVC site has a great example of using Backbone and React together.

XML in your JS

One of the chief concerns with React is all the XML in your JavaScript. Facebook calls it JSX.

var HelloMessage = React.createClass({  
  render: function() {
    return <div>Hello {this.props.name}</div>;
  }
});

Yeah, so, maybe count me in the group of folks who is sort of put off by that. I just spent the better part of a decade hammering home to junior developers that markup in your JavaScript is bad. But its probably something I can get used to, probably.

Anyone looking at that might also realize that every JavaScript runtime they know of will not be happy with that.

So, as you probably would expect, that code needs to be compiled/transpiled.

Compiling JSX

In the Backbone/React Todo example a library loaded in the browser performs the compiling. But we all know that's not a good idea. It works great for demos, but it won't for your app.

Facebook created react-tools which can, among other things, be used to compile JSX on the server.

mimosa-react

I created the JSX/React compiler for Mimosa specifically to wrap react-tools and allow Mimosa devs to compile .jsx on the fly. As with all the other Mimosa compilers, when you are running mimosa watch Mimosa will recompile your .jsx and if you are using live-reload, refresh your page immediately.

Mimosa React Todo App

To show the compiler off, but also to show React working within a larger, more fully-featured Mimosa application I started with the TodoMVC example and made the MimosaReactBackboneTodo demo app.

Here's the config for the Todo app. No other config is needed.

  "modules": [
    "copy",
    "server",
    "jshint",
    "require",
    "minify-js",
    "minify-css",
    "minify-img",
    "live-reload",
    "bower",
    "react"
  ]

This gives you...

  • React compiling
  • jshinting of compiled JavaScript
  • concatenation via r.js
  • minification of JavaScript, CSS and images
  • bower support
  • require.js support like path verification
  • live-reload
  • hooks into the node server that comes with the project.

Give it a try!

  1. npm install -g mimosa
  2. git clone https://github.com/dbashford/MimosaReactBackboneTodoList react
  3. cd react
  4. mimosa watch --server or mimosa watch -s
  5. Open localhost:3000

Enjoy! Any questions, just ask!

]]>
http://127.0.0.1:2368/using-react-with-backbonerequire-jsbowermimosa-1-line-of-config/dcb6c398-4f70-4706-b28a-c173b2f0838fFri, 14 Mar 2014 16:15:54 GMT
<![CDATA[ember.js, es6 modules, and some unfortunate transpiler behavior]]>It's Ember's Fault

In January my team at Berico started doing a lot of work with Ember. We'll probably have a good dozen folks writing Ember apps in the near future. Ember has a steep learning curve, but the higher up that curve we get, the happier we are with the decision. There is just a tremendous amount of power there.

As recent Ember adopters, we've kept a close eye on the Ember community. Among other things that community has adopted is the es6 module syntax. Commits like this are frequent as the Ember codebase itself gets an es6 module overhaul. Not ones to buck a trend, at least not yet, we've adopted that syntax in our apps as well.

How to es6 module?

Lets cover a little ground on the es6 syntax.

This code exports some simple named values.

// file: hello_world.js
var hello = "hello";  
var world = "world";  
export { hello, world };  

And this code imports those same values.

import { hello, world } from "hello_world";  
console.log( hello, world );  // hello world  

You can also export values without naming them using the default keyword.

// file: hello_world.js
var hello = "world"  
export default hello;  

And then import it giving it whatever name you wish.

import abc from "hello_world";  
console.log( abc );  // world  

If you want to import a file that doesn't export anything, perhaps it just runs code that attaches to window, you would write import "foo".

Awesome, lets use that now!


Fail.

It'll be quite some time before all the browsers we have to support will natively support this syntax. Years.

And that's it.

I'll totally blog about it in 2017.

Thanks for coming!

Srsly?

Nahhh. This problem, like all in life, can be transpiled away.

es6-module-transpiler

Square's es6-module-transpiler was made to convert -- or transpile -- code using es6 module syntax into code you can actually use. The transpiler will take in your code and compile it into either AMD or CommonJS. Lets look at some of the above code transpiled to AMD.

These two blocks of code...

// file: hello_world.js
var hello = "hello";  
var world = "world";  
export { hello, world };  
import { hello, world } from "hello_world";  
console.log( hello, world );  // hello world  

...get transpiled into these:

define(  
  ["exports"],
  function(__exports__) {
    "use strict";
    // file: hello_world.js
    var hello = "hello";
    var world = "world";
    __exports__.hello = hello;
    __exports__.world = world;
  });
define(  
  ["hello_world"],
  function(__dependency1__) {
    "use strict";
    var hello = __dependency1__.hello;
    var world = __dependency1__.world;
    console.log( hello, world );  // hello world
  });

This should resemble the sort of AMD code you might write.

Perform this transformation on your es6 module code before you load it in the browser and your require.js/AMD application will work perfectly.

How can I use it?

All the build tools have plugins for the es6-module-transpiler. Grunt. Gulp. Brunch. Mimosa.

But... we have a problem

Starting with version 0.3.0 (its at 0.3.6 as of this writing) the es6-module-transpiler broke AMD apps.

import Ember from 'ember';  
var App = Ember.Application.create({});  
export default App;  

This simple bit of code gets transpiled into this:

1 define(  
2   ["ember","exports"],  
3   function(__dependency1__, __exports__) {  
4     "use strict";  
5     var Ember = __dependency1__["default"];  
6     var App = Ember.Application.create({});  
7     __exports__["default"] = App;  
8   });  

Line 5 above is the problem. Ember is set to __dependency1__["default"], which would work great if Ember had a default property, but it doesn't (or at least it hasn't). Almost every other vendor library will have this same problem.

The transpiler expects, by way of its output, that all other modules that have default exports will attach that export to the default property. In fact, you can see the transpiler doing this on line 7. __exports__["default"] = App attaches App to the default property of __exports__ such that files importing this file can access it via that property.

Will they fix it?

It's looking like they won't. Sad face.

Edit: So I failed to notice that the compatFix option was available and mentioned in that issue. I had built a amd-shim module for Mimosa not knowing the ability to fix the issue was there as a hidden option.

Saved!

Lets hope that option isn't removed as some in that thread suggested should happen.

Play with it!

Check out the es6-module-transpiler and Ember in brzpegasus' example Ember app.

]]>
http://127.0.0.1:2368/ember-es6-modules-transpiler-and-an-amd-shim/2f294eeb-b868-4aa5-af91-4cc0c4153da3Sat, 08 Mar 2014 04:43:52 GMT
<![CDATA[Mimosa 2.1.4, require.js support improvements, thx r.js + esprima]]>Mimosa v2.1.4 brings with it something I've procrastinaed on for awhile thinking it would be much harder than it was. v2.1.4 includes mimosa-require v2.0.0 which vastly improves how that module determines your JavaScript code's define and require dependencies/config.

How does it improve it?

Backstory

The functionality that is mimosa-require's require.js support was one of a few key reasons I built Mimosa in the first place (starting almost 2 years ago!). Brunch didn't support AMD/require. Grunt was young, hard to configure (still is) and...just no. And there really wasn't anything else.

I wanted something that would:

  • validate dependency paths
  • validate requirejs.config.paths
  • map paths, shim and shim dependency paths, etc
  • let me know a path is bad the second it is bad

This validation alone is a huge time saver. And it really comes in handy when reorganizing your codebase. Move folderX to folderY then work your way through all the pathing errors mimosa-require informs you of and you are set.

I also wanted something that could determine the "main" require.js files, build out a r.js config, run it and output the results. Ideally it would do this without a single line of config, just by being smart about how require.js works and by programmitically learning things about the code as it was processed.

But the way mimosa-require was determining your dependencies and requirejs config was, well, it was evil.

The Hack

mimosa-require used eval.

And I feel shame.

Rather than try and tackle any sort of complicated parsing or regex, I decided, maybe correctly at the time, that a better, quicker way to get the information mimosa-require needed was to eval your JavaScript code.

mimosa-require defined in-scope versions of define, require and requirejs, then evaled your JavaScript. The local version of, for instance, define would capture the dependency array and off it would go. It would even treat the callback function as a string and search for embedded require calls in the event you were using require.js' commonjs wrapper.

The fact that eval was there never caused problems in and of itself, but treating the code that way would.

Everything would work great if you all your code was wrapped in define and require, and it would work great if any code outside those function calls didn't attempt to access some scope that mimosa-require's server-side eval wouldn't know anything about.

But, if your code looked like this? Trouble.

var uA = window.navigator.userAgent;  
define(["a","b"], function(a, b) {  
  ...
});

mimosa-require would define a window, just to cover a lot of global variable cases, but window.navigator would not exist in-scope. So window.navigator.userAgent would throw an error and mimosa-require would be unable to do anything with this file.

Bummer.

It would be an even bigger bummer if this file was one of your "main" files. mimosa-require would now not know it was a main file and it would not build the combined file.

Use Esprima

I've had "require + esprima" on my ToDo list for a very long time, but I knew it would be a huge effort. So much to parse, so many edge cases. Ugh.

Then an issue was logged against mimosa-require that had this problem at its root and I finally decided to look into it.

While I love writing esprima AST parsing code -- for reals, its legit awesome to write -- I was not going to love writing this.

r.js to the Rescue

I remember shortly after I released Mimosa and mimosa-require that James Burke the creator of require.js switched how require.js itself parses code to use Esprima. Certainly the tool mimosa-require is trying to help you use -- and that has to do all the things that mimosa-require does, just not interactively -- can provide some guidance.

An API for this maybe? No such luck. And why would there be.

But there is a parse.js sitting in the r.js repo. And it does have a parse function. And it does have a findConfig function.

Well, that's awesome.

It's not exposed, and it doesn't quite do what I need it to, but some copy paste, some minor hacking and day after I started I had ripped out the eval BS and replaced it with r.js' legit esprima parsing.

Ugh

Seriously. That's all it took. Copy, paste, 75 lines of code changed/removed. I let the evil fester for an exceptionally long time because I knew it would be 1000+ lines of code to do it properly and I had a lot of other higher priorities. For whatever reason it didn't occur to me that those 1000+ lines of code already existed.

Win

So now there are far fewer caveats to the require.js support. mimosa-require won't run your code and it won't trip over anything. It's using the same parsing mechanism r.js uses, so all should be right.

So try it out.

]]>
http://127.0.0.1:2368/mimosa-2-1-4-require-js-support-improvements-thx-r-js-esprima/e7e487d0-0546-432b-a91f-4e126a5af71aThu, 20 Feb 2014 15:25:03 GMT
<![CDATA[Making a Mimosa Module]]>While the site has a lot of documentation on how modules are built with a small walk-through, I wanted to dedicate some serious attention to how easy it is to build something and get it linked into your workflow.

Example Module

A great way to learn how a module is built is to look at a real simple existing module. We'll look at the handlebars-on-window module. The goal of that module is detect a handlebars.js file as it flows through Mimosa's build steps and transform the text of the file to make the Handlebars object visible on the window. If you are wondering why such a module would exist, you can check the README.

File Structure

This is the file structure for the handlebars-on-window module.

/src
  config.js
  index.js
.gitignore
.npmignore
README.md  
mimosa-config.coffee  
package.json  

Non-Mimosa Files

Lets knock out the simple stuff first. These files are more about Git, NPM and node and not about Mimosa, but they are a common part of any Mimosa module.

mimosa-config.coffee

If you are interested in building a module, you are likely using Mimosa. This file configures Mimosa. But, don't let the presence of this file confuse you, the mimosa-config file has nothing to do with the Mimosa module. A Mimosa module does not need a mimosa-config to be a module.

When I built this module I wanted to make sure I ran JSHint over the project's source code to make sure the JavaScript code is idiomatic and to catch simple syntax bugs quickly. It just so happens Mimosa can do that, so I use Mimosa to run JSHint.

README.md

README.md contains the module's documentation. How to install it, how to configure it and what its purpose is. More documentation the better! Many of the Mimosa modules have a common pattern for documentation if you care to follow it.

The handlebars-on-window has documentation that covers usage, functionality and configuration.

.gitignore

This indicates what local files you do not want to push to your git repository. Because Mimosa modules are node projects, using .gitignore to make sure you do not push the node_modules directory is common.

.npmignore

NPM is where you will deploy your module when you are done with it and it is how other people will get your module. As with .gitignore and git, .npmignore determines what files are not sent to NPM when you publish your module. The files that get published to NPM are the ones that get delivered when someone uses your module.

The mimosa-config is a good example of something to add to the .npmignore. It is only there to run JSHint during development. It isn't useful for anything else.

package.json

The package.json configures node projects. If your module needs any other node modules (like wrench for directory manipulation or request for some HTTP goodness), you would declare those as dependencies in your package.json. This file is also where you declare the name of your module, in this case mimosa-handlebars-on-window.

Nodejitsu has a great guide on the package.json.

Module Code

While some of the previous files are necessary, they don't really have anything to do with Mimosa. The files inside src are where the module's code exists.

The first thing to identify is where the module's main code is. When Mimosa uses the module, what does it use?

The package.json has a property in it named main.

"main": "./src"  

This points anything using this module to module's main entry point. In this case it is pointed at the directory ./src. By default, when a directory is the name rather than a file it means that the file to use is index.js inside that directory.

And that is where we'll start.

src/index.js

Because the index.js is the main for this NPM module, that means it is responsible for defining the interface Mimosa will use. At the bottom of the index.js file is a module.exports.

module.exports = {  
  registration: registration,
  defaults: config.defaults,
  placeholder: config.placeholder,
  validate: config.validate
};

Each property in this object is a reference to a function. These four functions are the functions that Mimosa will use in order to access the module's functionality.

Not only is module.exports the interface for this module, is also contains the interface Mimosa expects from its modules. For every module plugged into Mimosa, Mimosa will look to execute these specific functions and various times during a build or during mimosa new.

The defaults, placeholder and validate functions are all inside the config.js file that is required (imported) into index.js. We'll cover those after we touch on the most important of the interface functions.

registration

The registration function is how a Mimosa module hooks itself into a Mimosa build. It is the most important of all the functions, and it is only one line of code!

var registration = function (mc, register) {  
  register( 
    ['add','update','buildFile'],
    'afterCompile', 
    _attach, 
    mc.extensions.javascript );
};

Before digging into this code, lets refresh what this module does. It's purpose is to add the text "window.Handlebars" to the handlebars.js file. That's all. That means this module needs to process JavaScript files, capture the handlebars.js and update the text that is going to be written.

This line of code registers files with JavaScript extensions (mc.extensions.javascript) to be processed by the _attach function (which is higher up in the code) after compilation has been executed (afterCompile) whenever a file is added, updated or built (buildFile).

Lets break that down.

Callback

_attach is the callback for this registration. This is where the module's code lives. It is this code that will look for handlebars.js and update the text.

Extensions

mc.extensions.javascript is a reference to an array of JavaScript extensions being processed by the application. By registering this array of extensions, it ensures the _attach callback gets called only when a JavaScript file is being processed. This would include CoffeeScript files as well as JavaScript files. But it would ensure that, for instance, CSS files or images being processed by Mimosa would not trigger the _attach callback.

mc is the fully evaluated and amplified mimosa-confg and it is passed to the registration function. It includes all the configuration for all the modules, but it also includes information like the extensions object.

But when does the processing of JavaScript files in the _attach function occur?

Workflows

A Mimosa workflow is a set of steps that get executed during a Mimosa command.

The buildFile workflow runs during mimosa build and when mimosa watch first starts. When it first starts up, mimosa watch builds all the assets, but it keeps watching. add and update are executed during mimosa watch after initial startup when a file is added or updated. In all of these scenarios -- when building, adding or updating files -- we want the module to be checking the JavaScript files being processed to see if any of the files are handlebars.js.

Workflow Steps

When a file is processed through a workflow it goes through several workflow "steps". Steps include read when the file is read, compile when the file's input text is transformed into the desired output text, and write when it is written. This module wants to process files during the afterCompile step. This ensures that the module is working with JavaScript. If this module ran beforeCompile, then the file's output text may not have been determined and it is the output text we want to tweak.

When the callback gets called

When _attach gets called by Mimosa at the configured time, it gets passed some information.

var _attach = function ( mimosaConfig, options, next ){ ... }  
mimosaConfig

The first parameter is again the full mimosa-config with all of the application's configuration and plenty of other goodies. What we care about is that the mimosaConfig contains the configuration for this module: mimosaConfig.handlebarsOnWindows.

options

The options object has information about the file being processed. It has a files array, options.files, that contains any files being processed. Each entry in the files array has an inputFileText and an outputFileText. As mentioned above, this module is concerned with transforming the outputFileText.

next

next is Mimosa's lifecycle callback. When the module has finished doing whatever it needs to do, it must call this callback or else Mimosa will stop processing this file.

Read the code!

Armed with the information above, you should be able to read the 19 lines of code that comprise the _attach callback and understand what is happening. The key part is this one line...

file.outputFileText = file.outputFileText.replace(  
  mimosaConfig.handlebarsOnWindow.replace,
  "window.Handlebars = " +     mimosaConfig.handlebarsOnWindow.replace );

This line rewrites the outputFileText with window.Handlebars inside of it.

Regarding mimosaConfig and options

These two objects have lots of useful stuff in them. Just for curiosity's sake, you may want to console.log these objects just to see what is inside them.

src/config.js

The functions in this file are really straight forward. They are also all optional. If your module has no configuration, it wouldn't need this file at all.

Remember the index.js looks into the config.js file to expose some of its functions.

module.exports = {  
  registration: registration,
  defaults: config.defaults,
  placeholder: config.placeholder,
  validate: config.validate
};

defaults

This function returns the module's default configuration. Pretty simple!

exports.defaults = function() {  
  return {
    handlebarsOnWindow: {
      libName: 'handlebars.js',
      replace: "__exports__ = Handlebars"
    }
  };
};

placeholder

This function returns a string snippet that explains the default config that is placed in the mimosa-config-documented.coffee file during mimosa new and mimosa config. The string it returns is commented CoffeeScript.

exports.placeholder = function() {  
  return "\t\n\n"+
         " # handlebarsOnWindow:\n" +
         "   # libName: 'handlebars.js' # file name of handlebars library\n" +
         "   # replace: '__exports__ = Handlebars' # code to prepend 'window.Handlebars = ' to\n";
};

validate

This function is called by Mimosa to give the module a chance to validate its own config.

exports.validate = function(config, validators) {  
  var errors = [];

  if ( validators.ifExistsIsObject( errors, "handlebarsOnWindow config", config.handlebarsOnWindow ) ) {
    validators.ifExistsIsString( errors, "handlebarsOnWindow.libName", config.handlebarsOnWindow.libName );
    validators.ifExistsIsString( errors, "handlebarsOnWindow.replace", config.handlebarsOnWindow.replace );
  }

  return errors;
};

If this function returns an array of strings (error messages), Mimosa will error out after printing the errors. So, if, for instance, the libName property wasn't a string, the validate function would return something like:

["handlebarsOnWindow.libName must be a string"]

The validators parameter passed in contains a set of helpful validation methods like ifExistsIsString. The full set can be found in the Mimosa source.

So you wrote a module, now what?

Testing Locally

Run mimosa mod:install from the root of your module's directory and your Mimosa will install your module inside itself. Now you can use your module on local projects.

Put it in NPM

As long as your package.json is in working order, npm publish your module! And then tell the world about it (and let me know via @mimosajs).

]]>
http://127.0.0.1:2368/making-a-mimosa-module/9052d185-8ee6-48dc-96c0-780d4e7c24a2Thu, 30 Jan 2014 04:07:02 GMT
<![CDATA[Mimosa 2.0 Released, 2.1 Queued Up]]>This week Mimosa 2.0 was released. I'm exited to get this release out as it makes Mimosa leaner, meaner, easier to reason about for its users and its maintainer, and a ton easier to maintain long-term.

Compiler Refactor

The biggest change with this major release is the extraction of all of Mimosa's compilers out of Mimosa's core and into separate Mimosa modules. The only drawback of this change is that you now have to list your compilers in mimosa-config's modules array. A little less magic isn't a bad thing.

But the advantages are many.

  1. It is now super easy to many compilers of your own. Before, a new compiler would have required a pull request to Mimosa. If you want to, for instance, create an EmberScript compiler well, that just got easier. And there are bunches of existing compiler modules to use as examples.

  2. Mimosa now takes a lot less time to download. I heard more than a few times that npm installing Mimosa felt a bit like you were downloading all of NPM. Yanking out the compilers reduced install time by 60-70%. As more compilers get developed Mimosa's dependency bloat would have only worsened.

  3. Maintaining and impoving compilers can now happen apart from Mimosa itself. If a single compiler gets upgraded, it won't require a new version of Mimosa to be released.

  4. Mimosa core is smaller. The smaller and more modular it gets the less time I spend working on Mimosa's core and the more time I spend building out the modules my team and those others using Mimosa need.

Some of the old config, like compilers and templates.handlebars has been moved to their logical locations. Each compiler manages its own extensions and overrides for the compiler library if specific versions are needed.

After having updated a dozen or so projects to 2.0 I can say that these changes generally mean less config and a config that makes more sense.

There were plenty of other tweaks and fixes. For a comprehensive list of all that went into 2.0, check out the Release Notes.

2.1

Work on 2.1 will start shortly and it'll be heavily logging focused. After not getting much love or attention since the beginning, there has been a lot of feedback that logging needs to get better and more flexible, and it will.

Feedback

I love hearing what people are doing with Mimosa and helping folks through any trouble they may have. Shoot me a note @mimosajs, or hit the Google Groups or just make a GitHub issue to discuss what is on your mind.

]]>
http://127.0.0.1:2368/mimosa-2-0-released-2-1-queued-up/785347e6-64ea-4282-bb87-dd970ae363d9Mon, 27 Jan 2014 03:02:49 GMT
<![CDATA[I can see my blog from here!]]>Always wanted to start up a dev blog and get what I'm up to down in writing. But anytime I've thought to set one up I've instead decided to hack on code. No matter the reward that might come from blogging, it'll never be as rad as hacking code.

Hoping this will be a means to organize my thoughts, and that it will be encouragement to learn new things with enough rigor to be able to get blog entries out about them.

Being that I'm new to this, we'll see how much I struggle with the software. After tinkering with Jekyll a bit, I landed on Ghost. One thing I didn't want this to be was a pain in the ass to manage. Setting this all up and getting it hosted on GitHub was a piece of cake. Should you be interested, check out Ghost and then check out this killer pip package called Buster.

I'm the author of Mimosa and textract so you can probably expect I'll blog heavily about things related to those tools.

So, welcome, hope you stay awhile!

]]>
http://127.0.0.1:2368/i-can-see-my-blog-from-here/df8c0693-a8a5-413d-9dcd-cea1564c11fbSat, 25 Jan 2014 18:58:48 GMT