46
2015: A Static Site Generator Odyssey Created by Thomas Jaggi / and Olga Skurativska / @backflip @_olko

2015: A static site generator odyssey

Embed Size (px)

Citation preview

2015: A Static SiteGenerator OdysseyCreated by Thomas Jaggi / and Olga Skurativska / @backflip @_olko

Who we areFrontend engineers at

About 150 engineers,distributed over 6 locations

Interdisciplinary departmentwith UX / UI designers

Unic AG

BasisStatic frontendprototype

Issue #1:Communication with projectmembers

UX / UI designers

Backend engineers

Project managers

Customers

 

Preview serverPresentation of current and previous state of the frontendprototype

Overview page

Project page

Build index page

Build content page

Issue #2:Automating frontend routines

Working with templates and partials

Generating CSS (preprocessing SCSS, autoprefixing,minifying)

Generating JavaScript (dependency resolving,concatenating, minifying, linting, unit testing, customizedbuilds of libraries)

Icons and images handling

Watching for changes and livereloading

Anticipated question:Why didn't you just use anexisting static site generator?

Our experiencewith Middleman:

Fixed technology stack

Configuration based

Written in Ruby

Nice to have:JavaScript-based solution

Possibility to plug in different tools

Quick setup of new projects

Meet Estático!https://github.com/unic/estatico

Anticipated question:

Why Gulp, not Grunt?

Estático's Gulp task structureGoal 1: Easy maintenanceWe store tasks in separate files

Estático's Gulp task structureGoal 2: Make tasks testableDefine task logic as an exportable function

var taskBody = function(config) { return gulp.src(config.src) .pipe(jshint()) .pipe(concat('main.js')) .pipe(uglify()) .pipe(gulp.dest(config.dest)); };

Source and destination paths are parameters

gulp.task(taskName, function() { return taskBody({ src: 'source/*.js', dest: 'build/' });});

Estático's Gulp task structureGoal 3: WatcherEvery task exports its watch paths

var taskName = 'js', taskConfig = { ... watch: ['source/*.js', 'source/modules/**/*.js'] };

module.exports = { name: taskName config: taskConfig};

Watcher loops through configs

_.each(tasks, function(task) { watch(task.config.watch, function() { gulp.start(task.name); });});

More automation:ScaffoldingModule create task:

prompts for a module's name

creates module's files

registers module's CSS and JS

Scaffolding tasks have a nicecommand line interface

More automation:Handling data in a project

Data has to be separate from templates

Templating engine (Handlebars) and JSON solve thatproblem

Anticipated question:Why Handlebars?

Handlebars:looks like HTML, is easy to understand

is extendable with custom helpers

is mustache-like

From JSON to JavaScript objectData becomes reusable

We can modify data before display using JavaScript

Demo

Issue #3:Continuous integration (CI)

1. Commit

2. Build (and run tests, code analysis, …)

3. Publish (preview server, artefact storage, …)

Prerequisites1. Node.js with

2. That's it

Problem 1:Not all Nodes are created equal

0.12 introduced breaking changes

Packages don't necessarily work in every major version

$ nvm use (0.12.2)

$ node -v0.12.2

Solution:Version management toolExample: nvm

* When on Windows: nvm-windows

Problem 2:Platform differences

1. Missing dependencies

2. Different implementations

Example 1:Missing dependencies

✖ Error: pngquant failed to build, makesure that libpng-dev is installed

✖ Error: /lib/x86_64-linux-gnu/libc.so.6:version ̀GLIBC_2.14' not found

Example 2:Different implementations (SVG to PNG)

1. Use PhantomJS

2. Discover problem on Windows:Cannot start phantomjs: Phantom didn'trespond within 30 seconds)

3. Use GraphicsMagick

4. Discover problem on OS X: vs.

5. Use PhantomJS on Unix and GraphicsMagick on Windows

6. Discover new problem on Windows

7. Go back to 1.

Solution:Specify runtime and make itavailable

1. Specify software versions

2. Select your linux flavor

3. Create box (or image)

4. $ vagrant up && vagrant ssh

Problem 3:npm install  ≠  npm install

npm packages are specified using SemVer

Works fine in theory, doesn't work as fine in practice

Solution:Lock down dependencies$ npm shrinkwrap

Problems 4-99:npm

Great piece of software

Amazing team behind it

But: Many edge cases

Solution:When in doubt: Clear cache$ npm cache clean

Update npm$ npm install -g npm@latest

* When on Windows: npm-windows-upgrade

Issue #4: Open-sourcing things

When to publish

How (not) to deal with licensing

How (not) to maintain

When to publishJust get over yourself!

Code will never be perfect

Publish anyway

Improve continuously

How to deal with licensing

Set up contributor license agreement (CLA) workflow

http://choosealicense.com

Not an actor

How to maintainSchedule time to take care of contributions

Define responsibilities

Contribute back to other OSS software (report bugs,suggest features, …) ❤

SummaryAutomate everything!

Create your own set of Gulp tasks!

Open-source it!

Set up a preview server!

Who is behind all of this?

Thanks!

Do youwant to be our friend?

ContactThomas Jaggi, – [email protected] @backflip

Olga Skurativska, – [email protected] @_olko

Interested in working with us?https://www.unic.com/de/about/career/jobs/development/senior-frontend-engineer-15-08-18.html