A Simple .htaccess Recipe for HTTPS Redirect + HSTS

I like to get at least one blog post in a year — this one is coming in just under the wire!

One of the phone screen questions I like to ask junior frontend candidates (and occasionally more experienced frontend candidates) is:

Imagine you’re creating a website that doesn’t have any login capabilities, shopping carts, or anything other than static articles. Would you go to the effort of setting up HTTPS? Why or why not?”

The answers I’m hoping to hear are along the lines of, “to make sure that people are actually connecting to your site,” or “to prevent a man-in-the-middle from tampering with your site.” Which then sometimes leads into an interesting discussion about TLS and what the candidate understands about networking.

Important stuff! Which makes it at least a little bit embarrassing to admit that it was only this year that I got around to adding proper HTTPS with redirects to my own website. Now, at least, I can ask my interview question without feeling like a giant hypocrite.

To make this post more about utility and less about self-flagellation, here’s the configuration I used. I’m on an old shared host, so this configuration is oriented towards people like myself, who are stuck hand-editing .htaccess files like a peasant. Interestingly, when you search for “redirect HTTP to HTTPS”, there aren’t actually that many pages that cover HTTPS redirects and HSTS in the same place, so perhaps this will be useful to somebody:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

<IfModule mod_headers.c>
Header set Strict-Transport-Security "max-age=31536000; includeSubdomains;"
</IfModule>

Notes:

  • If you’re not on a shared host and forced to use .htaccess, the Apache documentation recommends using Redirect instead mod_rewrite.
  • The Strict-Transport-Security heading should be set only for HTTPS traffic. In this case, we’re in the clear because Header set applies to normal 2xx responses. If I had used Header always set, this would also set the heading on 3xx responses, which would be incorrect.
  • I haven’t configured HSTS preload yet, but you might consider doing that.
Posted in Web

JavaScript Tooling and Orders of Magnitude

I was listening to a dev podcast recently (prooobably Front End Happy Hour, but don’t quote me on that). One of the hosts mentioned that they give out a take-home problem for candidates. The take-home problem was supposed to take several hours, but some candidates managed to burn up most of their time setting up their build toolchain instead of solving the problem.

This got me thinking about engineering judgment. How do you ensure that the time you invest in tooling pays off over the lifetime of the project? For me, it helps to think about introducing frontend tooling and infrastructure based on the size of the codebase:

1-10 lines of code: An ad-hoc script. No tooling. The script is probably inlined into the page. If there are any dependencies (probably not), the script accesses these as globals on window.

10-100 lines of code: A single script file. Still no tooling, other than the linter built into your editor. The script resides in a single unminified file, to be included using a single <script src>. Dependencies are still globals. The project could have:

  • some dependencies, still implemented as globals
  • a number of functions and objects, but all implemented in the same file, perhaps wrapped in an IIFE

100-1000 lines of code: A modular project. This is a major break point. Using a JavaScript framework is still overkill (unless the project is a framework-specific component or library), but the project likely consists of multiple files, and pulls in significant dependencies. Unit tests are a must. The project could have:

  • dependencies defined in a lock file
  • a straightforward build script that bundles the code from a single entrypoint and runs the results through a minifier
  • source maps
  • unit tests
  • a watch script to (at least) run the unit tests

A generator tool could be useful here to bootstrap the project. However, the generator tool should not assume a JavaScript framework. (I like create-react-app, but I would use it at the next stage, not here.)

1000-10000 lines of code: A real-life web application. The application is now large enough to get mileage out of a JavaScript framework. The project could have:

  • a variety of third-party components, used mostly as-is
  • a build system that includes continuous integration, if not continuous deployment
  • a notion of “development” vs. “production” builds
  • a test suite with coverage reports and additional types of tests, such as functional tests and smoke tests
  • significant “Getting Started” automation and documentation, to ensure new developers can become productive quickly
  • a consistent notion of how to manage state, perhaps backed by a simple state management library

10000-100000 lines of code: The web application, becoming its own ecosystem. The code is large enough that some of its dependencies and third-party components are starting to be phased out in favor of more custom code tailored to the project. The project could have:

  • internal components that are complex enough to be their own mini web applications
  • a growing toolkit of internal utility components, along with a style guide on how to use them
  • one or more “daughter” repos, representing code that once resided in the application, but are now robust enough to be re-used across projects
  • harder guarantees on build reproducibility, such as requiring all builds to be run in a container
  • more checks at build time: extensive lint rules, best-effort automated accessibility checks, minimum code coverage percentages
  • code compilation that goes beyond basic module bundling: this could include advanced ES features, a type system or compile-to-JS language

These are my own rough guidelines. What are yours?

Posted in Web

A Lost JavaScript Framework

Toad and Frog went for a long walk.

They walked across a large meadow.

They walked in the woods.

They walked along the river.

At last they went back home to Toad’s house.

“Oh, drat,” said Toad. “Not only do my feet hurt, but I have lost one of the JavaScript frameworks I was using to build my startup.”

“Don’t worry,” said Frog. “We will go back to all the places where we walked. We will soon find your framework.”

They walked back to the large meadow. They began to look for the framework in the tall grass.

“Here is your framework!” cried Frog.

“That is not my framework,” said Toad. “That framework is really just a glorified DOM abstraction library. My framework was component-oriented.”

Toad cloned the DOM abstraction library from GitHub.

A sparrow flew down. “Excuse me,” said the sparrow. “Did you lose a framework? I found one.”

“That is not my framework,” said Toad. That framework supports two-way data binding. My framework relied on one-way data binding.”

Toad cloned the framework with two-way data binding from GitHub.

They went back to the woods and looked on the dark paths.

“Here is your framework,” said Frog.

“That is not my framework,” cried Toad. “That framework is highly opinionated. My framework was flexible.”

Toad cloned the opinionated framework from GitHub.

A raccoon came out from behind a tree. “I heard you were looking for a framework,” he said. “Here is one I just found.”

“That is not my framework!” wailed Toad. “That framework is controlled by a giant corporation. My framework had a proper governance model.”

Toad cloned the corporate framework from GitHub.

Frog and Toad went back to the river. They looked for the framework in the mud.

“Here is your framework,” said Frog.

“That is not my framework!” shouted Toad. “That framework has to be transpiled from some hipster functional language. My framework was good old ECMAScript 2015.”

Toad cloned the hipster framework from GitHub. He was very angry. He jumped up and down and screamed, “The whole world is covered with JavaScript frameworks, and not one of them is mine!”

Toad ran home and slammed the door. There, open in vim on his MacBook, he saw his component-oriented, one-way data bound, unopinionated, well-governed, non-hipster framework.

“Oh,” said Toad. “It was here all the time. What a lot of trouble I have made for Frog.”

Toad took all of the frameworks out of his pocket.

He took his MacBook off of his desk.

Toad used all the frameworks to build a web application.

The next day Toad gave his web application to Frog.

Frog thought that it was beautiful. He shopped it around to angel investors. None of the frameworks crashed.

Toad had glued them all together surprisingly well.

Posted in Web

Why is it a Bad Idea to Listen for Internal DOM Events in YUI Widgets?

Continuing in the same vein as the previous post, I thought I’d highlight another basic, but interesting facet of YUI development: listening to events from widgets.

Let’s say you have a TabView, and you want to take some action each time the user changes tabs. (Let’s say in this case, just count the tab switches.) Naively, you might do something like:

var tabview = new Y.TabView().render('#tabview'),
numSwitches = 0;

tabview.get('boundingBox').on('click', function (ev) {
    numSwitches += 1;
    Y.one('#counter').setHTML(numSwitches);
});

However, a far better way to go is to listen for widget state changes directly — in this case, the TabView‘s selectionChange event:

var tabview = new Y.TabView().render('#tabview'),
numSwitches = 0;

tabview.after('selectionChange', function (ev) {
    numSwitches += 1;
    Y.one('#counter').setHTML(numSwitches);
});

There are three reasons why you would want to use the latter approach over the former.

First, repeated clicks on the same label do not indicate a tab switch.

Second, a tabview might supply additional ways to navigate to different tabs such as keystrokes or gestures, which a click listener would miss.

Third, it is poor practice to depend on the internal structure of a widget’s HTML. The HTML produced by a widget is a reflection of the data the widget represents, and the UI elements produced are a consequence of that data. Changes to the widget’s data can trigger the widget to refresh its internal HTML, which in turn can destroy any DOM event listeners you might have set. If you need to react to widget state changes, listen directly for those state change events, not the DOM events that might have triggered the state change.

Naturally, these principles apply to any library that provides widgets, not just YUI. If you’re building a widget or plugin with some other JS library, think about how you can use that library to directly indicate a state change, rather than forcing other developers to listen for DOM events.

To sum up: if you’re trying to keep track of widget state changes, listen for state changes, not DOM changes. The DOM within a widget is volatile, and DOM events don’t necessarily correspond 1-to-1 to the thing you are actually trying to track.

Posted in Web

Why Does YUI Have a Y.one() Method?

When I was working on the YUI 3 Cookbook, one of the things I really enjoyed was being able to pick the brains of the YUI team and get a straight-from-the-horse’s-mouth account of YUI’s architecture and design. With the release of the cookbook, I thought it would be fun to look back through the manuscript and pick out some short topics that might be of interest to new and intermediate YUI users.

One basic thing you might be wondering about is… why does YUI have two idioms for reaching into the DOM?

YUI’s first method, Y.all(), retrieves a Y.NodeList instance:

var errorDivs = Y.all('div.error');

If the selector fails to match any elements, Y.all() returns an empty Y.NodeList.

By contrast, the second method, Y.one(), retrieves a single Y.Node instance:

var errorDiv = Y.one('div.error');

If the selector matches multiple nodes, Y.one() returns the first match (as if you were using the :first jQuery pseudo-selector). If the selector fails to match any elements, Y.one() returns null.

So what’s up with this? Why bother having two methods, and why do they behave so differently? Why not just have querySelectorAll()-like behavior and be done with it?

The answer is that it’s helpful to know ahead of time whether you will receive a single node or a collection. This in turn is why the two methods return different values when the selector fails to find a match. Since Y.one() returns null, it is great for simple node existence checks:

if (Y.one('#myDiv')) {
    ...
}

As for Y.all(), the fact that it always returns an empty collection makes it always safe for doing bulk operations. For instance, the following works just fine even if there are no error divs in the document:

Y.all('div.error').remove();

Some libraries rely on a single abstraction (reaching into the DOM always returns a collection), but the choice of Y.all() and Y.one() — or, if you’re thinking in native terms, querySelectorAll() and querySelector() — ultimately enables you to write cleaner code. The cost is having an extra API method to think about. Fortunately, YUI’s methods have short, distinct names, so it’s pretty easy to remember which one does what.

Posted in Web

YUI 3 Cookbook Now Available in DRM-free EPUB and MOBI

Building on last week’s news, the YUI 3 Cookbook is now officially available for purchase as an ebook! So far I’ve seen it available at the following fine Universal Resource Locations:

The multiformat bundle from O’Reilly is definitely DRM-free. I am pretty sure the Apple and Amazon files are also DRM-free… because if they weren’t, that would be just insanely stupid.

It goes without saying that yes, the YUI 3 Cookbook is also available in print form. You know, if you hate trees. When you were in school, and they told you that if you were lost, you should hug a tree — didn’t you think that was just a little bit creepy? You and me both, kid.

Posted in Web

YUI 3 Cookbook is off to the Printer!

I’m pleased to announce that the YUI 3 Cookbook is officially off to the printer! Hooray! Unfortunately I’m not actually at O’Reilly Tower right now, but I do have exclusive footage of the printing process getting underway:

You can still pre-order the physical YUI 3 Cookbook through O’Reilly Media, Barnes & Noble, Amazon.com, Powell’s Books, and many other fine vendors. Also: if for some reason you actually like trees, my spies report that ebooks might be available as early as next week! Subscribe to this blog for future updates.

Free YUI 3 Cookbook Sample Pack (Updated x2)

With the YUI 3 Cookbook draft nearing completion, I’ve put out a PDF sample pack of the first three chapters. The sample pack was actually announced last week during the YUIConf 2011 keynote, but here it is again:

TOC and Sample Pack

YUI 3 Cookbook Sample Pack

  1. Loading YUI
  2. DOM Manipulation
  3. UI Effects and Interactions
  4. Events
  5. AJAX
  6. CSS
  7. Infrastructure
  8. Widgets
  9. Utilities
  10. Server-side YUI
  11. Universal Access
  12. Professional Tools

CAUTION: Cookbook Sample Pack has not gone through the O’Reilly editing and technical review process. Cookbook Sample Pack contains numerous typos, awkward phrases, stylistic inconsistencies, and flat-out technical errors. Discontinue use of Cookbook Sample Pack if any of the following occurs: itching, tingling in extremities, loss of balance or coordination, or slurred speech. Do not taunt Cookbook Sample Pack.

Update #1: Bonus Material

By the way, if you downloaded the sample pack last week, please download it again. The updated version includes a number of edits I had waiting in the wings, plus some great catches from @codertales, plus TWO BONUS recipes, one about the Resize plugin, the other how to register custom named transitions for easy reuse. Whew! So what are you waiting for? Go get it! But mind the itching.

Update #2: February 22, 2012

The YUI 3 Cookbook Sample Pack has been updated again, this time incorporating a large number of technical edits. Still not formally copyedited, but other than that, this is as good as it gets!

Posted in Web

HOWTO Create a Windows 8 Metro App with JS and YUI 3

Before reading further, readers should know:

  • I am a knucklehead.
  • I am not an engineer by any means.
  • I have no Windows development experience whatsoever. I do not know anything about the Windows developer stack.
  • My last Windows machine at home was a homebrew PC in 2002. That year, I switched to OS X. The last Windows machine I used at work was in early 2005.
  • The procedure below does things the stupid way, rather than the right or elegant way.

To sum up — me: knucklehead. Windows: alien territory.

Onward.

A Suboptimal Workflow for Metro App Development with YUI 3

  1. Download the Windows 8 Developer Preview. Install the ISO as a VM using VirtualBox, Fusion, or Parallels. FWIW, I used Parallels with 2 GB RAM on a 30 GB volume.

    Marvel at the fact that Windows installations take a lot less time today than they did on 2002-era hardware. Click through license agreements with enthusiasm. But don’t sign up for Live.

  2. Boot your brand new Windows 8 VM! Don’t let the fact that your virtual sound card is broken dampen your spirits.

    Stare at the brave new tablety world that is Windows 8. This doesn’t look like XP at all. You are… kind of intrigued, actually. Your Mom, however, is going to be super-pissed.

  3. Click the Visual Studio 11 square-thingy. Start a JS project and choose one of the built-in templates.

    It’s… a single-page web app! It uses a brand new JavaScript framework called Win-NIH.js. No, it’s actually called WinJS. It’s even documented. I’m sure it’s awesome.

  4. Delete all script and link references to WinJS and related CSS assets from the main default.html web page.

  5. Important: disable Visual Studio’s auto-id-mangling by going to Tools -> Options -> Text Editor -> HTML -> Miscellaneous and unchecking “Auto ID elements on paste in Source view”. (Thanks, Hardy Erlinger!) Otherwise, copying and pasting will cause Visual Studio 11 to stomp over all the IDs in the HTML, breaking your project. Yes, really.

    Now you’re going to need some code. So fire up Internet Explorer — might as well go all-in on this Microsoft stuff.

  6. Go to yuilibrary.com and view the TODO App Example, a toy single-page app that demonstrates how to use the YUI 3 App Framework. Scroll down to the bottom of the page, copy the complete TODO example, and paste it into default.html. Good artists copy, great artists steal.

  7. Now it’s time to load the YUI library itself, or at least the modules that power the YUI 3 TODO app. Go to the YUI 3 Dependency Configurator. Select the modules event-focus, json, model, model-list, and view in the configurator, copy the resulting combo-load URL, and paste that URL into a new IE tab. IE will offer to open or save the JavaScript file. Click Save.

  8. Return to the project in Visual Studio. Right-click the /js folder and add an existing file. Browse to the Downloads folder and add the combo.js file. When the file is imported to your project, feel free to rename it to yui-todo.js or something else meaningful.

  9. In default.html, add a script element with a src of /js/yui-todo.js above all other script elements.

  10. In the YUI().use() call, replace the list of module names with just '*'.

  11. From the Build menu, click Deploy. This builds your app and then side-loads it into your Windows environment, all in one step.

  12. Go back to the main Windows 8 tablety area. Scroll all the way to the right, and you will see your TODO app, with a generic black icon. Single-click to launch.

Congratulations! You’ve built, deployed, and run your first JS-style Metro app. It works exactly like the browser version. Except you can’t exit the app. Hahaha! You’re going to have to throw away your VM and start over.

Kidding. To quit the Metro app, hit the CMD button. To make changes, you’ll want to delete the deployed app from your environment before attempting to rebuild and redeploy the app again.

Elapsed time from launching Visual Studio (knowing nothing) to a deployed Metro app (still knowing nothing): a little under an hour. I actually wasted most of that time on other things:

  • Stumbling around an unfamiliar UI, figuring out how to navigate around etc.
  • Fooling around in Visual Studio — looking at the source files, building and deploying one of the default projects, building and deploying a static HTML page with one JS function all as a Hello World project, etc.
  • The big one, the ID-stompage problem. This eventually required doing a Debug build. I have no idea how to use the Visual Studio debugger, and it slows things down tremendously, but it does generate some JS console log output for you when you go back to run the app.

Observations

  • Despite running into a serious bug in Visual Studio 11, I was really impressed that the whole thing worked as advertised. You are not locked into WinJS at all. If it runs in IE 10, it should build as a Metro app. I dig it.
  • As You Know Bob, in the browser YUI 3 is meant to load a small seed file, and then asynchronously load module files from a server or CDN running a combo-loader. For Metro apps, we’re subverting this process by hand-crafting a physical rollup file of the modules we need and calling YUI().use('*'). Obviously, the way I actually created that rollup is a huge hack.
  • I haven’t actually tested the YUI 3 Loader in Metro — it would be neat if it worked — but the loader is probably not all that relevant for creating Metro apps anyway.
  • I don’t really know Visual Studio at all, so I don’t know how to develop iteratively there very well. Also, if you need to track down a runtime error, doing a Debug build is particularly painful. I’m sure Visual Studio experts know exactly how to do this stuff efficiently. See also: I am a knucklehead.

Anyway, my recommendation for the typical frontend engineer is to just stick with the development environment you like. Build and test your app in browsers, and basically just use Visual Studio as a build tool. I bet someone smarter than me knows how to automatically import code into Visual Studio and trigger a build headlessly. That would be nifty.

Postscript for Future Microsoft App Store Employees

If you have been wondering why you keep having to reject submissions of this weird “YUI 3 TODO app” — well, this post is probably why. My sincere apologies.

Real Community Management: A Happy Story with a Grim Lesson

Yesterday, a Hacker News thread started about the recent yuilibrary.com site re-launch. The new template had drawn a good deal of praise from various Friends of YUI on the Internets over the previous few days, which made everyone feel pretty good.

But Hacker News lives very much outside the YUI community bubble, and feedback there was more mixed. One of the earliest comments set the tone:

While YUI is probably one of the best JS frameworks around the sloppy design of their webpage beats me. the yuilibrary.com looks so 90ish in its design.

Instead of letting the thread sit out there and rot, YUI engineer Ryan Grove quickly responded with:

What parts of it strike you as sloppy? How would you improve the design? We’d love to hear specific feedback.

And got comments like:

* Use a fixed-width site. Most people go for something like 960px. * Establish horizontal and vertical eyelines or columns. * If you're on Github, might as well use gists. Offer example projects as open projects on Github
+1 on the fixed width. I'm a developer, so I have a big monitor -- it's hard for my eye to follow sections of the document without lined up elements.
Trebuchet feels dated, especially when bolded and part of blue + orange scheme. That look was very trendy a few years ago. Also, too many faces. Two faces usually work fine...
... I know you have your own CDN but can we have back a "Download" button? I hate it when I have to search for 5 minutes to find out how to download something. It really makes me feel like the whole project is going to be a pain in the ass when even downloading it is hard.

About two hours later, Ryan responded again with:

Great feedback, everyone. I've pushed a few quick changes to address the low-hanging fruit:

- We're now using Maven Pro for headings (no more Trebuchet).

- Replaced Lucida Grande with Helvetica in the nav bar (sorry Windows users, you get Arial).

- The site now has a max width of 1200px instead of expanding infinitely. This seems like a reasonable compromise, since any purely fixed-width design draws the ire of people who hate fixed-width designs.

Keep the feedback coming!
We wanted to emphasize the CDN over downloads, but we clearly hid the download links too well.

I've added a "Downloads" link to the "Quick Start" dropdown menu in the top nav bar, and we'll give some thought to adding a more prominent link somewhere on the front page. Thanks for the feedback!

Not everything got fixed immediately, but some easy changes got pushed right away. And just like that, comments like this started appearing:

Thanks! That's a pretty amazingly quick response and makes it way easier to find.
Wow, that was fast.
All of a sudden with all of rgrove's (YUI's) interaction, it makes me feel all warm and fuzzy about using YUI again. Great customer service does make a difference.

No doubt not everyone was 100% satisfied, but the thread stayed popular for a good part of the day, and I think most folks came away with the feeling that the YUI team was responsive and effective. After all, they were in fact being responsive and effective. All in all, a good result.

However, the lesson here for the field of community management (at least when it comes to software products) is actually pretty grim.

The idea behind community management is that rather than letting feedback sit out there and decay, you have a professional someone whose job it is to come in and keep things from spiraling out of control. Talk to the people. Gather up the features and bugs. Communicate changes. Let people know that you’re listening.

But “listening” and “participating in the conversation” are weak sauce, and everyone knows it. It’s action that matters.

Having a community manager who is also a working engineer or a product manager makes sense to me. Those are people who can push changes. The icing on the cake is if your product allows for pushing simple changes very quickly. But even without that, just having real authority and knowledge over the timeline makes a world of difference.

By contrast, the classic dedicated community manager is someone who is bright and socially adept, someone who can funnel information back and forth, but who lacks real product authority. After all, you don’t want to waste a product person’s time doing that stuff, do you? Way too expensive. And they would suck at it. No, you need someone specialized.

More and more, that whole line of thinking seems like a huge trap.