"Post" is the New "Pre" – Using Postprocessors toRevolutionize Your Workflow



"Post" is the New "Pre" – Using Postprocessors toRevolutionize Your Workflow

0 0


post-is-the-new-pre

Post is the New Pre: Using Postprocessors to Revolutionize Your Workflow

On Github aladage / post-is-the-new-pre

"Post" is the New "Pre"

Using Postprocessors toRevolutionize Your Workflow

Aaron Ladage / aladage@degdigital.com / @aladage

“Sooner or later,everything oldis new again.”

– Stephen King, "The Colorado Kid"

The web has a funny wayof getting back to its roots.

Technological expansion and contraction

A natural reaction to:

  • Current browser limitations
  • Pace of new feature adoption

Flash was a necessity.

Seriously. No really, I mean it.

Yes, Flash sucked.

(Somebody thought this was a good idea.)

But it also gave us:

  • Streaming video before HTML5 video
  • Animation before CSS3 transitions and animations
  • Rich interactive experiences before robust JavaScript

Flash bridged a functionality gap,and ultimately, it encouraged web standards to catch up.

"Responsive Web Design"

– Ethan Marcotte, 2010

Three tenets of responsive:

  • Fluid grids
  • Media queries
  • Flexible images

There was one big problem with responsive images:

The groups that make web standards didn't see the problem.

A (very) distilled history:

  • Developers (including Marcotte) saw shortcomings in current <img> capabilities.
  • W3C and WHATWG showed little interest and suggested they create a community group (aka, the devs got blown off). Responsive Images Working Group was formed.
  • RIWG and other dev groups propose two solutions: <picture> and srcset. They're rejected again by WHATWG.
  • During this time, a polyfill emerges. Developers begin using the proposed solution and polyfill in the wild.
  • Eventually, a combined picture/srcset standard is created, with browser support appearing in late 2014.

In the case of responsive images, developers and innovation drove the standards, not the other way around.

Call me crazy,but I believe…

Front-end development is onthe verge of another greatre-evaluation and contraction.

Developers have been filling in the gaps in CSS and JavaScript for years.

"CSS is not a real programming language"

"JavaScript is a toy language"

Problems with CSS

  • Cross-browser compatibility issues
  • Vendor prefixes
  • No variables
  • No inline importing
  • No nested selectors
  • No functions/mixins
  • No color manipulation
  • No basic arithmetic

Problems with JavaScript

In the browser:

  • Messy syntax
  • Cross-brower compatibility issues
  • Difficult DOM traversal
  • Difficulty with effects/animation

Problems with JavaScript

Within the language itself:

  • No module-loading system
  • Quirky type coercion
  • No interpolation/template strings
  • No fat arrows
  • No default function arguments
  • No classes
  • No constants
  • No destructuring

Preprocessors became the solution.

…and a pretty good one at the time, too.

CSS:

JavaScript:

(If this slide doesn't piss off everyone in the room, nothing will.)

Or maybe you've tried them all?

Coffeescript:

This:

for num in [1..10]  
  if num % 2 == 0
    console.log "#{num} is even"
  else
    console.log "#{num} is odd"

Compiles to this:

var num, _i;

for (num = _i = 1; _i <= 10; num = ++_i) {  
  if (num % 2 === 0) {
    console.log("" + num + " is even");
  } else {
    console.log("" + num + " is odd");
  }
}

On the JavaScript library front:

Querying the DOM for an element in vanilla JS…

var el = document.getElementById("myContainer");

…became this with jQuery:

var el = $("#myContainer");

But preprocessorsperpetuate a problem.

(Say that five times fast.)

We're putting more and more layers ofabstraction between the code we writeand the code the browser can read.

Preprocessors are their own programming languages

  • Not "real" code
  • Proprietary syntax
  • Often written in "non-web" languages
  • Potentially buggy
  • Not as easily extensible
  • Must be compiled, today and forever
  • Browsers are catching up
  • Compile times can be slowwwwwww

JavaScript frameworks arealso becoming irrelevant

Why dump jQuery?

  • DOM traversal isn't that hard with vanilla JS. No, really.
  • IE10/11 have eliminated most cross-browser compatibility issues.
  • CSS3 is better suited for transitions and animations.
  • Dependencies suck.
  • Impress your friends with your library-less street cred!

I'll try not to sound like this:

Goodbye, preprocessors

Hello, postprocessors

Before you ask…

Technically, postprocessors are still preprocessors.

"Transpiler" might be more accurate.

That's the preferred term on the JavaScript side.

Postprocessors and transpilers get usback to writing code in the languages wefell in love with in the first place.

CSS Postprocessor:

JS Transpilers:

Our preprocessor process:

Our new postprocessor process:

Our new postprocessor process:

Our new postprocessor process:

Our new postprocessor process:

Our new postprocessor process:

So, how do you get started?

It's possible you already have.

Autoprefixer

Autoprefixer

  • A popular replacement for Compass's vendor prefix mixins.
  • Automatically adds vendor prefixes to CSS3 properties.
  • You define which browsers should be supported via a config file.
  • Cross-references the always-current caniuse.com database.
  • No need to memorize special function names; just write CSS and let it do its work in the background.

Part of the much largerPostCSS ecosystem:

PostCSS advantages:

  • Write your CSS using CSS (what a concept!).
  • Use CSS3 with reckless abandon.
  • Hell, use CSS4. Who cares if that's not actually a thing yet?
  • Works with your existing task runners
  • Built on Node!
    • No more Ruby dependencies!
    • Easier to debug
    • Can't find a plugin that does what you want? Write your own in nothing but JavaScript.
    • Faster compile times (40x faster than Ruby Sass / 4x faster than LibSass…allegedly).
  • Countless plugins

Don't. Freak. Out.

Believe it or not, there is life after Sass.

If you can do it with Sass, youcan probably do it with PostCSS.

Partials/Globbing

Partials/Globbing

Nested Selectors

Nested Selectors

Variables

postcss-custom-properties: a great opportunity to start following the (HIDEOUS) proposed CSS custom properties syntax:

:root {
    --color-blue: #0082c2;
}

.myContainer {
    background-color: var(--color-blue);
}

Variables

  • Yes, it's ugly.
  • But, it will someday be the standard, and allow for component-scoped variables.
  • If that grosses you out, use postcss-simple-vars for Sass-style variables instead.

Color

  • Like variables, you can follow the proposed CSS color module spec…and it's also ugly.
  • Work in RGBA, hex, HSL, HSV or HWB.
  • Use postcss-color.

Color

This also takes some getting used to:

.myContainer {
  background: color(red a(90%));
}

Combined with a variable:

.myContainer {
  background: color(var(--color-red) a(90%));
}

Mixins/Extends

  • Sass wins this one.
  • Lots of plugins for this. I like postcss-mixins. For basic arithmetic, I also use postcss-calc.
  • Ask yourself: how complex are your mixins? Is that a good thing?

What about JavaScript?

Well, in case you haven't heard by now…

EcmaScript 6 has been approved!!!

Remember this list?

  • No module-loading system
  • Quirky type coercion
  • No interpolation/template strings
  • No fat arrows
  • No default function arguments
  • No classes
  • No constants
  • No destructuring

ES6 fixes pretty much all these issues.

But we won't be able to use ES6code in production for years, right?

Wrong.

Write ES6 code like this:

import widgetBuilder from "modules/widgetBuilder";

const DEFAULT_TEXT = "This is some default text that won't change.";

let exampleFn = function() {
  
  let tmplStr = `This is amazing!
    it's a multiline string!
    Our default text is ${DEFAULT_TEXT}`
  
};

export default exampleFn;

Babel transpiles your code into this:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

var _modulesWidgetBuilder = require("modules/widgetBuilder");

var _modulesWidgetBuilder2 = _interopRequireDefault(_modulesWidgetBuilder);

var DEFAULT_TEXT = "This is some default text that won't change.";

var exampleFn = function exampleFn() {

  var tmplStr = "This is amazing!\n    it's a multiline string!\n    Our default text is " + DEFAULT_TEXT;
};

exports["default"] = exampleFn;
module.exports = exports["default"];

Works with all major JS loaders:

Common, AMD, System, UMD

Someday, we may even be able toturn off our transpilers, and ournext-gen code will "just work."

…but let's not kid ourselves.

There is no reason not to startwriting ES6 code today.

Front-end developmentis at a crossroads.

  • We're not that far away from next-gen CSS and JS being adopted into standards and supported natively in all modern browsers.
  • Until that happens, it's a wonderful time to get as close to "real" code as you can in your development process.
  • The benefits of switching to postprocessed CSS is debatable, but totally do-able.
  • The benefits of switching to transpiled JS is a no-brainer. Do it now.

As developers, we have the power and the responsibility to drive innovation and set the standards with how we write our code.

The people who makethe standards arepaying attention.

Thanks for listening.