My first job out of college was riding shotgun delivering building supplies. Today I have the honor of working for one of the most renowned enterprise-level retail websites in the US as an Engineer, and it all happened without ever taking a computer science class.
“Can you come home and help us ride this thing out?” I don’t remember my dad’s exact words, but I do remember a month before I was going to graduate that he asked me if I could come back and help out the family business.
It was the tail-end of 2008 and the economy, as I’m sure you remember, was taking a nose dive into the tanker, with new home starts being the first indicator to take a big hit. This was not a good thing for a business who’s sole source of income and sales were building materials.
So, with a degree in environmental science in tow, I made the trip back to work with my dad and help out where ever I could: riding shotgun delivering building materials with some of the brightest and nicest guys I’ve ever known, filling in for dispatch when the guy who did dispatch had to help pull orders and cleaning toilets. It was hard work.
Within a few months my dad asked me if I could rebuild our website. I hadn’t touched a code editor since I was 16 (in 9 years), but that didn’t stop me from giving it my best shot. I bought books on HTML & CSS, and rebuilt an informational brochure site with 5 to 6 pages, outlining what we did. I was proud of myself. It catalyzed a feeling I would never forget: I just took a blank directory on a computer and created something out of nothing.
From this single experience, I decided to buy more books, learn more about programming, understand design principles. Not just aesthetic design, but programming patterns & program arhcitecture. I upgraded our little website to a robust WordPress CMS. I did it almost all in my own time outside of work or during the trips when I rode shotgun. I had no formal education.
3 years into my coding journey, my family business stabilized. We found, that through building a better website, more people found us, which led to more inquiries, which led to an increase in sales radius of 20 miles to a coast-to-coast expansion, which led to drop shipping to customers in Arizona, New Jersey and other states. We took our web traffic from 10 visits a day to a peak of 400 visits a day. Learning to code potentially helped save our family business.
Today, through an amazing journey, I have the opportunity to touch code that millions of people see, that contributes to billions in yearly sales and gives customers all across the United States that feeling of “Zappos is a lovely shopping experience, I want to do it again!”
I want to reiterate this point: I have no formal education in programming. This isn’t to toot my own horn, because along the way I had the chance to learn from some of the brightest people in the field of Software Engineering both online and in person. I’ve been “lucky” to have had the experiences I’ve had, but it all started with me taking initiative. I wish I had a resource like hour of code to catalyze my passion at an earlier age.
This is the reason I believe everyone in the world with access to a computer should do hour of code.
With a computer, you are empowered to potentially fill one of the 1.4 million jobs in the United States that goes unfilled because there just aren’t enough people in the world to fill these rolls if you just do something.
So how would I suggest you get started? Learn something.
Visit the hour of code website and check out one of it’s resources.
tldr; Everyone with access to a computer should do hour of code, so start your journey!
Three that I recommed:
Thinkersmith’s Unplugged Hour of Code Activity: This one is about learning to solve problems without actually typing a line of code. This is singly the most important aspect of learning to code: Learning to solve problems.
So get out there, learn to code. If you don’t have a computer, go to the library and try out one of these resources. They don’t require an editor, or any special software on the computer. They’ve removed any barrier to entry for you to have the power to rewrite your future. So get out there,
console.log('Rewrite your future.');
A sidenote: If you have kids, at the very least, encourage them to do hour of code. There’s no better opportunity for them than to learn, for free, with great resources, how to write code.
A quick note: All of these tasks leverage minimatch, a ‘minimal matching’ utility that I highly recommend reading up on if you haven’t already: minimatch on Github
I rarely, if ever, create a Grunt file without including watch. Being able to run
grunt watch and know that I don’t need to run my tasks over and over again allows me to shave of huge amounts of time having to context switch between the terminal and my editor.
For my cookie manager utility, this is what my watch task looks like:
Watch is pretty straight forward:
Your watch task can get pretty complex with options, but I keep mine basic by just enabling livereload (which will refresh my browser automatically).
Like watch, the jshint task can be pretty simple, just pass it a minimatch array of files you want it to check and you’re on your way. One extra option that I didn’t show in the example above is the
afterconcat options. This allows you to run jshint on your source files before and your concatenated files after.
Unit testing (or any formal testing for that matter), seems to me to be the most under-utilized tool most front-end developers have. As developers, we could save a lot of time simply by leveraging unit tests to make sure we don’t break or regress code we’ve already written. Thankfully, there are a lot of great testing frameworks out there, and Mocha is the one that I like to use, because it allows you to run client-side unit tests in a headless browser.
I like to tie all of these tasks together with the Notify task. Notify will use whatever system notification application you use (Growl, notify-send, Snarl or OSX Notification Center) to alert you when something is complete or fails.
When something fails, grunt-notify will alert you with a notification that looks like this:
The options here are totally optional, but I like to keep my js hint notifications to around 5 and I like to see what project the notification is for. If you do this, you’ll have to register a new task for watch and notify to run together (as far as I know), that should look like this:
With Uglify, you pass in a files object with the file you want to write to as the key and an array of all the files you want to write with as the value.
I also like to add a banner with the package name, the package version, where the package lives and a timestamp.
Not all workflows are created equal, and it’s likely that there are far superior workflows to this one out there. This is an example of me learning by doing and finding what works for me.
What are you doing to be more productive in creating your development projects? Do you have anything you’d add to make this one better?
Grunt is a NodeJS task runner that allows you to automate all the things! I use it to speed up my development workflow and enhancing the performance of my projects.
It’s Thursday. I’ve just started a front-end project that needs to be done…tomorrow. I’ve started a new WordPress site for a client that we needed to churn out quickly, so I open up Coda, start to manually scaffold out a theme, manually create my php and html files, manually start to add CSS, then I flip over to my browser, hit the refresh button and watch the page reload.
Fast forward to the next day, and I’m cleaning up code, trying to make files smaller (and doing an awful job) and I finally wrap it up, and manually drag files into ftp in Coda, then manually sanity the site and call it a day.
As I’m writing this post, I’ve got Chrome open in the background and SublimeText 3 open taking half of the screen. I save my file and watch chrome magically update to my most recent markdown file’s changes.
This is just one advantage of Grunt.
Grunt has become one of those things in life where you didn’t realize just how badly you needed it until you start using it and thinking, “what have I been doing with my life?”
By automating all the things I used to have to manually do, I make more time to do more things, and ultimately make more time to focus on the important things while Grunt takes care of the trivially mundane.
It has a huge library of plugins to automate almost anything you can think of, the community on a whole is using Grunt for all of their projects (jQuery, twitter, Modernizr) which leads to contributing, which leads to more plugins, which, as you guessed, leads to greater adoption.
Easy to get up and running and lots of documentation.
Robust enough that you can use it for any kind of tasks, but minimal enough that it’s not bloated unless you need it to be.
I’ve added all of these code samples to a github gist, you can clone done the repo, and run the commands as you read rather than having to write out the examples yourself if it’s more convenient.
Project gist: Grunt: Up & Running
Grunt has a few dependencies that you’ll need to have installed:
From anywhere within your terminal run:
This is going to install the module for the command line tool globally (-g) so you can run
grunt anywhere on your machine and it will know what you’re referencing.
Next, in your project’s root, you’ll need to create a
npm init in your project) and a
Gruntfile.js. The package.json file is a NodeJS file that tells Node about all the attributes of your project and the different Node modules your project will depend on.
Here’s my sample
After you’ve created your
package.json, you’ll need to run
npm install, which is going to install grunt, jshint and uglify (any dependencies you specify in your
The final piece of the Grunt puzzle is to create your
In it we’re going to have it run two tasks:
We’ll create a default task and add the options to the
script.js, the path being relative to the Gruntfile’s location.
At the very least for running
grunt to work, you have to:
registerTaskof default and add the tasks you want to run
loadNpmTasksof all the tasks that are in your configuration object.
The only thing we need to do for this to work is to add a
Now that we have everything setup, , and you can switch back to your terminal and run
grunt from anywhere in your project (I always run it from the project root just to be safe), and grunt will run jshint and uglify on your script with the package name!
Having to run
grunt every time you make a change can be a real hassle, so for convenience to almost every project I use, I add the
grunt-contrib-watch task, so let’s go ahead and add it as a task:
When you do this as
--save-dev it will add it to your developer dependencies in your
package.json file, which will help you out in the long run, especially if you want other people to use your project. If you don’t pass in the flag to save as a dependency, when someone else pulls down your project and tries to work with it, they’ll have to manually install node modules and most likely give up on your project.
package.json after saving dev dependency for watch:
Now that we have the ability to watch files, we can add it to our
With an updated file, we can simply run
If you’re using Grunt, let me know what you like/don’t like about it, or some of the really useful plugins you’ve found! I’ll be adding posts every month about the plugins that I find useful for my workflow.
Bower has made it incredibly easy to install frontend packages (such as jQuery, Underscore, Backbone, Angular, the list goes on) and manage updates without the hassle of manually copying and pasting files into your projects or adding git submodules.
To get started using bower and grunt, you’ll need to have Node and npm already installed. Once you have them installed, from your command line, run
npm install -g bower, and let npm take care of pulling it in and setting it up for you. The -g flag is making bower available globally, so you don’t have to install it every time.
For convenience, I’ve added a working gist that can be cloned to your local box and run: Gist: Using Grunt and Bower for Frontend Package Management.
The first thing you’ll want to do is run
bower init which will generate your
bower.json file and add the name, version, authors, license and ignore properties. This is also where all of your package definitions will be so when you pull this project down on a different computer or work with someone else, they can install all of the packages with one command.
Now that Bower is installed and initialized, let’s setup our project’s bower configuration. I don’t like the name
bower_components for the directory we’re going to store it in, so create a file called
.bowerrc in the root of your project’s path, and add the following options:
We’re overwriting the default directory of
bower_components and defining the name of the package manifest.
In the project example, we’d like to use a few frontend packages:
If we want to find a package, for example font-awesome, but we don’t know the name, we can run
bower search font-awesome, which will return a list of results. Looks like the package we want is called ‘font-awesome’, so the next thing we can do is run
bower install font-awesome --save. This command will pull down the font-awesome package into
src/_lib and make it ready for us to use. If you take a peek into your
bower.json file, you’ll see that the command also added font-awesome to your json file, so that it is now available for anyone else who uses your project to pull all the dependencies in with
bower install underscore --save, for each dependency until you’ve installed them all.
I am a huge proponent of using Grunt as a build tool, especially for frontend, so it only makes sense that we’d use it here!
One of the “downsides” of package management with Bower is that it pulls in a lot of extra cruft, all the tests, configuration files, README.md files, anything that’s in version control, and when we’re developing, we don’t need all of it, so we can use Grunt to build only the files we need into our target directory.
Once you’ve gone through the steps to add uglify & copy grunt-contrib plugins, add options to your Gruntfile.js grunt config:
This Gruntfile will only be running a few tasks, but they’re really convenient from a frontend development workflow:
When you run
grunt, your dependencies will be put where they need to go and minified, so when you build, you can rest easy you don’t have to manually add packages, and as you upgrade your dependencies, grunt will still continue to upgrade your target version of them whenever you run it.
.gitignore, I add the following directories:
src/_lib (or whatever your bower directories name is). There’s a lot of debate about whether or not to version control your dependencies, and I tend to fall on the side of not doing it. For me, I don’t have a good reason to version control something that’s already version controlled, so it keeps my projects a little lighter.
If you decide to start using Grunt and Bower, let me know, and show me how you did it! Seeing something you think isn’t so great in my workflow? I’d be interested to hear other’s opinions on good practices.
Otherwise known as, better etiquite for answering questions on stackoverflow.com and conversation in general.
All sass (and not the compilable kind) aside, I’d like to share what I think makes a good developer a great developer: humility.
I used to work with this guy, Geoff Berger. He is one of the smartest guys I know. And not the “I’m a few steps ahead of you” types, but the kind that you think may have been composing music and writing theories of physics when he was waddling around in diapers kind of guys.
The thing is: He’d never admit it to you. He is the most humble person I’ve ever met.
If someone went to him with a question, he’d sit down and somehow in his gentlest way start by asking if you’re familiar with some concept about your question, and in a way that made you feel on equal footing with him, not in a belittling way. Then he’d step through and explain how everything was working together, all the time doing it with passion and excitement.
Whenever anyone described Geoff the two words that always surfaced were humble and smartest. He was always the smartest guy in the room, and he was always humble about it.
These qualities seem like no brainers, but they’re the ones that make for great developers:
Remember other people, just like you, are human. If you went to a medical specialist about a health problem, and you weren’t an expert, you would want them to treat you like a human, not like some moron off the street who didn’t know what squamous cells were and how your late night red bull runs and hackathons are creating them. You’d want them to be kind, and treat you with the respect that you deserve, because you’re a human being.
Answer the question, and just the question. A lot of times, developers, because we’re opinionated, like to shove said opinions into a conversation that has nothing to do with it. Keep it as short as it needs to be to answer the question fully. Note: Brief can be gentle. They’re not mutually exclusive.
Be excited about it! Don’t be excited about the fact that someone is listening to you. People will respect (and most likely catch) your excitement for the topic you’ve got answer to, but don’t just talk to have words come out of your mouth.
Be humble. I can’t stress this one enough. I’m not the best at anything. I’m not even close to the best. But I might have answers. Any person’s willingness to admit: “I’m not perfect, I’m not always right, and I do make mistakes.” is a great springboard for being heard. At the end of the day what I think the answer might be is just one possible solution, and most likely not even the best one for the requirements. I’m not just okay with that, I’m excited that I get to learn how other people solve problems and grow from it.
At the end of the day, we all go home to something, we’ve all had experiences, we all have baggage. We also all start from somewhere right? I am not the developer I was last year and I’m not the developer I will hopefully be next year. So I want to try, like Geoff did, to treat people that way. To find where they are and work from there. Not treat them as inferiors because they’re not where I am.
The technology field is hot, and it’s a great time to be a developer from a “doing great work” standpoint, but it doesn’t release us from the responsibilities of remembering that our peers are human beings. They exist after the experiences they have with us, and those experiences shape their journey as much as it shapes ours.
P.S. If you read this entire post and at this point felt like you were being belittled, take that feeling and tuck it away for next time you’re on my side of the discussion.