Some information about
JavaScript-Powered
Task Automation
Including:
- Various reasons you should know how to do it
- Various ways it can be done
- Various situations that call for it
- Various examples of various ways to do it, for various reason, in various situations that call for it
Examples live in a Github repository:
ME: DAVID CLARK
- A frontend developer with experience working on
- smaller, design-focused sites with quick turnaround (at an agency)
- large-scale, long-term web applications, where maintainability is top priority (at my current job)
- Currently work at HealthTrio, buliding a modern, React-based frontend framework to replace the outdated UIs of multiple applications
- We are hiring more frontend devs to help me!
david.dave.clark@gmail.com - @davidtheclark
davidtheclark.com
What I mean by
"task-automation"
- Establish a way to do something that needs doing.
- Create a simple command that will do that.
Why automation with Node makes sense for people like us
- It's JavaScript
- It's the dominant platform for frontend tools, especially tools related to JavaScript
Modern frontend development demands
task-automation
Without task-automation, you are causing needless suffering.
- Your authoring process suffers.
- Your code quality suffers.
- Browsers (and their users) suffer.
author-optimized !== browser-optimized
- Concatenation
- Minification
- JS modules
- Unsupported syntax: ES6, Coffescript
Code quality should be automatically enforced
- Linting
- Tests
If it's not automatic people will let it slide!
Automation opens up possibilities
Happily do all those things you would not want to do manually, every time.
- Spritesheets, SVG sprites, custom icon fonts (Grunticon)
- Duplicating images at multiple sizes, each optimized, for <picture>
- Inlining critical CSS and JS
- Analyzing code in various ways (e.g. list-selectors)
- Making major mindless changes (e.g. qualifying legacy CSS)
A few ways to automate tasks
- Grunt
- gulp
- npm scripts
- straight Node
We'll elaborate on these with an example ...
Github repository:
Task One: Styling
- Author in multiple SCSS files without vendor prefixes
- Output a single prefixed, minified, vanilla CSS file for the browser
- Development: re-compile on save & refresh browser with BrowserSync
Grunt
- Input-output: read files, perform a single task on contents, write new ones (repeat for every task)
- Configuration: gruntfile.js = wrapped config object
- Synchronous: next task won't start until previous task is completed
- Plugins wrap Node scripts
Basic usage:
- Install grunt locally, grunt-cli globally
- Install (locally) the plugin that does what you want done
- Setup the configuration in gruntfile.js
- Use the command: grunt [task[:target]]
Grunt
Grunt
gulp
- Streams (piping): read files, perform multiple operations, write new ones
- Code: gulpfile.js = Node script
- Asynchronous (or synchronous): Multiple tasks can run asynchronously. This helps with speed.
- Plugins wrap Node scripts
Basic usage:
- Install gulp locally and globally
- Install (locally) the gulp plugin or other npm module that does what you want done
- Write some code to use it in gulpfile.js
- Run
Non-streams
Source File → Transformation A → Output File #1
Output File #1 → Transformation B → Output File #2
Output File #2 → Transformation C → Output File #3
Streams
Source File → Transformation A
↓
Transformation B
↓
Transformation C → Output File #1
npm scripts
- Directly use a Node module's CLI (command line interface). No middle-man plugin.
- Write commands in package.json
- Synchronous by default, but can be made async (or even parallel)
Basic usage:
- Install the npm module that does what you want done and has a CLI
- Write down your repeatable command in package.json
- Run
A few more notes about npm scripts
- Commands have local modules in their path: no need for global installs
- Commands can call other commands
- You can use regular old command line streaming with | and >
- You can run commands at the same time (like gulp's async) with a tool like parallelshell
- Generally, you can directly use the npm modules that Grunt or gulp plugins depend on
- There are ways to make the commands more flexible, with configuration variables and passing arguments through to the command
Why might I want to cut out the middleman?
("middleman" = runner + plugin)
- More modules to choose from
- Fewer possibly buggy interfaces
- Fewer maintainers to rely on
- More knowledge about the module itself = more flexibility in the long run
- General attitude of minimalism
Write a Node Script!
-
Directly use a Node module's JS API. No middle-man plugin and you can throw in arbitrary JS.
-
Write a script wherever
-
Asynchronous or synchronous, whatever you write
-
Allow for CLI-style arguments, if that fits you needs
To do it:
- Write JS
- Run, via > node [script]
Task Two: JavaScript and Browserify
-
Author JS in multiple ES6 modules
-
Output a single linted, uglified, ES5 file
-
Development: re-compile on save & refresh browser with BrowserSync
Pros/Cons: GRUNT
Pros
-
For JS beginners: Not really code
-
No async-related confusions
Cons
-
Non-stream style can make sequential tasks confusing (plugins overreach to compensate)
-
Non-stream + sync + overhead = relatively slow
-
Not flexible or customizable (unless you start writing your own plugins)
- Plugin and runner intermediary
>> Missing anything? <<
Pros/Cons: GULP
Pros
- Intermix regular npm modules, gulp plugins, and arbitrary JS
- Flexibility of real JS plus useful API and conventions for tasks (reading-transforming-writing, watching, chaining)
-
Streams end up making more sense, more often than Grunt's isolated tasks
-
Streams + async = fast
Cons
-
Async can cause some confusion, some getting-used-to
-
Plugin and runner intermediary
- Not always as friendly with non-gulp JS as you'd like (esp. different streaming formats)
>> Missing anything? <<
Pros/Cons: NPM SCRIPTS
Pros
-
No intermediary between the module and you
-
Sync or async, stream or non-stream
-
Learn how to use the tools themselves, and some bash
-
Simple simple simple (usually)
Cons
-
Complex commands can become harder to read than JS
-
Cannot insert arbitrary JS
-
Sometimes its harder to find help and examples
>> Missing anything? <<
Pros/Cons: NODE JS FILES
Pros
-
No intermediary between the module and you
-
Sync or async, stream or non-stream
-
Arbitrary JS = ultimate control, if customization is priority
-
Learn how to use the tools themselves
-
Be a real Node programmer, not just a pre-packaged workflow consumer
Cons
-
Might end up reimplementing patterns built into gulp/Grunt, running into problems they make it easy to avoid
>> Missing anything? <<
Task Three: Webpack to make a Shareable Library
-
Author a React component in multiple ES6 modules using JSX syntax
-
Output a single linted, uglified, ES5 file that expects React as a global and exposes its own global
-
Also output linted, ES5 module files that can be consumed via CommonJS by other Browserify/Webpack users
-
Development: webpack-dev-server
QUESTIONS?
david.dave.clark@gmail.com - @davidtheclark
davidtheclark.com
JavaScript-Powered Automation
By David Clark
JavaScript-Powered Automation
- 673