Devin ClarkJS, Web, and Software Ramblings2020-10-20T00:00:00-00:00https://devin-clark.com/Devin Clarkdclarkdesign@gmail.comCSS Validation2011-12-01T15:08:03-00:00https://devin-clark.com/blog/css-validation/<p>means nothing. Valid CSS does not guarantee a good user experience, the layout is correct, or the site even functions at all. This <a href="http://sonspring.com/journal/css-validator-nonsense">nonsense</a> must end. Jeffrey Way's article <em><a href="http://net.tutsplus.com/articles/general/but-it-doesnt-validate/">But It Doesn't Validate</a></em> is another rant on the topic. I would definitely recommend you read it.</p>
<!--more-->
<blockquote>never, ever, ever compromise the use of the latest doctype, CSS3 techniques and selectors for the sake of validation <cite>Jeffrey Way, <em>But It Doesn't Validate</em></cite></blockquote>
The argument of using the validation to check for syntax errors (typos, missing semicolons, etc) is moot because I work with <a href="http://sass-lang.com/">SASS</a> and it will not compile into CSS if there is a syntax error. Also, it gives you a nice little message telling you the problem.
<p>This is ultimately up to you. If you want to be stuck in the past ignoring new technology completely, have at it but don't force it on others.</p>
Alternative Syntax in PHP, FTW!2012-01-08T21:33:52-00:00https://devin-clark.com/blog/alternative-syntax-in-php-ftw/<div class="alert-message info">
<p>This is a guest post by my co-worker and friend, the wonderful <a href="http://ensellitis.com/">Chris Ensell</a>. Chris is a Freelance Web Developer and is my go-to guy for any PHP questions I have (and I have a lot).</p>
</div>
<p>For newer coders, browsing through code can be daunting. There can be a LOT of brackets to go through, and it gets easy to get lost. Especially if you aren't the one who wrote it. Sometimes, even experts can have problems, especially when troubleshooting.</p>
<p>There is one way of writing code that will help you, and others who may use your code after you. Alternative syntax, and since I have started using it, I have fallen in love.</p>
<p>Let's start with a little code.</p>
<pre><code class="php">function getTags( $text ) {
$posttags = get_the_tags();
if ( $posttags ) {
foreach( $posttags as $tag ) {
$theTag = $tag->slug;
if ( !$theTag == "foobar" ) {
$url = get_bloginfo('url');
foreach ( $starts as $start ) {
$text = str_replace($start.$theTag, '<
a href="'.$url.'/?tag='.$theTag.'">' . $theTag . '', $text);
}
} else {
$text = str_replace($start.$theTag, '<strong>'.$theTag.'</strong>', $text);
}
}
}
return $text;
}</code></pre>
<p>This is a part of one of my plugins I am working on that searches posts for the names of tags you're blog uses and links them to the proper archive page. Granted, I padded the code up a bit with some useless stuff and reverted it back to the old school syntax.</p>
<p>So, what can we do to make this more readable, especially to newer coders? Alternative syntax is a perfect starting point. So, let me show you a few examples of that...</p>
<p>This is a basic else/if statement, using the old classic syntax.</p>
<pre><code class="php">if ( $foo ) {
$bar = false;
} elseif ( $bar ) {
$foo = false;
} else {
$foobar = "howdy!";
}</code></pre>
<p>First alternative syntax I'll show you can only be used if you are using it to define a variable, or something that only needs one line.</p>
<pre><code class="php">if ( $foo )
$bar = false;
elseif ( $bar )
$foo = false;
else
$foobar = "howdy!";</code></pre>
<p>As you can see, the brackets are completely gone now. This is great if its a simple elseif. You can also put it all on one line for easier organization:</p>
<pre><code class="php">if ( $foo )
$bar = false;
elseif ( $bar )
$foo = false;
else $foobar = "howdy!";</code></pre>
<p>As you can see, it makes things easier to navigate.</p>
<p>Now, if you have multiple lines, you are going to want to use this method:</p>
<pre><code class="php">if ( $foo ) :
$bar = false;
elseif ( $bar ) :
$foo = false;
else :
$foobar = "howdy!";
endif;</code></pre>
<p>What we did here is pretty much replace the brackets with colons and at the end replaced the final bracket with an endif.</p>
<p>So, let's put it to use on that original example I posted at the beginning.</p>
<pre><code class="php">function getTags( $text ) {
$posttags = get_the_tags();
if ( $posttags ) :
foreach( $posttags as $tag ) :
$theTag = $tag->slug;
if ( !$theTag == "foobar" ) :
$url = get_bloginfo('url');
foreach ( $starts as $start )
$text = str_replace($start.$theTag, '<a href="'.$url.'/?tag='.$theTag.'">' . $theTag . '', $text);
else :
$text = str_replace($start.$theTag, '<strong>'.$theTag.'</strong>', $text);
endif;
endforeach;
endif;
return $text;
}</code></pre>
<p>See! Isn't that cleaner looking? You will also find it easier to find where one statement ends more easily. This is an excellent way to code. You will find that WordPress uses this a lot in their themes as well, and for good reason.</p>
<p>This doesn't only apply to <code>elseif</code>. It also works with <code>while</code>, <code>for</code>, <code>foreach</code>, and <code>switch</code>.</p>
<p>You can find more information in the <a href="http://php.net/manual/en/control-structures.alternative-syntax.php">PHP manual</a>.</p>
The Making of devin-clark.com2013-09-02T19:02:02-00:00https://devin-clark.com/blog/the-making-of-devin-clark-com/<p>My design philosophy for the project I strive for is something minimal, with a subtly powerful UI. I used <a href="http://www.bohemiancoding.com/sketch/">Sketch 2</a> for initial design mockups. This post will be somewhat of a living document.</p>
<p>For my back-end, I am using <a href="http://wordpress.org/">WordPress</a> because it is amazing. On the front-end I am using <a href="http://jquery.com/">jQuery</a>, <a href="http://prismjs.com/">PrismJS</a>, and <a href="https://github.com/csswizardry/csswizardry-grids">csswizardry-grids</a>.</p>
<p>The front-end is fairly typical so I am not putting much emphasis on that process. I built it mobile-first with responsive breakpoints for mobile, tablet (portrait and landscape), and desktop.</p>
<h2>Build Process</h2>
<p>I am using Compass and Sass for my CSS. Compass generates a sprite of all the various icons on the site. I used <a href="http://simpleicons.org/">Simple Icons</a> for the social icons. I don't use any of the vendor prefix generating mixins compass provides because I have <a href="https://github.com/ai/autoprefixer">Autoprefixer</a> set to compile the stylesheet after Compass finishes. Here is my Gruntfile. It is pretty simple. I keep it in the root of my project.</p>
<pre class="language-javascript"><code class="language-javascript">module<span class="token punctuation">.</span><span class="token function-variable function">exports</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">grunt</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token comment">// load all grunt tasks matching the `grunt-*` pattern</span><br> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'load-grunt-tasks'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>grunt<span class="token punctuation">)</span><span class="token punctuation">;</span><br><br> <span class="token keyword">var</span> globals <span class="token operator">=</span> <span class="token punctuation">{</span><br> template_url<span class="token operator">:</span> <span class="token string">'app/wp-content/themes/dev-v2/'</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">;</span><br><br> grunt<span class="token punctuation">.</span><span class="token function">initConfig</span><span class="token punctuation">(</span><span class="token punctuation">{</span><br> watch<span class="token operator">:</span> <span class="token punctuation">{</span><br> sass<span class="token operator">:</span> <span class="token punctuation">{</span><br> files<span class="token operator">:</span> <span class="token punctuation">[</span>globals<span class="token punctuation">.</span>template_url <span class="token operator">+</span> <span class="token string">'sass/*.scss'</span><span class="token punctuation">]</span><span class="token punctuation">,</span><br> tasks<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">'compass'</span><span class="token punctuation">]</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> css<span class="token operator">:</span> <span class="token punctuation">{</span><br> files<span class="token operator">:</span> <span class="token punctuation">[</span>globals<span class="token punctuation">.</span>template_url <span class="token operator">+</span> <span class="token string">'css/style.css'</span><span class="token punctuation">]</span><span class="token punctuation">,</span><br> tasks<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">'autoprefixer'</span><span class="token punctuation">]</span><span class="token punctuation">,</span><br> options<span class="token operator">:</span> <span class="token punctuation">{</span><br> spawn<span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> compass<span class="token operator">:</span> <span class="token punctuation">{</span><br> dist<span class="token operator">:</span> <span class="token punctuation">{</span><br> options<span class="token operator">:</span> <span class="token punctuation">{</span><br> basePath<span class="token operator">:</span> globals<span class="token punctuation">.</span>template_url<span class="token punctuation">,</span><br> config<span class="token operator">:</span> globals<span class="token punctuation">.</span>template_url <span class="token operator">+</span> <span class="token string">'config.rb'</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> autoprefixer<span class="token operator">:</span> <span class="token punctuation">{</span><br> dist<span class="token operator">:</span> <span class="token punctuation">{</span><br> options<span class="token operator">:</span> <span class="token punctuation">{</span><br> browsers<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">'last 2 versions'</span><span class="token punctuation">]</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> files<span class="token operator">:</span> <span class="token punctuation">{</span><br> <span class="token string">'app/wp-content/themes/dev-v2/style.css'</span><span class="token operator">:</span> <span class="token punctuation">[</span>globals<span class="token punctuation">.</span>template_url <span class="token operator">+</span> <span class="token string">'css/style.css'</span><span class="token punctuation">]</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><br> grunt<span class="token punctuation">.</span><span class="token function">registerTask</span><span class="token punctuation">(</span><span class="token string">'default'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'compass'</span><span class="token punctuation">,</span> <span class="token string">'autoprefixer'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>
<h2>Deployment</h2>
<p>I am using <a href="https://github.com/BrunoDeBarros/git-deploy-php">git-deploy-php</a>, slightly modified, to deploy the project files and the migrated version of the database. The deploy shell script I use looks very similar to this. It relies heavily on <a href="http://wp-cli.org/">wp-cli</a></p>
<pre class="language-bash"><code class="language-bash"><span class="token builtin class-name">cd</span> ~/Sites/devin-clark<br><span class="token function">git</span> push<br><span class="token function">git</span> rev-parse HEAD <span class="token operator">></span> REVISION<br><span class="token builtin class-name">cd</span> app<br>wp db <span class="token builtin class-name">export</span> <span class="token punctuation">..</span>/backup-snapshot.sql<br>wp search-replace devin-clark.com/ devin-clark.com/ --skip-columns<span class="token operator">=</span>guid<br>wp db <span class="token builtin class-name">export</span> <span class="token punctuation">..</span>/production.sql<br>wp db <span class="token function">import</span> <span class="token punctuation">..</span>/backup-snapshot.sql<br><span class="token function">rm</span> <span class="token punctuation">..</span>/backup-snapshot.sql<br><span class="token builtin class-name">cd</span> <span class="token punctuation">..</span><br>php git-deploy<br><span class="token comment"># Run a script on the server to import the database</span></code></pre>
<p>And boom goes the dynamite... The files are now synced with my Git repository and the local database is migrated to the live server all in one command.</p>
<p>Do you have any questions? Is there anything you feel I missed or could have covered better? Let me know in the comments and I will try my best to sort it out. Thank you for reading and have a great day</p>
Grunt: A Tool for the Modern Web Artisan2013-09-17T21:59:07-00:00https://devin-clark.com/blog/grunt-tool-modern-web-artisan/<p>Automate Everything; a philosophy we should all strive for as developers. Grunt can help with this and I would like to help you learn how to properly utilize it.</p>
<p>Have you ever… compiled Compass/Sass, used Autoprefixer on CSS, concatenated JavaScript or CSS, minified JavaScript or CSS or linted JavaScript or CSS manually? Well you’re wasting a lot of time. Grunt can do all of these (and more) with one command or even when you save a relevant file.</p>
<h2 id="installinggrunt">Installing Grunt</h2>
<p>Grunt and all of its tasks are node modules on NPM so installation is as easy as <code>npm install -g grunt-cli</code>. Don’t get too excited; this is just the global command for grunt. </p>
<p>Now we need to open out project directory in a terminal window and run <code>npm install grunt --save-dev</code>. If you don’t already have a package.json file in your project, run <code>npm init</code> first. I usually just hit enter through the fields and change them later. Now we are up and running …sort of. </p>
<p>Grunt has hundreds of plugins that you install via NPM. I would recommend you install them with the <code>--save-dev</code> option so they will be stored in your package.json file. This will allow other developers to take your project, run npm install and be ready to go. </p>
<h2 id="usinggrunt">Using Grunt</h2>
<p>Let’s dive in with some code. I am going to include a sample Gruntfile at the bottom of the post that I used in a recent project. Here is a very minimal example to get you started. Place this code in Gruntfile.js.</p>
<pre class="language-javascript"><code class="language-javascript">module<span class="token punctuation">.</span><span class="token function-variable function">exports</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">grunt</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'load-grunt-tasks'</span><span class="token punctuation">)</span><span class="token punctuation">(</span>grunt<span class="token punctuation">)</span><span class="token punctuation">;</span><br><br> grunt<span class="token punctuation">.</span><span class="token function">initConfig</span><span class="token punctuation">(</span><span class="token punctuation">{</span><br> jshint<span class="token operator">:</span> <span class="token punctuation">{</span><br> all<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">'js/*.js'</span><span class="token punctuation">]</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><br> grunt<span class="token punctuation">.</span><span class="token function">registerTask</span><span class="token punctuation">(</span><span class="token string">'default'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string">'jshint'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>
<p>You might notice this line <code>require('load-grunt-tasks')(grunt);</code> and wonder what kind of madness that is. This is a brilliant Grunt plugin called <a href="https://github.com/sindresorhus/load-grunt-tasks">load-grunt-tasks</a> that loads in all the tasks automagically so you don’t need a line to require each task. To install, just run <code>npm install --save-dev load-grunt-tasks</code>.</p>
<p>For this task to work, you will need to run <code>npm install grunt-contrib-jshint --save-dev</code>. Then you can run <code>grunt</code> and it will run jshint on your all the js files in the js directory. Every task I’ve seen includes sample(s) of this code in the README.</p>
<p>As promised, here is the link to <a href="https://gist.github.com/DevinClark/6603821">my boilerplate Gruntfile</a>.</p>
<p>Thanks for reading. If you have any questions or comments please leave a comment below and I will try my best to address it. In the future, I would like to cover <a href="http://gruntjs.com/project-scaffolding">grunt-init</a>, a scaffolding tool.</p>
200OK Conference Wrap Up2013-10-07T19:52:36-00:00https://devin-clark.com/blog/200ok-conference-wrap/<p><a href="http://200ok.us/">200OK</a>, Oklahoma's premier web dev conference, took place in Tulsa, Oklahoma on September 27th 2013. I had the pleasure of attending and I would like to share my experiences. It was an excellent conference, with a rock star (yeah I said it!) lineup of speakers. This was the first time (that I can remember) going to Tulsa. I live about two hours away.</p>
<h2 id="firefox-os-and-web-apis">Firefox OS and Web APIs</h2>
<p>This talk was given by <a href="http://davidwalsh.name/">David Walsh</a>. The slides are available at <a href="https://devin-clark.com/blog/200ok-conference-wrap/dwf.tw/200">dwf.tw/200</a>. I have followed David's blog for years and I was excited when I saw he was speaking.</p>
<h2 id="mobile-web-at-etsy">Mobile Web at Etsy</h2>
<p>This talk was given by <a href="http://laraswanson.com/">Lara Swanson</a>. Lara is an amazing speaker and obviously is a descendant of my personal hero, Ron Swanson. </p>
<p><img src="http://cdnl.complex.com/mp/620/400/80/0/bb/1/ffffff/4ae86e3e1e1068a9d3e866db6a3dfbb4/images_/assets/CHANNEL_IMAGES/POP_CULTURE/2013/04/the-50-funniest-gifs-of-ron-swanson/cvepz_41_563115.gif" alt="Ron Swanson Bacon and Eggs"></p>
<p>I found this talk to be incredibly interesting because it combines two things that really fascinate me, mobile web development and performance. </p>
<p>Etsy has an alert set up that notifies the team when a page violates their performance SLA. I think that's a great idea. </p>
<p>They have an amazing device lab. You can read about it on <a href="http://codeascraft.com/2013/08/09/mobile-device-lab/">Code as Craft</a>.</p>
<p>The <a href="http://laraswanson.com/mobileweb/">slides and some relevant resources</a> for this talk, which I highly recommend you go through, are available on Lara's website.</p>
<h2 id="github-culture-and-technology">Github Culture and Technology</h2>
<p>This talk was given by <a href="http://twitter.com/michaelgorsuch">Michael Gorsuch</a>. I was surprised to hear we have a Githubber in Oklahoma City. One interesting thing Michale mentioned in the talk is how Github practices README driven development. The idea behind it is to write the blog post before the product and use the blog post to guide the product.</p>
<p>He recommended a talk <em><a href="http://vimeo.com/m/10877889">Everything I know about Open Source I learned from Indie Hip Hop</a></em></p>
<p>It was an excellent insight into the work environment of Github and I would definitely recommend you watch the video for this presentation when it becomes available. I will try to do a post or something when they videos from 200OK are available.</p>
<h2 id="brackets-edge-code">Brackets & Edge Code</h2>
<p>This talk was given by <a href="https://twitter.com/cfjedimaster">Raymond Camden</a>, a hilarious man and Adobe Evangelist. He is the man responsible for the daily Adobe Updates but I do not hold that against him. Raymond revealed the magic of the wonderful code editor, <a href="http://brackets.io/">Brackets</a>. It is certainly something I would consider using instead of Sublime Text for JavaScript editing.</p>
<h2 id="conclusion">Conclusion</h2>
<p>A common theme between most of the companies who spoke was they use some sort of chat program, whether it is IRC at Etsy or Campfire + Hubot at Github, to effectively communicate between team members.</p>
<p>I look forward to attending next year!</p>
<p>Did you attend 200OK and have something you wish to add? Leave a comment.</p>
Star Dates in JavaScript2013-12-29T19:13:21-00:00https://devin-clark.com/blog/star-dates-in-javascript/<p>While on my winter vacation, I began creating problems to solve out of boredom and to keep my JavaScript skills sharp. One evening, after an unknown amount of whiskey, I decided to look into converting dates into Stardates. TREKKIE ALERT! Don’t let this discourage you from reading. There still is a decent amount of information JavaScript Dates that can be extracted from this article.</p>
<p>After a bit of research I found that stardates don’t really exist (yet). That was a bit of a disappointing dead end but I found <a href="http://en.wikipedia.org/wiki/Julian_day">Julian Days</a> to be about the closest equivalent. I assume we will use these in place of stardates in the future. Anyways, I started researching Julian Days, lots of Stack Overflowin’, and (SPOILER ALERT) I eventually got a working converter build. </p>
<p>The first hurdle I had to solve was figuring out the OMG MATH aspect of <a href="http://aa.usno.navy.mil/faq/docs/JD_Formula.php">the formula I found</a>. This was solved by finding a different formula that worked with seconds rather than ALL THE UNITS. This new formula also made conversion to UTC easier, because Julian Days are always calculated using UTC time.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">var</span> <span class="token constant">JD</span> <span class="token operator">=</span> <span class="token constant">EPOC_SECONDS</span> <span class="token operator">/</span> <span class="token number">86400000</span> <span class="token operator">-</span> <span class="token constant">TIMEZONE_OFFSET</span> <span class="token operator">/</span> <span class="token number">1440</span> <span class="token operator">+</span> <span class="token number">2440587.5</span><span class="token punctuation">;</span></code></pre>
<p>Now, we have a working formula. Let’s plug it in as a JavaScript Date() method. Yes, before you get all up in arms, I am going to use <code>Date.prototype.toStarDate</code>. The day this causes a collision will be a very happy day for me, should that day ever come.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token class-name">Date</span><span class="token punctuation">.</span>prototype<span class="token punctuation">.</span><span class="token function-variable function">toStarDate</span> <span class="token operator">=</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token keyword">return</span> <span class="token keyword">this</span> <span class="token operator">/</span> <span class="token number">86400000</span> <span class="token operator">-</span> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">getTimezoneOffset</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">1440</span> <span class="token operator">+</span> <span class="token number">2440587.5</span><span class="token punctuation">;</span><br><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>
<p>I originally was rounding the result to two decimal places I later realized that would produce an incorrect Julian Day. I am still skeptical whether JavaScript floating point math is an issue here. It would probably be worth integrating something like <a href="https://github.com/dtrebbien/BigDecimal.js">BigDecimal.js</a> but that seems out of scope for a whiskey-fueled “just for funzies” project.</p>
<p>Here is a possibly working <a href="http://jsfiddle.net/DevinClark/u3u5P/">demo link</a>. If you made it this far, I salute you.</p>
Quick Tip: npm CLI Shorthands2014-04-09T15:28:38.724-00:00https://devin-clark.com/blog/quick-tip-npm-cli-shorthands/<p>If you're like me, you spend a lot of time daily using npm, the official node package manager. Typing <code>npm install whatever-package --save</code> or <code>npm install whatever-package --save-dev</code> is very tedious.</p>
<p>I recently discovered there are aliases for <code>--save</code> and <code>--save-dev</code>. <code>--save</code> can be replaced with <code>-S</code> and <code>--save-dev</code> with <code>-D</code>.</p>
<p>There are a few others in the source link below but I felt those two are the most commonly used. I hope this speeds up your <code>npm install</code>-ing like it did mine!</p>
<p>Also, you can run <code>npm i whatever-package</code> instead of <code>npm install whatever-package</code>.</p>
<p><a href="https://www.npmjs.org/doc/misc/npm-config.html#Shorthands-and-Other-CLI-Niceties">Source</a></p>
Browserify: Rockin' the Wizard Hat2014-04-15T15:05:52.065-00:00https://devin-clark.com/blog/okcjs-browserify/<p><a href="http://twitter.com/jvrousseau">Jordan Rousseau</a> recently gave a presentation at <a href="http://okcjs.org/">OKC.JS</a> about <a href="http://browserify.org/">Browserify</a>. Jordan is the fearless leader of the web team, of which I happen to be a member, at <a href="http://wdtinc.com/">Weather Decision Technologies</a>.</p>
<p><img src="https://devin-clark.com/blog/okcjs-browserify/assets/images/jordan-rousseau-gandalf.jpg" alt="Jordan Rousseau as Gandalf"></p>
<p>Jordan spends the first 18 slides talking about bad ways to handle loading JavaScript. When I say "bad ways" I mean ways that are difficult to maintain and/or do not scale well. After a lot of investigation, we landed on Browserify.</p>
<p>Browserify is a utility that builds CommonJS modules into a single bundle browser code with Node.js-style requires. Just like node Browserify allows you to write modules in separate files and use <code>module.exports</code> to expose external methods and properties. You can also use (some) npm modules!</p>
<h2 id="getting-started">Getting Started <a class="direct-link" href="#getting-started">#</a></h2>
<p>To begin, simply install browserify using npm.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> i browserify -g</code></pre>
<p>This installs the CLI for Browserify. It can be a bit annoying to use at times so we use <a href="https://github.com/jmreidy/grunt-browserify">grunt-browserify</a>. If you are dead set on using the CLI, I recommend you look into <a href="https://github.com/substack/watchify">watchify</a>. If you use Gulp, I believe you can use it with Browserify but I have never used Gulp so I can't speak to it personally.</p>
<h3 id="using-with-grunt">Using with Grunt <a class="direct-link" href="#using-with-grunt">#</a></h3>
<pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> i grunt-browserify -D</code></pre>
<p>This will install the grunt-browserify task and save it in the <code>package.json</code> file as a <code>devDependency</code>.</p>
<pre class="language-javascript"><code class="language-javascript">browserify<span class="token operator">:</span> <span class="token punctuation">{</span><br> dev<span class="token operator">:</span> <span class="token punctuation">{</span><br> files<span class="token operator">:</span> <span class="token punctuation">{</span><br> <span class="token string">'js/bundle.js'</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">'js/app.js'</span><span class="token punctuation">]</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> options<span class="token operator">:</span> <span class="token punctuation">{</span><br> transform<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">'brfs'</span><span class="token punctuation">]</span><span class="token punctuation">,</span><br> alias<span class="token operator">:</span> <span class="token punctuation">[</span><br> <span class="token string">'./node_modules/lodash/dist/lodash.underscore:underscore'</span><br> <span class="token punctuation">]</span><span class="token punctuation">,</span><br> debug<span class="token operator">:</span> <span class="token boolean">false</span><br> <span class="token punctuation">}</span><br> <span class="token punctuation">}</span><br><span class="token punctuation">}</span></code></pre>
<p>Here is kind of the boilerplate code for the browserify task of our web projects. Nothing super special here. LoDash is being aliased to underscore because Backbone attempts to require Underscore and it will throw an error if we are using LoDash in place of Underscore.</p>
<p>Jordan has some interesting demos in his slides, available at the bottom of the post. They are definitely worth checking out.</p>
<h2 id="transforms">Transforms <a class="direct-link" href="#transforms">#</a></h2>
<p>Transforms in are essentially Browserify middleware that run source transformations on files before they are parsed by Browserify. An example of a transform is <a href="https://github.com/jaredhanson/deamdify">deAMDify</a>, a module that converts AMD modules to CommonJS so they will play nice with Browserify. A few other transforms to check out are <a href="https://github.com/substack/brfs">brfs</a>, <a href="https://github.com/thlorenz/es6ify">es6ify</a>, and <a href="https://github.com/jnordberg/coffeeify">coffeeify</a> (if you are <em>that</em> kind of person). For a more comprehensive list see <a href="https://github.com/substack/node-browserify/wiki/list-of-transforms">the Browserify wiki on transforms</a>.</p>
<p><img src="https://devin-clark.com/blog/okcjs-browserify/assets/images/npm-install-all-things.jpg" alt="NPM INSTALL ALL THE THINGS!"></p>
<h2 id="resources">Resources <a class="direct-link" href="#resources">#</a></h2>
<ul>
<li><a href="http://benclinkinbeard.com/posts/how-browserify-works/">How Browserify Works</a></li>
<li><a href="http://maxogden.com/node-packaged-modules.html">Introducing RequireBin, Browserify-CDN and npmsearch</a></li>
<li><a href="https://github.com/substack/node-browserify/wiki">Browserify Wiki</a></li>
<li><a href="http://browserify.org/">Browserify.org</a></li>
</ul>
<p>The slides for Jordan's talk are <a href="http://rousseau.io/browserify-okcjs/">available on github</a>. Hopefully, you now have everything you need to become a Browserify Wizard! Feel free to ask if you have any questions.</p>
Quick Tip: Useful Npm Package Listing2014-05-07T16:14:07.361-00:00https://devin-clark.com/blog/quick-tip-useful-npm-package-listing/<p>We've all had to suffer through <code>npm ls</code> and it's endless trees of dependencies but there is a better way!</p>
<p>That way is the <code>--depth</code> flag. That's right, it was as easy as <code>npm ls --depth=0</code>. Now you can see the packages you actually installed.</p>
<p>That was easy... too easy... If you ran that command you probably noticed a bunch of these little buggers at the bottom of the output.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> ERR<span class="token operator">!</span> max depth reached: express@3.5.2, required by my-project@0.4.18</code></pre>
<p>Let's fix this. Start by running <code>sudo nano ~/.profile</code>. If you would rather use vi for this, type <code>alias vi='nano'; sudo vi ~/.profile</code>. Then, add this line to the file, save, and reload <code>~/.profile</code> by running <code>source ~/.profile</code>.</p>
<pre class="language-bash"><code class="language-bash"><span class="token builtin class-name">alias</span> <span class="token string">"npmls0"</span><span class="token operator">=</span><span class="token string">"npm ls --depth=0 2>/dev/null"</span></code></pre>
<p>The key to this is <code>2>/dev/null</code>. All it does it eat the errors.</p>
<p>Now you can just run <code>npmls0</code> and see your npm packages and their associated versions.</p>
<p><a href="https://www.npmjs.org/doc/cli/npm-ls.html#depth">Source</a></p>
Getting Started with the Bourbon Family: a Sassoholics Best Friend2014-05-16T00:59:10.434-00:00https://devin-clark.com/blog/getting-started-with-bourbon/<p>When I say "The Bourbon Family", I am referring to <a href="http://bourbon.io/">Bourbon</a>, <a href="http://neat.bourbon.io/">Neat</a>, <a href="http://bitters.bourbon.io/">Bitters</a>, and <a href="http://refills.bourbon.io/">Refills</a>. What are they? Well, Bourbon is a mixin library for Sass. The others are built on top of Bourbon. Neat is a Sass grid system. Bitters is a kind of scaffold project with some sensible default styles. Refills is a collection of common components (think Bootstrap with less fail :P). Together they form the Bourbon Family!</p>
<p><img src="https://devin-clark.com/blog/getting-started-with-bourbon/assets/images/bourbon.jpg" alt="Bourbon FTW!"></p>
<h2 id="installation">Installation <a class="direct-link" href="#installation">#</a></h2>
<p>To begin, install Bourbon, Neat, and Bitters using Ruby Gems.</p>
<pre class="language-bash"><code class="language-bash">gem <span class="token function">install</span> bourbon neat bitters</code></pre>
<p>This will install the CLI gems that are used to install The Bourbon Family to your project. Next we need to install them in our project. I prefer to install them to a lib directory inside my Sass directory. This can be done for Bourbon by passing a <code>--path</code> argument to the install command. For some reason, Neat and Bitters do not take a path argument. No worries! We can work around that.</p>
<pre class="language-bash"><code class="language-bash">bourbon <span class="token function">install</span> --path ./sass/lib/<br>neat <span class="token function">install</span> <span class="token operator">&&</span> <span class="token function">mv</span> neat ./sass/lib/<br>bitters <span class="token function">install</span> <span class="token operator">&&</span> <span class="token function">mv</span> bitters ./sass/lib/</code></pre>
<p>This will install a bunch of scss files into <code>sass/lib</code>. I check these into Git. I'm not sure if that is a bad thing but it works for me.</p>
<h2 id="getting-started">Getting Started <a class="direct-link" href="#getting-started">#</a></h2>
<p>Now you can import them into your base Sass file.</p>
<pre class="language-scss"><code class="language-scss"><span class="token comment">// Variables</span><br><span class="token property"><span class="token variable">$black</span></span><span class="token punctuation">:</span> #000<span class="token punctuation">;</span><br><br><span class="token keyword">@import</span> <span class="token string">'lib/bourbon/bourbon'</span><span class="token punctuation">;</span><br><br><span class="token keyword">@import</span> <span class="token string">'lib/neat/neat-helpers'</span><span class="token punctuation">;</span><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/grid-settings'</span><span class="token punctuation">;</span><br><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/variables'</span><span class="token punctuation">;</span><br><br><span class="token comment">// Bitters Variable Overrides</span><br><span class="token property"><span class="token variable">$base-font-family</span></span><span class="token punctuation">:</span> <span class="token string">'Open Sans'</span><span class="token punctuation">,</span> <span class="token variable">$sans-serif</span><span class="token punctuation">;</span><br><span class="token property"><span class="token variable">$header-font-family</span></span><span class="token punctuation">:</span> <span class="token string">'Noto Sans'</span><span class="token punctuation">,</span> <span class="token variable">$base-font-family</span><span class="token punctuation">;</span><br><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/extends/base'</span><span class="token punctuation">;</span><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/mixins/base'</span><span class="token punctuation">;</span><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/typography'</span><span class="token punctuation">;</span><br><span class="token comment">//@import "lib/bitters/forms";</span><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/tables'</span><span class="token punctuation">;</span><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/lists'</span><span class="token punctuation">;</span><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/flashes'</span><span class="token punctuation">;</span><br><br><span class="token keyword">@import</span> <span class="token string">'lib/neat/neat'</span><span class="token punctuation">;</span></code></pre>
<p>Woah! That's a lot of imports. Well... not really. Ideally your base sass file should be <em>entirely</em> imports. This is accomplished by structuring your Sass in a modular way. </preach> If you are wondering why I have forms commented out, it's because my blog (the project I took this code example from) didn't have any forms. I probably should have commented out flashes and maaaayyybeee tables but it's not a big deal. This is where Sass is beneficial. Take what you need and only what you need.</p>
<p>You will probably want to use some kind of CSS reset because Bitters does not bundle one. I (and Bitters) recommend <a href="http://necolas.github.io/normalize.css/">Normalize.css</a>. Normalize is different than most CSS resets. Normalize, as the name suggests, normalizes element styles across browsers instead of just zeroing out all styles.</p>
<h2 id="bourbon">Bourbon <a class="direct-link" href="#bourbon">#</a></h2>
<p>Bourbon is awesome! While a good chunk of it's functionality can be negated by <a href="https://github.com/ai/autoprefixer">autoprefixer</a> but that doesn't make Bourbon any less awesome. Let's check out a few Bourbon methods.</p>
<pre class="language-scss"><code class="language-scss"><span class="token property"><span class="token variable">$mobile-width</span></span><span class="token punctuation">:</span> <span class="token function">em</span><span class="token punctuation">(</span>480<span class="token punctuation">)</span><span class="token punctuation">;</span><br><br><span class="token keyword">@include</span> <span class="token function">hidpi</span><span class="token punctuation">(</span>1.5<span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token selector">.logo </span><span class="token punctuation">{</span><br> <span class="token property">width</span><span class="token punctuation">:</span> 100%<span class="token punctuation">;</span><br> <span class="token punctuation">}</span><br><span class="token punctuation">}</span></code></pre>
<ul>
<li><code>em()</code> takes a pixel value as a parameter and returns an em value.</li>
<li><code>hidpi()</code> takes an optional device pixel ratio, and generates a media query based on it.</li>
</ul>
<p>These are just two methods Bourbon contains to make your life easier. You can read in the <a href="http://bourbon.io/docs/">Bourbon docs</a> about the dozens of others!</p>
<h2 id="neat">Neat <a class="direct-link" href="#neat">#</a></h2>
<p><img src="https://devin-clark.com/blog/getting-started-with-bourbon/assets/images/neat.jpg" alt="I think you're neat"></p>
<p>Neat is a grid system built on top of Bourbon. <strong><em>OMG</em></strong> not <em>another</em> grid system! No. Bad you. Neat is different. Neat is a <em>semantic</em> grid system, meaning it doesn't pollute your HTML with grid attributes and div-itis. If you want to see an example of the exact opposite of Neat, check out the <a href="http://getbootstrap.com/css/#grid">docs for the Bootstrap grid system</a>. When you pull in Neat like we did earlier with the <code>@import "lib/neat/neat";</code> line, what do you think is compiled? If you said not much you are correct. All Neat will output is:</p>
<pre class="language-css"><code class="language-css"><span class="token selector">*</span> <span class="token punctuation">{</span><br> <span class="token property">-webkit-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span><br> <span class="token property">-moz-box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span><br> <span class="token property">box-sizing</span><span class="token punctuation">:</span> border-box<span class="token punctuation">;</span><br><span class="token punctuation">}</span></code></pre>
<p>What you do get does not compile directly. You get mixins and functions to build you own grid system. Let's give it a shot.</p>
<pre class="language-scss"><code class="language-scss"><span class="token selector">header </span><span class="token punctuation">{</span><br> <span class="token keyword">@include</span> outer-container<span class="token punctuation">;</span><br><br> <span class="token selector">.logo </span><span class="token punctuation">{</span><br> <span class="token keyword">@include</span> <span class="token function">span-columns</span><span class="token punctuation">(</span>3<span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><br><br> <span class="token selector">nav </span><span class="token punctuation">{</span><br> <span class="token keyword">@include</span> <span class="token function">span-columns</span><span class="token punctuation">(</span>9<span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><br><span class="token punctuation">}</span></code></pre>
<p>We just coded the layout of the header for a website. By default, Neat is a 12 column grid, using percentage widths. You can change this by changing the <code>$grid-columns</code> variable. You can also override it inside a media block. Let's spice this up and make it responsive and some other cool stuff.</p>
<blockquote>
<p>Protip: Neat has a grid overlay that you can toggle by setting the <code>$visual-grid</code> boolean to true. This can be very useful.</p>
</blockquote>
<pre class="language-scss"><code class="language-scss"><span class="token property"><span class="token variable">$mobile</span></span><span class="token punctuation">:</span> <span class="token function">new-breakpoint</span><span class="token punctuation">(</span>max-width 480px<span class="token punctuation">,</span> 4<span class="token punctuation">)</span><span class="token punctuation">;</span><br><br><span class="token selector">section </span><span class="token punctuation">{</span><br> <span class="token keyword">@include</span> <span class="token function">media</span><span class="token punctuation">(</span><span class="token variable">$mobile</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token selector">.logo </span><span class="token punctuation">{</span><br> <span class="token keyword">@include</span> <span class="token function">span-columns</span><span class="token punctuation">(</span>2<span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token keyword">@include</span> <span class="token function">shift</span><span class="token punctuation">(</span>1<span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><br><br> <span class="token selector">nav </span><span class="token punctuation">{</span><br> <span class="token keyword">@include</span> <span class="token function">span-columns</span><span class="token punctuation">(</span>4<span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><br> <span class="token punctuation">}</span><br><span class="token punctuation">}</span></code></pre>
<p>Here we are defining a breakpoint for mobile devices that will use a 4 column grid. This works for me because I feel that 12 columns is way too granular for that small of a width. We are also making the logo 50% width (2 out of 4 columns) and shifting it to the right one column, centering it, and making the navigation full width. Wait just a minute, sir... Did you just nest a media query? Yep. Welcome to Neat. I recommend you check out the <a href="http://neat.bourbon.io/docs/">Neat docs</a>.</p>
<h2 id="bitters">Bitters <a class="direct-link" href="#bitters">#</a></h2>
<p><a href="http://bitters.bourbon.io/">Bitters</a> is a collection of base styles, typography, form styles, variables, and even includes an error message module. The error message module is designed with Rails in mind, though it is by no means specific to Rails. Bitters is not a library. It is structured in a way that is designed to be your starting point. Though the breakpoints it provides aren't as comprehensive as most of us need, it is still definitely worth using and easy enough to edit to your liking. If you are interested in the breakpoints I added for this site here they are. Honestly, I'm not using most of them but it doesn't hurt to over do them.</p>
<pre class="language-scss"><code class="language-scss"><span class="token comment">// Widths</span><br><span class="token property"><span class="token variable">$mobile-width</span></span><span class="token punctuation">:</span> <span class="token function">em</span><span class="token punctuation">(</span>480<span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token property"><span class="token variable">$small-tablet-width</span></span><span class="token punctuation">:</span> <span class="token function">em</span><span class="token punctuation">(</span>720<span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token property"><span class="token variable">$large-tablet-width</span></span><span class="token punctuation">:</span> <span class="token function">em</span><span class="token punctuation">(</span>960<span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token property"><span class="token variable">$desktop-width</span></span><span class="token punctuation">:</span> <span class="token function">em</span><span class="token punctuation">(</span>1050<span class="token punctuation">)</span><span class="token punctuation">;</span><br><br><span class="token comment">// Bourbon Neat Breakpoints</span><br><span class="token property"><span class="token variable">$mobile</span></span><span class="token punctuation">:</span> <span class="token function">new-breakpoint</span><span class="token punctuation">(</span>max-width <span class="token variable">$mobile-width</span><span class="token punctuation">,</span> 4<span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token property"><span class="token variable">$small-tablet</span></span><span class="token punctuation">:</span> <span class="token function">new-breakpoint</span><span class="token punctuation">(</span>min-width <span class="token variable">$small-tablet-width</span> max-width <span class="token variable">$large-tablet-width</span> <span class="token operator">-</span> 1<span class="token punctuation">,</span> 8<span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token property"><span class="token variable">$large-tablet</span></span><span class="token punctuation">:</span> <span class="token function">new-breakpoint</span><span class="token punctuation">(</span>min-width <span class="token variable">$large-tablet-width</span> max-width <span class="token variable">$desktop-width</span> <span class="token operator">-</span> 1<span class="token punctuation">,</span> 12<span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token property"><span class="token variable">$tablet</span></span><span class="token punctuation">:</span> <span class="token function">new-breakpoint</span><span class="token punctuation">(</span>min-width <span class="token variable">$small-tablet-width</span> max-width <span class="token variable">$desktop-width</span> <span class="token operator">-</span> 1<span class="token punctuation">,</span> 12<span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token property"><span class="token variable">$desktop</span></span><span class="token punctuation">:</span> <span class="token function">new-breakpoint</span><span class="token punctuation">(</span>min-width <span class="token variable">$desktop-width</span><span class="token punctuation">,</span> 16<span class="token punctuation">)</span><span class="token punctuation">;</span><br><br><span class="token property"><span class="token variable">$small-tablet-down</span></span><span class="token punctuation">:</span> <span class="token function">new-breakpoint</span><span class="token punctuation">(</span>max-width <span class="token variable">$large-tablet-width</span><span class="token punctuation">,</span> 8<span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token property"><span class="token variable">$tablet-down</span></span><span class="token punctuation">:</span> <span class="token function">new-breakpoint</span><span class="token punctuation">(</span>max-width <span class="token variable">$desktop</span><span class="token punctuation">,</span> 8<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<h2 id="refills">Refills <a class="direct-link" href="#refills">#</a></h2>
<p><a href="http://refills.bourbon.io/">Refills</a> is a collection of pretty UI components built using The Bourbon Family. It is a nice thing to have in your toolbelt because even if it isn't <em>exactly</em> what you want, it gets you pretty close.</p>
<h2 id="conclusion">Conclusion <a class="direct-link" href="#conclusion">#</a></h2>
<p>If you made it this far, I salute you and you are probably in love with The Bourbon Family. I hope you enjoyed the ride. Do you have any questions? Leave a comment and I will try to help. I've also been know to hang out in the #techlahoma IRC channel on Freenode with the rest of the <a href="http://techlahoma.com/">Techlahomies</a> (my username there is dddev).</p>
<h2 id="full-example">Full Example <a class="direct-link" href="#full-example">#</a></h2>
<p>Here is a compiled version of the examples above in case you wanted to play around with it (or use it as a starting point).</p>
<pre class="language-scss"><code class="language-scss"><span class="token comment">// Variables</span><br><span class="token property"><span class="token variable">$black</span></span><span class="token punctuation">:</span> #000<span class="token punctuation">;</span><br><br><span class="token keyword">@import</span> <span class="token string">'lib/bourbon/bourbon'</span><span class="token punctuation">;</span><br><br><span class="token keyword">@import</span> <span class="token string">'lib/neat/neat-helpers'</span><span class="token punctuation">;</span><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/grid-settings'</span><span class="token punctuation">;</span><br><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/variables'</span><span class="token punctuation">;</span><br><br><span class="token comment">// Bitters Variable Overrides</span><br><span class="token property"><span class="token variable">$base-font-family</span></span><span class="token punctuation">:</span> <span class="token string">'Open Sans'</span><span class="token punctuation">,</span> <span class="token variable">$sans-serif</span><span class="token punctuation">;</span><br><span class="token property"><span class="token variable">$header-font-family</span></span><span class="token punctuation">:</span> <span class="token string">'Noto Sans'</span><span class="token punctuation">,</span> <span class="token variable">$base-font-family</span><span class="token punctuation">;</span><br><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/extends/base'</span><span class="token punctuation">;</span><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/mixins/base'</span><span class="token punctuation">;</span><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/typography'</span><span class="token punctuation">;</span><br><span class="token comment">//@import "lib/bitters/forms";</span><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/tables'</span><span class="token punctuation">;</span><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/lists'</span><span class="token punctuation">;</span><br><span class="token keyword">@import</span> <span class="token string">'lib/bitters/flashes'</span><span class="token punctuation">;</span><br><br><span class="token keyword">@import</span> <span class="token string">'lib/neat/neat'</span><span class="token punctuation">;</span><br><br><span class="token selector">header </span><span class="token punctuation">{</span><br> <span class="token keyword">@include</span> outer-container<span class="token punctuation">;</span><br><br> <span class="token selector">.logo </span><span class="token punctuation">{</span><br> <span class="token keyword">@include</span> <span class="token function">span-columns</span><span class="token punctuation">(</span>3<span class="token punctuation">)</span><span class="token punctuation">;</span><br><br> <span class="token keyword">@include</span> <span class="token function">hidpi</span><span class="token punctuation">(</span>1.5<span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token selector">.logo </span><span class="token punctuation">{</span><br> <span class="token property">background-size</span><span class="token punctuation">:</span> 100% auto<span class="token punctuation">;</span><br> <span class="token punctuation">}</span><br> <span class="token punctuation">}</span><br> <span class="token punctuation">}</span><br><br> <span class="token selector">nav </span><span class="token punctuation">{</span><br> <span class="token keyword">@include</span> <span class="token function">span-columns</span><span class="token punctuation">(</span>9<span class="token punctuation">)</span><span class="token punctuation">;</span><br><br> <span class="token selector">a </span><span class="token punctuation">{</span><br> <span class="token property">color</span><span class="token punctuation">:</span> <span class="token variable">$black</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><br> <span class="token punctuation">}</span><br><br> <span class="token keyword">@include</span> <span class="token function">media</span><span class="token punctuation">(</span><span class="token variable">$mobile</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token selector">.logo </span><span class="token punctuation">{</span><br> <span class="token keyword">@include</span> <span class="token function">span-columns</span><span class="token punctuation">(</span>2<span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token keyword">@include</span> <span class="token function">shift</span><span class="token punctuation">(</span>1<span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><br><br> <span class="token selector">nav </span><span class="token punctuation">{</span><br> <span class="token keyword">@include</span> <span class="token function">span-columns</span><span class="token punctuation">(</span>4<span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><br> <span class="token punctuation">}</span><br><span class="token punctuation">}</span></code></pre>
Quick Tip: Don't use Star (and not for the reason you think)2014-05-24T14:38:24.757-00:00https://devin-clark.com/blog/quick-tip-dont-use-star/<p>So, here at <a href="http://wdtinc.com/">WDT</a> we do a lot of the JavaScripts and the CSSes. We had an issue in two of our weather mapping applications where users could not type in text boxes in using Safari. We tried to ignore this bug until yesterday when Jordan, our resident code wizard, found the cause of this issue.</p>
<p>What does this have to do with the wildcard selection operator in CSS? We found that someone (not saying it was me, not saying it wasn't me) had <code>* {user-select: none; }</code> in the stylesheet. The intention was to make the app feel like less of a web app and solve issues with dragging. What's wrong with this? We are making the assumption browsers all have the same interpret the CSS specification in the same way. In this case, user-select on a text input in Safari does not allow users to type in the text input.</p>
<p>Discovering this issue also let to <a href="https://twitter.com/jvrousseau/status/469933110096691201">this awesome passive aggressive tweet</a>.</p>
What You Might Not Know about Chrome DevTools2014-06-18T18:28:03.629-00:00https://devin-clark.com/blog/what-you-might-not-know-about-chrome-devtools/<p>Part One? Chrome's DevTools is a magical and mysterious beast. We can conquer this beast together! Josh Bavari recently gave a <a href="http://jbavari.github.io/blog/2014/05/20/okcjs-javascript-debugging-techniques/">Lightning Talk on JS debugging</a>. You should check it out. He is a great presenter.</p>
<h2 id="console-api">Console API <a class="direct-link" href="#console-api">#</a></h2>
<p>Let's start off with the <a href="https://developer.chrome.com/devtools/docs/console-api">Console API</a>. Josh mentions a few in his presentation but there are so much more! The console object contains a lot more than just <code>console.log()</code>.</p>
<h3 id="count">Count <a class="direct-link" href="#count">#</a></h3>
<p>There's a good chance you have done something like <code>console.log(i + " Times")</code> in a loop to count the number of iterations. Instead you could do <code>console.count('My Loop Name')</code> and you will get an output like this:</p>
<pre><code>My Loop Name: 1
My Loop Name: 2
My Other Loop: 1
My Loop Name: 3
My Other Loop: 2
</code></pre>
<p>The number increments each time the function with that label runs. Each label has a counter so go wild creating as many as you need.</p>
<h3 id="formatting">Formatting <a class="direct-link" href="#formatting">#</a></h3>
<p>You can also format and even style some* of the console statements. By format I mean a <code>printf</code> kind of API. If you are familiar with <code>printf</code> then you are just curious what the format specifiers are.</p>
<h4 id="format-specifiers%3A">Format Specifiers: <a class="direct-link" href="#format-specifiers%3A">#</a></h4>
<ul>
<li><code>%s</code> - String.</li>
<li><code>%d</code> or <code>%i</code> - Integer.</li>
<li><code>%f</code> - Floating point number.</li>
<li><code>%o</code> - DOM Element.</li>
<li><code>%O</code> - Object.</li>
<li><code>%c</code> - The secret to styling console statements.</li>
</ul>
<p>How about an example?</p>
<pre class="language-javascript"><code class="language-javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'My Array Name: %s Contents: %O Length: %i'</span><span class="token punctuation">,</span> <span class="token string">'stuff'</span><span class="token punctuation">,</span> stuff<span class="token punctuation">,</span> stuff<span class="token punctuation">.</span>length<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>This example will output the following in the console: <img src="https://devin-clark.com/blog/what-you-might-not-know-about-chrome-devtools/assets/images/console-example-1.png" alt="Console Output"> If you are wondering why I added <code>stuff.length</code> to my output string because it is in the <code>%O</code>, I needed an integer for my example. That is all.</p>
<p>Now let's talk about styling a little. I have never used it in a practical application. The styling uses CSS. All you have to do is add the <code>%c</code> format specifier to the output string and add some CSS as the value. An example would illustrate this better. I am just going to extend the previous example and make it <em>pretty</em></p>
<pre class="language-javascript"><code class="language-javascript">console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><br> <span class="token string">'%cMy Array Name: %s Contents: %O Length: %i'</span><span class="token punctuation">,</span><br> <span class="token string">'color: #663399; font-size: 2em;'</span><span class="token punctuation">,</span><br> <span class="token string">'stuff'</span><span class="token punctuation">,</span><br> stuff<span class="token punctuation">,</span><br> stuff<span class="token punctuation">.</span>length<br><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>This example will output the following in the console: <img src="https://devin-clark.com/blog/what-you-might-not-know-about-chrome-devtools/assets/images/console-example-2.png" alt="Console Output"> Look at that huge purple output. Hard to miss, huh?</p>
<h3 id="group">Group <a class="direct-link" href="#group">#</a></h3>
<p>You can also group console statements with methods like <code>console.group()</code> and <code>console.groupCollapsed()</code>. These methods will group any log statements between it and a <code>console.groupEnd()</code> method. This can be helpful if you are logging out a lot of data. A lot of times I will wrap the contents of a function I am debugging to make things easier to read. <strong>It is important to note</strong> that this does not work if there is an asynchronous call inside the group. It will appear outside of the group.</p>
<h3 id="time">Time <a class="direct-link" href="#time">#</a></h3>
<p>Need to time something? Look no further than <code>console.time(label)</code>, <code>console.timeline(label)</code>, or <code>console.timeStamp([label])</code>. Time and timeline have similar functionality; timeStamp is a little different. Time and timeline both have <code>*End()</code> methods. Time will output the time elapsed between the two method calls. Timeline starts the DevTools Timeline for the amount of time between start and end methods.</p>
<p>TimeStamp will just give you a marker at the current time on the Timeline with the specified label. This allows you to see what happening on the Timeline at that timestamp.</p>
<p>If you need a high precision time for profiling look into the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Performance">Performance API</a>. Also see this article about <a href="http://codingjohnson.com/javascript-precision-timing#.U6DygpRdWH8">JavaScript Precision Timing</a>.</p>
<h3 id="console-tab">Console Tab <a class="direct-link" href="#console-tab">#</a></h3>
<p>Right clicking on the Console section of DevTools to reveal two options. The first option is "Log XMLHttpRequests" and will output the HTTP method and the URL of the request. I can not express how much this has helped me while developing the SPA app that had heavy API integration. I have been working on the past few months.</p>
<p>The second option is "Preserve Log upon Navigation". This option allows you to debug issues where a redirect occurs. Recently, I used these on an issue was one of my API calls was throwing a 401 status code and causing a redirection to the login page. It was simple to track down which call using both of these options.</p>
Global npm Install without Sudo2015-01-26T16:16:12.839-00:00https://devin-clark.com/blog/global-npm-install-without-sudo/<p>You should not have install global node modules with root! The default for directory global node modules is usually <code>/usr/local/</code> when installing from the <a href="https://www.npmjs.com/">npmjs.com</a> binary. This directory is not writable by users (as intended). I would like to preface this with I have only done this on a OS X. The instructions should be the same for Linux. Sorry Windows users, I can't help here.</p>
<p>The secret to fixing this problem is to change the directory npm uses to globally install. To do this we will change the <code>prefix</code> option in npm config. First, we can run <code>npm config get prefix</code> to see where packages are currently being installed. Next, make a directory where you would like the packages to be installed (and is user writeable). I use <code>~/npm</code>.</p>
<p>Next, we need to tell npm to use the newly created directory by running <code>npm config set prefix ~/npm</code>.</p>
<p>You might think we are done now but now we will need to add <code>~/npm/bin</code> to <code>$PATH</code> so we can use the executables. I store <code>$PATH</code> changes in <code>~/.bashrc</code>. If you would like to store them in another file, feel free.</p>
<p><code><troll type="fanboy"></code>For speed I prefer to use <em>the best command line text editor</em>, nano. <code></troll></code> Anyways, just add this to the file then restart your Terminal window.</p>
<pre class="language-bash"><code class="language-bash"><span class="token assign-left variable"><span class="token environment constant">PATH</span></span><span class="token operator">=</span><span class="token environment constant">$PATH</span><span class="token builtin class-name">:</span><span class="token environment constant">$HOME</span>/npm/bin</code></pre>
<p>That's it! You will need to reinstall any global modules you had previously installed.</p>
<p>Also, my boss, <a href="http://twitter.com/jvrousseau">Jordan</a> uses this setup with <a href="https://github.com/creationix/nvm">nvm</a>. He had a problem because nvm installs global packages in versioned directories. This would break all his <code>npm link</code>'s on version updates. <code>npm link</code> is a big part of our Node development workflow.</p>
<h3 id="more-information">More Information <a class="direct-link" href="#more-information">#</a></h3>
<ul>
<li><a href="https://docs.npmjs.com/cli/config">npm config</a></li>
<li><a href="http://www.nano-editor.org/">nano</a></li>
</ul>
Drinking with npm (Bourbon and Neat)2015-03-17T14:41:19.982-00:00https://devin-clark.com/blog/drinking-with-npm-bourbon-and-neat/<p>Both <a href="http://bourbon.io/">Bourbon</a> and <a href="http://neat.bourbon.io/">Neat</a> are available on npm. This, along with <a href="https://github.com/sass/node-sass">node-sass</a>, has allowed me to remove Ruby from my development stack.</p>
<p>I'm sure at least a few of you are under the impression that npm is only for node modules. This is not true. jQuery has recently <a href="http://blog.npmjs.org/post/111475741445/publishing-your-jquery-plugin-to-npm-the-quick">given up on their plugin registry</a> in favor of npm. So, you can use npm for client-side code!</p>
<p>To start, let's delete Bourbon and Neat out of the <code>lib</code> directory (or wherever you are currently storing it). Next, we can <code>npm i bourbon bourbon-neat --save</code>.</p>
<p>Now you might think you can just <code>@import 'bourbon';</code> but there is one change we have to make to our sass compilation process. I am using <a href="https://github.com/sindresorhus/grunt-sass">grunt-sass</a> but these instructions should apply to any project using node-sass under the hood.</p>
<p>Node-sass has an option for <a href="https://github.com/sass/node-sass#includepaths">includePaths</a>. This option is an array of additional paths used to resolve an <code>@import</code>. We need to add two paths to this so we can import bourbon and neat.</p>
<p>At the time of writing, the grunt-sass config will look like this. It should be easy enough to do this with any of the other node-sass wrappers.</p>
<pre class="language-javascript"><code class="language-javascript">options<span class="token operator">:</span> <span class="token punctuation">{</span><br> includePaths<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">'node_modules/bourbon/app/assets/stylesheets'</span><span class="token punctuation">,</span> <span class="token string">'node_modules/bourbon-neat/app/assets/stylesheets'</span><span class="token punctuation">]</span><span class="token punctuation">;</span><br><span class="token punctuation">}</span></code></pre>
<p>This will allow you to <code>@import 'bourbon';</code> and <code>@import 'neat';</code>, and also enjoy <a href="http://semver.org/">semver</a>.</p>
<p>Have you also solved this problem in a different way? I would love to hear about it!</p>
Nebraska JS Conference 20152015-08-27T18:27:03.146-00:00https://devin-clark.com/blog/nebraska-js-conference-2015/<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p><a href="http://nejsconf.com/">NebraskaJS Conf</a> is a conference I had the pleasure of attending recently. It was held at the Omaha Henry Doorly Zoo, named the #1 Zoo in the World by TripAdvisor.</p>
<h2 id="responsive%2C-adaptive%2C-and-responsible-(codepo8)">Responsive, Adaptive, and Responsible (codepo8) <a class="direct-link" href="#responsive%2C-adaptive%2C-and-responsible-(codepo8)">#</a></h2>
<ul>
<li>Web design was never meant to be done in pixels</li>
<li>"Are we OK with building and discarding everything we do over and over again?"</li>
<li>"Why do we build things we don't use in production?"</li>
<li>The environment we work in flows like water, there is a constant need for new ideas.</li>
<li>"Best practices are found, not defined".</li>
<li>-220k +300k LOC</li>
<li>Every HTTP request is a terrible thing</li>
<li>"Most speed increases are based on analyzing and fixing developer mistakes/sloppiness"</li>
<li>"Everything in ES6 is a syntax error in older browsers."</li>
<li><a href="http://featuretests.io/">http://featuretests.io</a></li>
<li>Problems with transpiling:
<ul>
<li>You don't run or debug the code you write.</li>
<li>You are at the mercy of the transpiler to create efficient code.</li>
<li>Browsers that support ES6 will never get any [ES6 code].</li>
</ul>
</li>
<li><a href="http://kpdecker.github.io/six-speed/">http://kpdecker.github.io/six-speed/</a></li>
<li>We can't use ES6 safely in the browser.</li>
<li><a href="http://es6katas.org/">http://es6katas.org</a>
<ul>
<li>Learn es6 by viewing the ECMAScript unit test code</li>
</ul>
</li>
<li>Blaming the tool is a sign of a bad craftsman, good craftsmen improve the tools by feeding back to the tool maker.</li>
</ul>
<h2 id="streams-(pam-selle)">Streams (Pam Selle) <a class="direct-link" href="#streams-(pam-selle)">#</a></h2>
<ul>
<li><a href="http://pselle.github.io/omgstreams">Slides</a></li>
<li>Streams are the most awesome data structure you don't know enough about.</li>
<li>Comes from Unix</li>
<li>All glory to pipe</li>
<li>streams are delayed lists</li>
<li>Why?
<ul>
<li>Can't/Don't want to hold everything in memory.</li>
</ul>
</li>
<li>INFINITE DATA
<ul>
<li>WIZARDS</li>
</ul>
</li>
<li>Push and Pull Modes (flavors of streams)</li>
<li>Timeouts: 'Never ever block forever'</li>
<li>Node streams are push streams.</li>
<li>Generators!
<ul>
<li>Pull streams</li>
<li>ask for more when you want more (call next() on the generator)</li>
</ul>
</li>
<li>BaconJS
<ul>
<li>functional operators on events</li>
</ul>
</li>
<li>HighlandJS
<ul>
<li>single interface for many data types.
<ul>
<li>Arrays, Generators, Node streams, Events, Promises.</li>
<li>functional operations on these data types.</li>
</ul>
</li>
</ul>
</li>
<li>RxJS - Reactive programming</li>
<li>Trojan Horse for Reactive Programming.</li>
<li>PRESENTATION: <a href="https://www.youtube.com/watch?v=Agu6jipKfYw">Evan Czaplicki at Strangeloop</a></li>
<li>"Once you learn monads, you are unable to explain monads."</li>
<li>Intro to Rx by staltz.</li>
<li>Browser streams standard (worked on by the Node team).</li>
<li>Observable type proposal for es7
<ul>
<li>Native type</li>
</ul>
</li>
<li>Turing Incomplete <a href="http://turing.cool/">http://turing.cool</a>
<ul>
<li>Pam's Podcast</li>
</ul>
</li>
</ul>
<h2 id="custom-elements-(mike-macaulay)">Custom Elements (Mike Macaulay) <a class="direct-link" href="#custom-elements-(mike-macaulay)">#</a></h2>
<ul>
<li><a href="http://michaelmac.org/presentations/custom-elements/#/">Slides</a></li>
</ul>
<p>My Laptop died around here so notes became sparse (Phone typing...)</p>
<h2 id="architecting-communities-(amanda-harlin)">Architecting Communities (Amanda Harlin) <a class="direct-link" href="#architecting-communities-(amanda-harlin)">#</a></h2>
<ul>
<li><a href="https://docs.google.com/presentation/d/1Bfe4p0xzQNzqWF9-Mr7_gtstGo41v1lRfF0gUBd-W1U/pub?start=false&loop=false&delayms=60000&slide=id.p">Slides</a></li>
<li>Amanda spoke about the practices and tooling we have put in place to make <a href="http://techlahoma.org/">Techlahoma</a> Community successful.</li>
</ul>
<blockquote class="twitter-tweet" lang="en"><p lang="und" dir="ltr"><a href="https://twitter.com/amandaharlin">@amandaharlin</a> at <a href="https://twitter.com/hashtag/nejsconf?src=hash">#nejsconf</a> <a href="http://t.co/1KZs9bNQdi">pic.twitter.com/1KZs9bNQdi</a></p>— The Jessinator (@SeeJessicaCode) <a href="https://twitter.com/SeeJessicaCode/status/629722674390904832">August 7, 2015</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="und" dir="ltr"><a href="https://twitter.com/hashtag/nejsconf?src=hash">#nejsconf</a> <a href="http://t.co/QXzrIiEAGt">pic.twitter.com/QXzrIiEAGt</a></p>— Devin Clark (@iDevinClark) <a href="https://twitter.com/iDevinClark/status/629725935890100224">August 7, 2015</a></blockquote>
<h2 id="high-performance-in-the-critical-rendering-path-(%40ponyfoo)">High Performance in the Critical Rendering Path (@ponyfoo) <a class="direct-link" href="#high-performance-in-the-critical-rendering-path-(%40ponyfoo)">#</a></h2>
<ul>
<li>Slides: <a href="https://speakerdeck.com/bevacqua/high-performance-in-the-critical-path-nejsconf">High Performance in Critical Rendering Path</a></li>
</ul>
<h3 id="measuring">Measuring <a class="direct-link" href="#measuring">#</a></h3>
<ul>
<li>Devtools Audits</li>
<li>Measure early; Measure often.</li>
</ul>
<h3 id="perf">Perf <a class="direct-link" href="#perf">#</a></h3>
<ul>
<li>Optimize tcp</li>
<li>Gzip all text</li>
<li>Keep alive</li>
<li>Use nginx gzip. Everywhere. Now.</li>
<li>Defer font loading. Check <a href="https://speakerdeck.com/bevacqua/high-performance-in-the-critical-path-nejsconf?slide=41">slides for code</a>. Very cool.</li>
<li><a href="https://github.com/pocketjoso/penthouse">Penthouse</a> for critical path css</li>
<li>So many more tools in the slides.</li>
</ul>
<h2 id="universal-javascript-(bruce-coddington)">Universal JavaScript (Bruce Coddington) <a class="direct-link" href="#universal-javascript-(bruce-coddington)">#</a></h2>
<ul>
<li><a href="http://www.slideshare.net/BruceCoddington/reacting-to-the-isomorphic-buzz">Slides</a></li>
<li><a href="https://github.com/nicknisi/dotfiles/blob/master/vim/vimrc.symlink">Nick's vimrc file</a>
<ul>
<li>Still working on making my way through this...</li>
</ul>
</li>
<li>Server-side React</li>
</ul>
<blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">"I'm going to hurry up and finish my talk before they change things on me." <a href="https://twitter.com/BruceCoddington">@BruceCoddington</a> <a href="https://twitter.com/hashtag/nejsconf?src=hash">#nejsconf</a></p>— Dave Reid (@davereid) <a href="https://twitter.com/davereid/status/629714749656272900">August 7, 2015</a></blockquote>
<h2 id="lily">Lily <a class="direct-link" href="#lily">#</a></h2>
<p>Lily is a surprise speaker who spoke about how she is learning to code using <a href="https://bitsbox.com/">bitsbox.com</a>.</p>
<blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">Welcome our youngest speaker, Lily! <a href="https://twitter.com/LilyNEJSConf">@LilyNEJSConf</a> <a href="http://t.co/V2Q6OPOgvg">pic.twitter.com/V2Q6OPOgvg</a></p>— NEJS CONF 2015 (@nejsconf) <a href="https://twitter.com/nejsconf/status/629728970208972800">August 7, 2015</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">8 year old lily showing <a href="https://twitter.com/hashtag/nejsconf?src=hash">#nejsconf</a> the JS game she coded using <a href="https://twitter.com/BitsboxKids">@BitsboxKids</a>. Can't compete with that. I'm done. <a href="http://t.co/QPJpotXVGF">pic.twitter.com/QPJpotXVGF</a></p>— Christian Heilmann (@codepo8) <a href="https://twitter.com/codepo8/status/629729132285263872">August 7, 2015</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">Next speaker is Lilly who's going into the third grade. Presenting now on what's she's learned with JS. <a href="https://twitter.com/nejsconf">@nejsconf</a> <a href="http://t.co/3KCUAon30e">pic.twitter.com/3KCUAon30e</a></p>— amanda harlin (@amandaharlin) <a href="https://twitter.com/amandaharlin/status/629728527865098240">August 7, 2015</a></blockquote>
<h2 id="final-(read%3A-random)-thoughts">Final (Read: Random) Thoughts <a class="direct-link" href="#final-(read%3A-random)-thoughts">#</a></h2>
<blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">Drone group photo at <a href="https://twitter.com/hashtag/nejsconf?src=hash">#nejsconf</a>! <a href="https://t.co/4hiwkreB4q">https://t.co/4hiwkreB4q</a></p>— Matt Steele (@mattdsteele) <a href="https://twitter.com/mattdsteele/status/629880500090478593">August 8, 2015</a></blockquote>
<blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">Wildlife at <a href="https://twitter.com/hashtag/nejsconf?src=hash">#nejsconf</a> <a href="http://t.co/PJmlSvaw4S">pic.twitter.com/PJmlSvaw4S</a></p>— Ryan Stille (@RyanStille) <a href="https://twitter.com/RyanStille/status/629732235298541568">August 7, 2015</a></blockquote>
<p>Nope'd the hell out around this time. I did <em>almost</em> get to touch a shark though. That was pretty cool.</p>
<blockquote class="twitter-tweet" lang="en"><p lang="en" dir="ltr">How many other JS conferences can you pet a shark? Thats right, nowhere but <a href="https://twitter.com/hashtag/nejsconf?src=hash">#nejsconf</a> <a href="http://t.co/OteamIPnX6">pic.twitter.com/OteamIPnX6</a></p>— Justin Baker (@ezbakejustin) <a href="https://twitter.com/ezbakejustin/status/629681805780611072">August 7, 2015</a></blockquote>
<p><a href="https://thesuperbytes.bandcamp.com/">The SuperBytes</a> played at the afterparty. They are really good. 8-bit punk rock band.</p>
Creating Vagrant Boxes using Vagrant2015-09-02T21:41:00-00:00https://devin-clark.com/blog/creating-vagrant-boxes-using-vagrant/<p><a href="https://docs.vagrantup.com/v2/">Vagrant</a> is a huge pain in the ass (sometimes). Creating Vagrant boxes is more so (or so I thought).</p>
<p>A little bit of backstory. I started out using a tool called <a href="https://packer.io/">Packer</a> to build machine images. Packer has a post processor for Vagrant to export a Vagrant box. The most frustrating part for me was having to start from nothing, instead of starting from a base image.</p>
<p>So then I came across a <code>package</code> command in the Vagrant documentation. This command allows you to export a running box. I got the wild idea to create a <a href="https://docs.vagrantup.com/v2/vagrantfile/index.html">Vagrantfile</a> to build my Vagrant box. Using an existing base and shell provisioning gave me exactly what I needed.</p>
<p>First, we set the the box to be "ubuntu/trusty". You can set this to whatever box you want. This alone eliminates most of the work Packer had to do.</p>
<pre class="language-ruby"><code class="language-ruby">config<span class="token punctuation">.</span>vm<span class="token punctuation">.</span>box <span class="token operator">=</span> <span class="token string">"ubuntu/trusty"</span></code></pre>
<p>Next, we <a href="https://docs.vagrantup.com/v2/provisioning/shell.html">provision</a> the box with whatever we want to install. In my case, it is IO (Node), and a few global node modules. There are about a <a href="https://docs.vagrantup.com/v2/provisioning/index.html">dozen different provisioners available</a>. We are going to use inline shell because it is the simplest.</p>
<pre class="language-ruby"><code class="language-ruby">config<span class="token punctuation">.</span>vm<span class="token punctuation">.</span>provision <span class="token string">"shell"</span><span class="token punctuation">,</span> privileged<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> run<span class="token punctuation">:</span> <span class="token string">"once"</span><span class="token punctuation">,</span> inline<span class="token punctuation">:</span> <span class="token operator"><</span><span class="token operator"><</span><span class="token operator">-</span><span class="token constant">SHELL</span><br> <span class="token comment"># Install Node dependences</span><br> sudo apt<span class="token operator">-</span>get <span class="token operator">-</span>qy install build<span class="token operator">-</span>essential git wget curl<br> sudo apt<span class="token operator">-</span>get install <span class="token operator">-</span>y python<span class="token operator">-</span>software<span class="token operator">-</span>properties python g<span class="token operator">++</span> make<br><br> <span class="token comment"># Install Node</span><br> curl <span class="token operator">-</span>sL https<span class="token punctuation">:</span><span class="token operator">/</span><span class="token operator">/</span>deb<span class="token punctuation">.</span>nodesource<span class="token punctuation">.</span>com<span class="token operator">/</span>setup_iojs_2<span class="token punctuation">.</span>x <span class="token operator">|</span> sudo bash <span class="token operator">-</span><br> sudo apt<span class="token operator">-</span>get install <span class="token operator">-</span>y iojs<br><br> <span class="token comment"># Remove node install dependencies</span><br> sudo apt<span class="token operator">-</span>get purge <span class="token operator">-</span>y wget apt<span class="token operator">-</span>transport<span class="token operator">-</span>https software<span class="token operator">-</span>properties<span class="token operator">-</span>common python python<span class="token operator">-</span>software<span class="token operator">-</span>properties g<span class="token operator">++</span> make<br> sudo apt<span class="token operator">-</span>get autoremove <span class="token operator">-</span>y<br> sudo apt<span class="token operator">-</span>get clean all<br><br> <span class="token comment"># Install node modules</span><br> sudo npm install <span class="token operator">-</span>g pm2 grunt<span class="token operator">-</span>cli<br><br><span class="token constant">SHELL</span></code></pre>
<p>Now, we can create the machine by running <code>vagrant up</code> in the same directory as the Vagrantfile. If you aren't super familiar with Vagrant, I recommend you go through their <a href="https://docs.vagrantup.com/v2/getting-started/index.html">getting started tutorials</a>. After this finishes, we can run <code>vagrant package --output whatevs.box</code>. This command will package the machine we just created and provisioned into a Vagrant box.</p>
<p>You can upload that to a server, fax it, or whatever so the rest of you team can use it. We are currently storing these boxes in a Vagrant repository on our Artifactory server.</p>
<p>If you are on Windows and are having an issue relating to SSH timeouts, check out <a href="http://amiduos.com/support/knowledge-base/article/enabling-virtualization-in-lenovo-systems">this article</a> on enabling virtualization in BIOS.</p>
<p>Here is my full Vagrantfile.</p>
<pre class="language-ruby"><code class="language-ruby"><span class="token constant">Vagrant</span><span class="token punctuation">.</span>configure<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token keyword">do</span> <span class="token operator">|</span>config<span class="token operator">|</span><br> config<span class="token punctuation">.</span>vm<span class="token punctuation">.</span>box <span class="token operator">=</span> <span class="token string">"ubuntu/trusty"</span><br><br> config<span class="token punctuation">.</span>vm<span class="token punctuation">.</span>provision <span class="token string">"shell"</span><span class="token punctuation">,</span> privileged<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">,</span> run<span class="token punctuation">:</span> <span class="token string">"once"</span><span class="token punctuation">,</span> inline<span class="token punctuation">:</span> <span class="token operator"><</span><span class="token operator"><</span><span class="token operator">-</span><span class="token constant">SHELL</span><br> sudo apt<span class="token operator">-</span>get <span class="token operator">-</span>qy install build<span class="token operator">-</span>essential git wget curl<br> sudo apt<span class="token operator">-</span>get install <span class="token operator">-</span>y python<span class="token operator">-</span>software<span class="token operator">-</span>properties python g<span class="token operator">++</span> make<br><br> curl <span class="token operator">-</span>sL https<span class="token punctuation">:</span><span class="token operator">/</span><span class="token operator">/</span>deb<span class="token punctuation">.</span>nodesource<span class="token punctuation">.</span>com<span class="token operator">/</span>setup_iojs_2<span class="token punctuation">.</span>x <span class="token operator">|</span> sudo bash <span class="token operator">-</span><br> sudo apt<span class="token operator">-</span>get install <span class="token operator">-</span>y iojs<br><br> sudo apt<span class="token operator">-</span>get purge <span class="token operator">-</span>y wget apt<span class="token operator">-</span>transport<span class="token operator">-</span>https software<span class="token operator">-</span>properties<span class="token operator">-</span>common python python<span class="token operator">-</span>software<span class="token operator">-</span>properties g<span class="token operator">++</span> make<br> sudo apt<span class="token operator">-</span>get autoremove <span class="token operator">-</span>y<br> sudo apt<span class="token operator">-</span>get clean all<br><br> sudo npm install <span class="token operator">-</span>g pm2 grunt<span class="token operator">-</span>cli<br><br> <span class="token constant">SHELL</span><br><span class="token keyword">end</span></code></pre>
Testing React Components with Enzyme2016-03-28T21:44:31.161-00:00https://devin-clark.com/blog/testing-react-components-enzyme/<p>We finally boarded the React train and it is great. I looked at <a href="https://github.com/airbnb/enzyme">Enzyme</a> and <a href="https://facebook.github.io/jest/">Jest</a>. Enzyme seems a lot easier to use so I chose it. I am impressed with how it turned out.</p>
<p>For this workflow, you will need to install these packages.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> <span class="token function">install</span> enzyme babel-register babel-preset-react chai mocha react-addons-test-utils --save-dev</code></pre>
<p>This is the relevant part of the <code>package.json</code> file. The first argument to the <code>mocha</code> command is a setup file for mocha. The second is a glob for all the test files. I am using an npm script for this but use whatever.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token string">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span><br> <span class="token string">"test"</span><span class="token operator">:</span> <span class="token string">"mocha website/test/.setup.js website/test/**/*-test.js"</span><br><span class="token punctuation">}</span></code></pre>
<p>Here is the <code>.setup.js</code> file. It adds <code>babel-register</code> with the react preset. This allows JSX to work in the tests.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'babel-register'</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">{</span><br> presets<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">'react'</span><span class="token punctuation">]</span><span class="token punctuation">,</span><br><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Here we have a small stateless react component that we are going to test. Stateless React components are pure functions without internal state or lifecycle methods. You should use these anywhere you are not using state or any of the component lifecycle methods. Pure functions are easier to test. Given the same input, a pure function always return the same output.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">var</span> React <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'react'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><br><span class="token keyword">function</span> <span class="token function">Burrito</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token string">'use strict'</span><span class="token punctuation">;</span><br><br> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token operator"><</span>div className<span class="token operator">=</span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>name<span class="token punctuation">}</span><span class="token operator">></span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>ingredients <span class="token operator">&&</span> props<span class="token punctuation">.</span>ingredients<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">', '</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token punctuation">}</span><br><br>Burrito<span class="token punctuation">.</span>defaultProps <span class="token operator">=</span> <span class="token punctuation">{</span><br> name<span class="token operator">:</span> <span class="token string">'burrito'</span><br> ingredients<span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><br><span class="token punctuation">}</span><span class="token punctuation">;</span><br><br>Burrito<span class="token punctuation">.</span>propTypes <span class="token operator">=</span> <span class="token punctuation">{</span><br> name<span class="token operator">:</span> React<span class="token punctuation">.</span>PropTypes<span class="token punctuation">.</span>string<span class="token punctuation">,</span><br> ingredients<span class="token operator">:</span> React<span class="token punctuation">.</span>PropTypes<span class="token punctuation">.</span>array<br><span class="token punctuation">}</span><span class="token punctuation">;</span><br><br>module<span class="token punctuation">.</span>exports <span class="token operator">=</span> Burrito<span class="token punctuation">;</span></code></pre>
<p>Now, let's test this component. Enzyme allows us to <a href="http://airbnb.io/enzyme/docs/api/shallow.html">shallow render a component</a>, then exposes an API to get and set data on the rendered component. My favorite part is it doesn't use PhantomJS. We are going to use <code>.text()</code> and <code>.hasClass(classname)</code> in this example.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">var</span> wrapper <span class="token operator">=</span> enzyme<span class="token punctuation">.</span><span class="token function">shallow</span><span class="token punctuation">(</span><span class="token operator"><</span>Burrito <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token function">expect</span><span class="token punctuation">(</span>wrapper<span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>to<span class="token punctuation">.</span><span class="token function">equal</span><span class="token punctuation">(</span><span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>We did it! In this test, we <a href="http://airbnb.io/enzyme/docs/api/shallow.html">shallow render</a> our Burrito component, then we <code>expect</code> (a <a href="http://chaijs.com/">chai</a> function) the text of the rendered component to be empty.</p>
<p>We can also do something similar with <code>hasClass</code>.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">var</span> wrapper <span class="token operator">=</span> enzyme<span class="token punctuation">.</span><span class="token function">shallow</span><span class="token punctuation">(</span><span class="token operator"><</span>Burrito <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token function">expect</span><span class="token punctuation">(</span>wrapper<span class="token punctuation">.</span><span class="token function">hasClass</span><span class="token punctuation">(</span><span class="token string">'burrito'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>to<span class="token punctuation">.</span><span class="token function">equal</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Here is a full example for testing the Burrito component we created.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">var</span> React <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'react'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token keyword">var</span> expect <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'chai'</span><span class="token punctuation">)</span><span class="token punctuation">.</span>expect<span class="token punctuation">;</span><br><span class="token keyword">var</span> enzyme <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'enzyme'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token keyword">var</span> Burrito <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'../js/components/Burrito'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><br><span class="token function">describe</span><span class="token punctuation">(</span><span class="token string">'<Burrito />'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token string">'use strict'</span><span class="token punctuation">;</span><br><br> <span class="token function">describe</span><span class="token punctuation">(</span><span class="token string">'Text: '</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token function">it</span><span class="token punctuation">(</span><span class="token string">'renders no text with no props'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token keyword">var</span> wrapper <span class="token operator">=</span> enzyme<span class="token punctuation">.</span><span class="token function">shallow</span><span class="token punctuation">(</span><span class="token operator"><</span>Burrito <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token function">expect</span><span class="token punctuation">(</span>wrapper<span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>to<span class="token punctuation">.</span><span class="token function">equal</span><span class="token punctuation">(</span><span class="token string">''</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><br> <span class="token function">it</span><span class="token punctuation">(</span><span class="token string">'renders no text with no props'</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token keyword">var</span> wrapper <span class="token operator">=</span> enzyme<span class="token punctuation">.</span><span class="token function">shallow</span><span class="token punctuation">(</span><span class="token operator"><</span>Burrito ingredients<span class="token operator">=</span><span class="token punctuation">{</span><span class="token punctuation">[</span><span class="token string">'chicken'</span><span class="token punctuation">,</span> <span class="token string">'beans'</span><span class="token punctuation">]</span><span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token function">expect</span><span class="token punctuation">(</span>wrapper<span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>to<span class="token punctuation">.</span><span class="token function">equal</span><span class="token punctuation">(</span><span class="token string">'chicken, beans'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><br> <span class="token function">describe</span><span class="token punctuation">(</span><span class="token string">'Name: '</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token function">it</span><span class="token punctuation">(</span><span class="token string">"is named 'burrito' with no props"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token keyword">var</span> wrapper <span class="token operator">=</span> enzyme<span class="token punctuation">.</span><span class="token function">shallow</span><span class="token punctuation">(</span><span class="token operator"><</span>Burrito <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token function">expect</span><span class="token punctuation">(</span>wrapper<span class="token punctuation">.</span><span class="token function">hasClass</span><span class="token punctuation">(</span><span class="token string">'burrito'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>to<span class="token punctuation">.</span><span class="token function">equal</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><br> <span class="token function">it</span><span class="token punctuation">(</span><span class="token string">"is named 'the-james-mason' with 'the-james-mason' passed as name"</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token keyword">var</span> wrapper <span class="token operator">=</span> enzyme<span class="token punctuation">.</span><span class="token function">shallow</span><span class="token punctuation">(</span><span class="token operator"><</span>Burrito name<span class="token operator">=</span><span class="token string">"the-james-mason"</span> <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token function">expect</span><span class="token punctuation">(</span>wrapper<span class="token punctuation">.</span><span class="token function">hasClass</span><span class="token punctuation">(</span><span class="token string">'the-james-mason'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>to<span class="token punctuation">.</span><span class="token function">equal</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Test coverage is another cool thing I did. I used <a href="https://github.com/bcoe/nyc">nyc</a> to generate a coverage report after the tests run. The coverage report shows you what percentage of each file's statements, branches, and functions are tested. To run nyc, you can change the mocha npm script to look the code below.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token string">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span><br> <span class="token string">"test"</span><span class="token operator">:</span> <span class="token string">"nyc mocha website/test/.setup.js website/test/**/*-test.js"</span><br><span class="token punctuation">}</span></code></pre>
<p>It seems a bit magical to me but it did help me uncover missing paths in my tests.</p>
<p>Writing tests like these for all your components gives an incredible peace of mind. Generating test coverage will help ensure we are testing everything. I may try <a href="https://github.com/sindresorhus/ava">Ava</a> instead of Mocha in the future.</p>
A Simple Build Process for React and JSX2016-06-28T19:00:39.900-00:00https://devin-clark.com/blog/simple-react-jsx-build-process/<p>Unfortunately, build processes are a big part of JavaScript development. Build processes do not have to be complicated, despite what you may have heard. Let's jump in with my default for building React and JSX projects. I say "default" because if the project gets complicated I will move to using Gulp. An example of a more complicated project is one with multiple entry points.</p>
<p>Previously, I used the <a href="https://github.com/andreypopp/reactify">reactify transform</a> but it has been deprecated in favor of <a href="https://github.com/babel/babelify">babelify</a>. We will use babelify.</p>
<p>First, we install these packages.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> <span class="token function">install</span> browserify watchify babelify babel-preset-react --save-dev</code></pre>
<p>Next, we add some configuration to our <code>package.json</code> file.</p>
<pre class="language-js"><code class="language-js"><span class="token string">"browserify"</span><span class="token operator">:</span> <span class="token punctuation">{</span><br> <span class="token string">"transform"</span><span class="token operator">:</span> <span class="token punctuation">[</span><br> <span class="token punctuation">[</span><br> <span class="token string">"babelify"</span><span class="token punctuation">,</span><br> <span class="token punctuation">{</span><br> <span class="token string">"presets"</span><span class="token operator">:</span> <span class="token punctuation">[</span><br> <span class="token string">"react"</span><br> <span class="token punctuation">]</span><br> <span class="token punctuation">}</span><br> <span class="token punctuation">]</span><br> <span class="token punctuation">]</span><br><span class="token punctuation">}</span><span class="token punctuation">,</span></code></pre>
<p>Here we are configuring browserify to use the <a href="https://github.com/babel/babelify">babelify transform</a> and using <a href="https://www.npmjs.com/package/babel-preset-react">babel-preset-react</a> to handle the JSX part.</p>
<p>Finally, we need to add some npm scripts so we can run this.</p>
<pre class="language-js"><code class="language-js"><span class="token string">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span><br> <span class="token string">"build"</span><span class="token operator">:</span> <span class="token string">"browserify index.js -o bundle.js"</span><span class="token punctuation">,</span><br> <span class="token string">"watch"</span><span class="token operator">:</span> <span class="token string">"watchify index.js -vo bundle.js"</span><br><span class="token punctuation">}</span><span class="token punctuation">,</span></code></pre>
<p>Now we are able to run <code>npm run watch</code> and <code>npm run build</code>. Watch will watch our files and run browserify on change. We use this while working. Build will run browserify. This is really only used by our build server.</p>
Deep Objects in Lodash2016-10-17T00:51:49.230-00:00https://devin-clark.com/blog/deep-objects-lodash/<p>A quick introduction to two Lodash methods I found recently, <code>_.get</code> and <code>_.set</code>, to help work with deeply nested objects.</p>
<p>Let's say I have this object and I want to get the name.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token punctuation">{</span><br> b<span class="token operator">:</span> <span class="token punctuation">[</span><br> <span class="token punctuation">{</span><br> c<span class="token operator">:</span> <span class="token punctuation">{</span><br> name<span class="token operator">:</span> <span class="token string">'Arya'</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> <span class="token punctuation">]</span><span class="token punctuation">,</span><br><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre>
<p>Normally, we would be able to do <code>a.b[0].c.name</code> but what if one of the values turned out to be null? This is common when we are waiting for data from an HTTP request or another source. We usually solve this by constructing this big mess that checks for falsy values at each step.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">var</span> name <span class="token operator">=</span> a <span class="token operator">&&</span> a<span class="token punctuation">.</span>b <span class="token operator">&&</span> a<span class="token punctuation">.</span>b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span> <span class="token operator">&&</span> a<span class="token punctuation">.</span>b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>c <span class="token operator">&&</span> a<span class="token punctuation">.</span>b<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>c<span class="token punctuation">.</span>name<span class="token punctuation">;</span><br><span class="token comment">// => 'Arya'</span></code></pre>
<p>Let's clean this up using Lodash's <code>get</code> method.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">var</span> name <span class="token operator">=</span> _<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token string">'b[0].c.name'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token comment">// => 'Arya'</span></code></pre>
<p>We can also provide a default value as the third argument.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">var</span> name <span class="token operator">=</span> _<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token string">'b[0].c.name'</span><span class="token punctuation">,</span> <span class="token string">'A girl has no name'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token comment">// => 'Arya'</span><br><br><span class="token keyword">var</span> name <span class="token operator">=</span> _<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token string">'b[1].c.name'</span><span class="token punctuation">,</span> <span class="token string">'A girl has no name'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token comment">// => 'A girl has no name'</span></code></pre>
<p>I really like how much this cleans up the code.</p>
<p>We can also generate the object using <code>_.set</code>.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span><br><br>_<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> <span class="token string">'b[0].c.name'</span><span class="token punctuation">,</span> <span class="token string">'Arya'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token comment">// => {b: [{c: {name: 'Arya'}}]}</span></code></pre>
<p>It is important to note that <code>_.set</code> mutates the passed object. To solve this, I would do something like this.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">var</span> a <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span><br><br><span class="token keyword">var</span> new_a <span class="token operator">=</span> _<span class="token punctuation">.</span><span class="token function">set</span><span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">assign</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">,</span> a<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">'b[0].c.name'</span><span class="token punctuation">,</span> <span class="token string">'Arya'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token comment">// => {b: [{c: {name: 'Arya'}}]}</span></code></pre>
<p>To read more about these methods, check out the documentation for <a href="https://lodash.com/docs/4.16.4#get">get</a> and <a href="https://lodash.com/docs/4.16.4#set">set</a>.</p>
Use Fetch2016-11-30T18:36:13.673-00:00https://devin-clark.com/blog/use-fetch/<p>How do <strong>you</strong> make an HTTP request in JavaScript? Do you pull in jQuery? Write your own XMLHttpRequest? There's a better way.</p>
<p>Enter <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API">fetch</a>.</p>
<pre class="language-js"><code class="language-js"><span class="token keyword">function</span> <span class="token function">toJSON</span><span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token keyword">return</span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token punctuation">}</span><br><br>window<br> <span class="token punctuation">.</span><span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">'http://catfacts-api.appspot.com/api/facts'</span><span class="token punctuation">)</span><br> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>toJSON<span class="token punctuation">)</span><br> <span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">response</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>response<span class="token punctuation">)</span><span class="token punctuation">;</span><br> <span class="token comment">// => {facts: ["Cat families usually play best in even numbers. Cats and kittens should be acquired in pairs whenever possible."], success: "true"}</span><br> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>This code will make a GET request to the catfacts API, parse the response as JSON, and log out the response to the console.</p>
<p>The bad news is support isn't super amazing with <a href="http://caniuse.com/#search=fetch">some browsers</a> (as of November 2016). The good news is there are a handful of polyfills. <a href="https://github.com/github/fetch">whatwg-fetch by Github</a> is a great one and it is a lot smaller than jQuery (and probably smaller than your XMLHttpRequest wrapper if it is feature-complete).</p>
<p>You can also use this in Node (and we do at <a href="http://wdtinc.com/">WDT</a>) using <a href="https://github.com/matthew-andrews/isomorphic-fetch">isomorphic-fetch</a>.</p>
<p>The things I love about <code>fetch</code> is that it has the API of a lot of the ajax wrappers out there.</p>
Virtualized Rendering in React2017-11-27T09:32:00-00:00https://devin-clark.com/blog/virtualized-rendering-in-react/<p>Virtual rendering (also known as virtualized rendering, windowing, and a number of other terms) is a method of only rendering the elements that need to be rendered to the DOM.</p>
<p>A common example of this is a list of a million items but only ten are visible at any time. Rendering the entire list would be incredibly inefficient, and slow, but rendering 10 to 15 items at a time and more as you scroll makes things much faster.</p>
<p>If your growth-driven startup has any chance of scaling, this is very important to consider.</p>
<p>There are a handful of existing libraries that you can use to render in this way. <a href="https://github.com/bvaughn/react-virtualized">React Virtualized</a> is my favorite. It also includes support for grids, tables, infinite scrolling, and even 'masonry-style' layouts.</p>
<p>If you are a VC-funded growth-driven startup, you probably don't want to use a library. You have the resources, the drive, and the overwhelming need to invent your own. Using a library is really more for bootstrap growth-driven startups.</p>
<p>Here is a quick implementation of a list, using React Virtualized. You can view this <a href="https://codesandbox.io/s/ykmnl65nlz">demo on Code Sandbox</a>.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">{</span> render <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-dom'</span><span class="token punctuation">;</span><br><span class="token keyword">import</span> React <span class="token keyword">from</span> <span class="token string">'react'</span><span class="token punctuation">;</span><br><span class="token keyword">import</span> <span class="token punctuation">{</span> List <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'react-virtualized'</span><span class="token punctuation">;</span><br><br><span class="token comment">// Generate a big list.</span><br><span class="token comment">// Ignore the man behind the curtain.</span><br><span class="token keyword">const</span> list <span class="token operator">=</span> Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span><span class="token punctuation">{</span> length<span class="token operator">:</span> <span class="token number">100000</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token parameter">v<span class="token punctuation">,</span> i</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token keyword">return</span> i<span class="token punctuation">;</span><br><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br><br><span class="token comment">// Generate each row</span><br><span class="token keyword">function</span> <span class="token function">rowRenderer</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> key<span class="token punctuation">,</span> index<span class="token punctuation">,</span> style <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token keyword">return</span> <span class="token punctuation">(</span><br> <span class="token operator"><</span>div key<span class="token operator">=</span><span class="token punctuation">{</span>key<span class="token punctuation">}</span> style<span class="token operator">=</span><span class="token punctuation">{</span>style<span class="token punctuation">}</span><span class="token operator">></span><br> Disruption Idea #<span class="token punctuation">{</span>list<span class="token punctuation">[</span>index<span class="token punctuation">]</span><span class="token punctuation">}</span><br> <span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span><br> <span class="token punctuation">)</span><span class="token punctuation">;</span><br><span class="token punctuation">}</span><br><br><span class="token comment">// Render our list</span><br><span class="token function">render</span><span class="token punctuation">(</span><br> <span class="token operator"><</span>List width<span class="token operator">=</span><span class="token punctuation">{</span><span class="token number">220</span><span class="token punctuation">}</span> height<span class="token operator">=</span><span class="token punctuation">{</span><span class="token number">400</span><span class="token punctuation">}</span> rowCount<span class="token operator">=</span><span class="token punctuation">{</span>list<span class="token punctuation">.</span>length<span class="token punctuation">}</span> rowHeight<span class="token operator">=</span><span class="token punctuation">{</span><span class="token number">30</span><span class="token punctuation">}</span> rowRenderer<span class="token operator">=</span><span class="token punctuation">{</span>rowRenderer<span class="token punctuation">}</span> <span class="token operator">/</span><span class="token operator">></span><span class="token punctuation">,</span><br> document<span class="token punctuation">.</span><span class="token function">getElementById</span><span class="token punctuation">(</span><span class="token string">'root'</span><span class="token punctuation">)</span><br><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>In a later post, we are going follow in the footsteps of a VC-funded growth-driven startup and build our own basic version of a virtual list.</p>
Slimmer Code Reviews with Husky2018-03-15T17:53:25.680-00:00https://devin-clark.com/blog/husky-githooks/<p><a href="https://github.com/typicode/husky">Husky</a> is a simple tool for configuring Git hooks in a project. It really shines when you need to easily configure Git hooks for a project across a team. That is what we are going to do today.</p>
<p>First, we need to add a script to our <code>package.json</code> file. We already have an existing command for eslint configured (<code>npm run lint</code>), so all we need to do to get Husky configured is add a <code>prepush</code> script that runs the lint script.</p>
<pre class="language-json"><code class="language-json"><span class="token punctuation">{</span><br> …<br> <span class="token property">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span><br> <span class="token property">"lint"</span><span class="token operator">:</span> <span class="token string">"gulp lint"</span><span class="token punctuation">,</span><br> <span class="token property">"prepush"</span><span class="token operator">:</span> <span class="token string">"npm run lint"</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> …<br><span class="token punctuation">}</span></code></pre>
<p>Next, we can install husky into our project using the following command.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> <span class="token function">install</span> husky --save-dev</code></pre>
<p>It might seem like we should have done this first but Husky itself works by using an <code>npm install</code> lifecycle hook that fires after <code>npm install</code> is run. This means the husky setup we just did will take effect now.</p>
<p>Now you can commit and push these changes. You will see that it runs the linting script before the push runs. If the linting script fails, the push will not happen.</p>
<p>There is another tool called <a href="https://github.com/okonet/lint-staged">lint-staged</a> that will run a given script only on staged files in Git. This is great if want if you are trying to slowly roll linting into a project and taking things a file at a time. It is not a replacement for Husky. It is really more of an enhancement to Husky. We can go over lint-staged in more detail in a later article.</p>
JavaScript Styling with Feeling2018-05-11T09:32:00-00:00https://devin-clark.com/blog/js-with-feeling/<p>This is a quick introduction to how I did CSS-in-JS on a recent project using <a href="https://emotion.sh/">Emotion</a> and <a href="https://preactjs.com/">Preact</a>.</p>
<p>To start, I need to install emotion and a Babel plugin. The Babel plugin generates source maps and optimizes style output. Emotion highly recommends this for production use.</p>
<pre class="language-bash"><code class="language-bash"><span class="token function">npm</span> <span class="token function">install</span> --save emotion<br><span class="token function">npm</span> <span class="token function">install</span> --save-dev babel-plugin-emotion</code></pre>
<p>Create a .babelrc file (or add the emotion parts to my existing babelrc file). Source maps will add a lot of weight to my bundle, so I am disabling them in production.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token punctuation">{</span><br> <span class="token string">"env"</span><span class="token operator">:</span> <span class="token punctuation">{</span><br> <span class="token string">"production"</span><span class="token operator">:</span> <span class="token punctuation">{</span><br> <span class="token string">"plugins"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">"emotion"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token string">"sourceMap"</span><span class="token operator">:</span> <span class="token boolean">false</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">]</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> <span class="token string">"development"</span><span class="token operator">:</span> <span class="token punctuation">{</span><br> <span class="token string">"plugins"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token string">"emotion"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token string">"sourceMap"</span><span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span><span class="token punctuation">]</span><span class="token punctuation">]</span><br> <span class="token punctuation">}</span><br> <span class="token punctuation">}</span><br><span class="token punctuation">}</span></code></pre>
<p>Now, I can start making components. I've made a basic component to define a section with padding on the bottom. I prefer defining the styles as objects instead of template tags. It feels more natural in JavaScript to me. I wrap all the styles in a styles object. The individual items in the style object are wrapped in emotion's css function.</p>
<pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> <span class="token punctuation">{</span> css <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'emotion'</span><span class="token punctuation">;</span><br><span class="token keyword">import</span> <span class="token punctuation">{</span> h <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'preact'</span><span class="token punctuation">;</span><br><span class="token keyword">import</span> <span class="token punctuation">{</span> <span class="token constant">GRID_UNIT</span> <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'../constants/layout'</span><span class="token punctuation">;</span><br><br><span class="token keyword">const</span> styles <span class="token operator">=</span> <span class="token punctuation">{</span><br> container<span class="token operator">:</span> <span class="token function">css</span><span class="token punctuation">(</span><span class="token punctuation">{</span><br> paddingBottom<span class="token operator">:</span> <span class="token constant">GRID_UNIT</span> <span class="token operator">*</span> <span class="token number">5</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br><span class="token punctuation">}</span><span class="token punctuation">;</span><br><br><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">Section</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>section</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>styles<span class="token punctuation">.</span>container<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>children<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>section</span><span class="token punctuation">></span></span><span class="token punctuation">;</span><br><span class="token punctuation">}</span></code></pre>
<p><code>GRID_UNIT</code> is a constant I have defined with a value of 8. I make all my dimensions, margins, and padding a multiple of this number. Because of this I am able to get a very uniform interface without much effort.</p>
<p>To use the styles, I just pass the style I want to className. If I need to do any kind of composition I can use <code>cx</code> from emotion and pass an array of styles that are merged together. <code>cx</code> uses the <a href="https://github.com/JedWatson/classnames">classnames API</a>.</p>
<pre class="language-jsx"><code class="language-jsx"><span class="token keyword">import</span> <span class="token punctuation">{</span> css<span class="token punctuation">,</span> cx <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'emotion'</span><span class="token punctuation">;</span><br><span class="token keyword">import</span> <span class="token punctuation">{</span> h <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'preact'</span><span class="token punctuation">;</span><br><span class="token keyword">import</span> <span class="token punctuation">{</span> <span class="token constant">GRID_UNIT</span> <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'../constants/layout'</span><span class="token punctuation">;</span><br><br><span class="token keyword">const</span> styles <span class="token operator">=</span> <span class="token punctuation">{</span><br> container<span class="token operator">:</span> <span class="token function">css</span><span class="token punctuation">(</span><span class="token punctuation">{</span><br> fontSize<span class="token operator">:</span> <span class="token number">20</span><span class="token punctuation">,</span><br> paddingBottom<span class="token operator">:</span> <span class="token constant">GRID_UNIT</span> <span class="token operator">*</span> <span class="token number">3</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br><span class="token punctuation">}</span><span class="token punctuation">;</span><br><br><span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">SectionHeading</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br> <span class="token keyword">return</span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>h2</span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span><span class="token function">cx</span><span class="token punctuation">(</span>styles<span class="token punctuation">.</span>container<span class="token punctuation">,</span> props<span class="token punctuation">.</span>className<span class="token punctuation">)</span><span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token punctuation">{</span>props<span class="token punctuation">.</span>children<span class="token punctuation">}</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>h2</span><span class="token punctuation">></span></span><span class="token punctuation">;</span><br><span class="token punctuation">}</span></code></pre>
<p>By passing <code>props.className</code> to <code>cx</code> I can override the default styles.</p>
<pre class="language-jsx"><code class="language-jsx"><span class="token keyword">const</span> styles <span class="token operator">=</span> <span class="token punctuation">{</span><br> specialHeading<span class="token operator">:</span> <span class="token function">css</span><span class="token punctuation">(</span><span class="token punctuation">{</span><br> fontSize<span class="token operator">:</span> <span class="token number">22</span><span class="token punctuation">,</span><br> color<span class="token operator">:</span> <span class="token string">'blue'</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br><span class="token punctuation">}</span><span class="token punctuation">;</span><br><br><span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token class-name">SectionHeading</span></span> <span class="token attr-name">className</span><span class="token script language-javascript"><span class="token script-punctuation punctuation">=</span><span class="token punctuation">{</span>styles<span class="token punctuation">.</span>specialHeading<span class="token punctuation">}</span></span><span class="token punctuation">></span></span><span class="token plain-text">Very Special Heading</span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span><span class="token class-name">SectionHeading</span></span><span class="token punctuation">></span></span><span class="token punctuation">;</span></code></pre>
<p>Next, I use <code>injectGlobal</code> to do a simple CSS reset.</p>
<pre class="language-javascript"><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">{</span> injectGlobal <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'emotion'</span><span class="token punctuation">;</span><br><br><span class="token function">injectGlobal</span><span class="token punctuation">(</span><span class="token punctuation">{</span><br> html<span class="token operator">:</span> <span class="token punctuation">{</span><br> boxSizing<span class="token operator">:</span> <span class="token string">'border-box'</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br><br> <span class="token string">'*'</span><span class="token operator">:</span> <span class="token punctuation">{</span><br> boxSizing<span class="token operator">:</span> <span class="token string">'inherit'</span><span class="token punctuation">,</span><br> margin<span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span><br> padding<span class="token operator">:</span> <span class="token number">0</span><span class="token punctuation">,</span><br><br> <span class="token string">':before'</span><span class="token operator">:</span> <span class="token punctuation">{</span><br> boxSizing<span class="token operator">:</span> <span class="token string">'inherit'</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br><br> <span class="token string">':after'</span><span class="token operator">:</span> <span class="token punctuation">{</span><br> boxSizing<span class="token operator">:</span> <span class="token string">'inherit'</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br> <span class="token punctuation">}</span><span class="token punctuation">,</span><br><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>Being able to snapshot test the styles using jest-emotion is a big plus for me too. You can read more about that on the <a href="https://emotion.sh/docs/jest-emotion">Emotion docs</a>.</p>
Knex and Postgres2020-07-02T00:00:00-00:00https://magistratehq.com/blog/knexjs-postgres/An introduction to using Knex.js and Postgres originally appearing on Magistrate's blog.Gravatars and Postgres 12 using Generated Columns2020-07-08T00:00:00-00:00https://www.magistratehq.com/blog/generated-columns-postgres/A quick look at an interesting use case for generated columns in Postgres originally appearing on Magistrate's blog.Case-Insensitive Text Columns in Postgres with citext2020-08-15T00:00:00-00:00https://www.magistratehq.com/blog/citext-extension/A dive into Postgres' citext extension originally appearing on Magistrate's blog.Storing Timezones in Postgres2020-10-01T00:00:00-00:00https://www.magistratehq.com/blog/user-timezones-in-postgres/A quick tip on storing a user's timezone in Postgres using build-in utilities originally appearing on Magistrate's blog.Set Postgres System Timezone2020-10-20T00:00:00-00:00https://www.magistratehq.com/blog/set-postgres-system-timezone/A quick guide on how to set Postgres system timezone in a way that works across restarts originally appearing on Magistrate's blog.