Lightning Components and Browserify
Lightning Components
Over the last week, I’ve been working with the Salesforce Lightning Component Framework. It’s a simple way to build single page apps using client side JS and server side Apex. I am in no way a true Salesforce developer - I’m really just a noob - but it’s super fun to learn and for any one with a MVC background, you can pick it up quickly.
This is not, however, an overview of how to get started on Lightning - there are other, more qualified tutorials out there like Reid Carlberg’s Newbie Notes or Christoph Coenraets Lightning Components Tutorial. If you are looking for a solid front-to-back overview - start with one of these.
Challenge Accepted
One of the difficulties I have run into during my learning process, is that including a library like jQuery, isn’t as simple as adding a file and calling it in the application. Salesforce uses “static resources” for things like css files, and javascript files.
When you want to use those in a Lightning component, you simply call it like so:
<aura:application >
<link href='/resource/bootstrap/' rel="stylesheet"/>
</aura:application>
This calls the static resource that is the css file for Bootstrap SF1 theme.
Based on this, simply adding a jQuery static resource should be a piece of cake.
<aura:application >
<script src="/resource/jQuery/"></script>
<link href='/resource/bootstrap/' rel="stylesheet"/>
</aura:application>
One would expect this to load jQuery, which, essentially it does, however it’s a bit of a race case. The script loads a few milliseconds after the application, and you can’t actually use it. There is a great thread covering this behavior, and I won’t go into much detail here, but the solution is to use RequireJS in a component, and an event to listen for everything to be loaded, and then load the RequireJS config and all of the static resources.
This, to me, was a challenge.
The Dark Magic of Browserify
I have been toying with Browserify for a bit now, and ditched RequireJS some time ago. I was never a fan of the AMD syntax, and I love being able to pull all of my JS together into one file with one command. So I was curious, if it would be at all possible to pull off some magic and load everything with one file.
In my developer console, I created a New->Static Resource, and named it AppScripts
. It creates a new js file with a sample function in it. I’ll use this again in a bit, but went ahead and set it up in the application.
<aura:application >
<script src="/resource/AppScripts/"></script>
<link href='/resource/bootstrap/' rel="stylesheet"/>
</aura:application>
Now I turned my attention to my local machine. I’m not going to go over all the ins and outs of Browserify, but I will walk you through what I did to set it up.
First, you have to get set up a bit, and install a couple things. You will be using NPM to manage your packages, so go through a quick npm init
process first. Once that’s complete, open up your package.json
and update your scripts
section.
"scripts": {
"bundle": "browserify main.js -o scripts.js"
}
This will allow you to use npm run bundle
from the command line, and will output a scripts.js
file.
First, however, you have to install the required modules -
npm i --save-dev browserify jQuery
This will install the requirements for this simple test. After that completes, I created a main.js
file. Remember the script in npm? It’s looking for main.js - you can change the script to be any name - just make sure they match.
In my main.js file - I did just a quick script to see if it was working -
var $ = jQuery = require('jquery');
$(function(){
console.log('This is working.');
});
When npm run bundle
gets called on the command line - it will take this file, and it’s recursive dependencies, and output them to scripts.js
. You can then minify this file to save space, but for now I’m skipping that. At this point, I opened my scripts.js
file, copied the entire file, and pasted into my static resource AppScripts
, and saved it.
I previewed the application in the browser, and my console log showed the text appropriately. I have tried a few other simple tests, and so far, everything appears to load properly and execute.
So What’s Next
Now I’m going to go nuts. So many things I want to try out and see if they will work. It’s not that the current framework is limiting, but it’s a restriction not having some go-to libraries. I don’t want to reinvent modules that exist, so any way I can get this to work, I’m going to make it happen.
Some ideas to try - bootstrap js components, data grids, knockout, handlebars, and so on. What I have yet to determine is what is available to me at run time. Some of the controller js will need to be tested - can I use my Browserify bundle to run controller code? No clue - this may not even work at all - I was just excited to get this to work - I had to share.