We do not like being told what to do, but we do like knowing how things fit together.! ! (Even if we end up taking them apart and making them our own.)
Overview • What is a style guide?! • Examples of style guides! • Rolling your own framework! • Using NPM and Webpack! • Using ES6 and React! • Using PhantomJS! • DEMO! :)
What a Style Guide May Contain! ! It is about design governance and code standards.! ! What we mean by that is:! ! • No more rogue agents, shooting from the hip with unique snowflake designs, or developers building one-off widgets in code. • Everything in a project should exist for a reason, and its purpose should be documented accordingly. • This allows for easier and quicker onboarding, where someone can refer back to established patterns and code conventions. • It gives you a defensive point reference, in case implementation goes awry. It's a "last known good" state of UI development.! ! (Design coworker Brandy Taylor coined the term "Design Governance.")
In Addition to Design, We Also Document! ! • Accessibility expectations, with a tie-in to SEO to "sell" it.! ! • AJAX does not mean "Accessibility Just Ain't eXciting."! ! • Browser requirements (January 12, 2016 = R.I.P. IE8).! ! • Best practices: • Responsive design, explanation and breakpoints. • What we will or will not attempt to achieve outside of CSS. • Border-radius, box-shadow, gradients, opacity, etc. • Non-native form controls. Styling is okay, but recreating something the browser gives you "for free" is not.
Clarification! ! There is nothing inherently wrong with using a third party library or framework (that is half our job), assuming that… ! • The library or framework that you are using solves a problem you actually have. • You are not "solutioneering," attempting to use a tool designed to solve other people's problems.! ! • You are using it as a "tool," not a "crutch."! ! ! The more invested you are in a "kitchen sink" framework, especially if it lacks extensibility, the harder it is to adapt to change over the lifetime of a given app or product.
Note: We Do Not Recommend Rewriting Your Framework Three Weeks Before a Presentation! ! September 25th, 2015! ! Nathan: "When you get back from Burning Man, let's start working on our Front Porch slides."! ! Mundi: "Actually, why don't we go ahead and rewrite it using React on the client and server."! ! Nathan: O_o
Our Requirements for ISG v2! ! • Statically generated.! • Portable.! • Server agnostic.! • Zip-able (can be sent as flat-file).! ! • Stays fresh.! • Can be built from the live app's codebase.! • App should not "know" about the style guide.
Our Requirements for ISG v2! ! • Contains brand standards.! • Has room to grow.! • Can have non-dev contributors.! ! • Automated listing of unique patterns.! • Live working UI.! • Code examples: JavaScript and HTML.! ! • Houses screenshots and technical specs.
Used in Both v1 and v2 • Lodash.js: data manipulation.! • Glob: file/directory globbing.! • FS-Extra: file system utilities.! • PhantomJS: for screenshots.
Gotchas with NPM! ! • We love that using NPM for task automation removes the need to use a task runner like Grunt or Gulp.! ! • However, chaining together commands with NPM scripts can get hairy. There are tradeoffs either way.! ! • Closer to the metal, but more manual curation.
Gotchas with NPM! ! Cross platform portability…! ! For example, {"clean": "rm -r ./build"} will not work on Windows.! ! Instead, use something like Trash-CLI.! ! It abstracts this functionality across platforms.! ! https://github.com/sindresorhus/trash-cli
Things to Consider! ! • If it suits your project's needs, using Grunt or Gulp can help ease the burden of automation.! ! • Ultimately, both Gulp and Grunt use Node under the hood anyway.! ! • Using NPM scripts is like an "API" to your build automation. Even if you are using Grunt or Gulp, you can map tasks to package.json too.
I Will Admit… React is awesome. I was basically super wrong.! ! Over the years, I have only found a short list of concepts to be exciting in web development.! ! • CMS powered sites.! • jQuery.! • Sass.! • React.
ECMAScript 6 is Weird (in a Familiar Way) The way we are using React is…! ! • ES6 classes, transpiled to ES5 (via Babel).! • JSX ("HTML" in JS), which Nathan thought he would dislike.! • "Standard" for our JS linter.! • ASI: Automatic Semicolon Insertion – Don't kill us!! • Otherwise, it has generally agreeable conventions.! ! Note: ES6 and JSX feel different enough that going ASI (too) was not actually that big of a stretch. MAKE NEW ALL THE THINGS.
Using React on the Server – aka "isomorphic"! – aka "universal" – aka "cool kids" • Create JSX "layout" components. • Then, using Node… • Use webpackRequire() to load the template and resolve dependencies: CSS, Markdown, images, etc. • Use ReactDOMServer.renderToStaticMarkup() to process the template and return HTML. • Save the rendered HTML output to disk.
Our Approach to Creating Screenshots! ! • We create a PhantomJS script to iterate through a list of paths, taking a screenshot of each at mobile, tablet, and desktop widths.! ! • We generate a list of full-page screenshots that are linked to each actual "application" screen.
PhantomJS Gotchas! ! • A server must be running for phantom to be able to access the pages you want to screenshot. Keep your server on!! ! • We wanted to use the awesome PageRes library. However, it ships with PhantomJS 1.x which uses an old version of WebKit. This has poor support for CSS3, making our screenshots look less than ideal.
PhantomJS Gotchas! ! • PhantomJS 2.x is not easily installed via NPM (in our experience).! ! • You have to manually download and install PhantomJS yourself, which makes automation difficult. It is not as easy as: "npm install ..."! ! • Activity on the project seems to have slowed.! ! • In the future, we may look at using SlimerJS (based on Firefox).
PhantomJS Pro Tip™! ! We are adding to the document, so that approaches like having a "sticky footer" don’t jack with the page's natural height. Basically, forcing something other than the tag to scroll will confuse Phantom.! ! You can manually add this to the HTML tag (or via console) as you build pages, to check what PhantomJS will "see" when it goes to screenshot each page. This approach allows you to (de-)target Phantom via CSS.