Frontend JS workflow - Gulp 4 and the like

52
Frontend workflow Gulp 4 and the like By / Damien Seguin @dmnsgn

Transcript of Frontend JS workflow - Gulp 4 and the like

Page 1: Frontend JS workflow - Gulp 4 and the like

Frontend workflow

Gulp 4 and the likeBy / Damien Seguin @dmnsgn

Page 2: Frontend JS workflow - Gulp 4 and the like

FRENCH Creative Developer at UNIT9, Rockstar

/ GitHub Twitter

Page 3: Frontend JS workflow - Gulp 4 and the like

What are the common components of our current workflow?

What is new in Gulp 4?

Are task-runner still relevant? What to expect in 2016?

Page 4: Frontend JS workflow - Gulp 4 and the like

What are the commoncomponents in our current

workflow?Package manager

Module system/syntax

Module loader/bundler

Task runner / Build system

Page 5: Frontend JS workflow - Gulp 4 and the like

Package ManagerHandles dependencies

Package: a set of files that are bundled togetherand can be installed and removed as a group.

Centralisation (one database/registry to pull data from)

Installation/uninstallation (one command to execute)

Upgrade (versionning)

Link Dependencies (avoid dependency hell)

Page 6: Frontend JS workflow - Gulp 4 and the like

Two main competitors

Bower: "A package manager for the web"

: "npm is the package manager for JavaScript"

but also JSPM

Page 7: Frontend JS workflow - Gulp 4 and the like

Bower

$ bower install underscore#1.0.3

$ bower install backbone # with underscore as a dependency

Unable to find a suitable version for underscore, please choose one: 1) underscore#1.0.3 which resolved to 1.0.3 and is required by bowerexample 2) underscore#>=1.7.0 which resolved to 1.8.3 and is required by backbone#1.2.3

. └── bower_components ├── backbone └── underscore

$ npm install -g bower

Page 8: Frontend JS workflow - Gulp 4 and the like

$ npm install [email protected]

$ npm install backbone # with underscore as a dependency

. └── node_modules ├── backbone │   └── node_modules │   └── underscore └── underscore

$ npm uninstall underscore $ npm dedupe [email protected] node_modules/backbone/node_modules/underscore -> node_modules/underscore

npm and front-end packagingnpm as a front-end package manager by @kewah

npm is only for CommonJS!npm is only for server-side JavaScript!

Page 9: Frontend JS workflow - Gulp 4 and the like

JSPM

Dynamically loads ES6 modules in browsers and NodeJSSystemJS:

: list of packages and their endpointRegistry

$ jspm install npm:react

$ jspm install github:angular/bower-angular

$ jspm install react

"react": "npm:react",

. ├── config.js ├── jspm_packages └── package.json

Page 10: Frontend JS workflow - Gulp 4 and the like

Other attempts

JamJS

DuoJS

VoloJS

Component

Ender

...

Page 11: Frontend JS workflow - Gulp 4 and the like

Module system/syntaxDefines a way of writing modular code

No built-in support in JS for modules

ES6 to the rescue

Page 12: Frontend JS workflow - Gulp 4 and the like

ES5 GlobalAMDCommonJSES6 modules

Page 13: Frontend JS workflow - Gulp 4 and the like

ES5

Module pattern (MusicPlayer.js)

var MusicPlayerModule = (function() {

var currentTrack = undefined;

return { play: function(track) { currentTrack = ajax.getTrackObject(); }, getTitle: function() { return currentTrack.title; } };

})();

Usage

<script src="scripts/MusicPlayer.js"></script>

// Get track and play it var trackId = 'EOUyefhfeaku'; MusicPlayerModule.play(trackId);

// Get module state: currentTrack MusicPlayerModule.getTitle();

Page 14: Frontend JS workflow - Gulp 4 and the like

AMD

Module (MusicPlayer.js)

define('MusicPlayerModule', ['ajax'], function (requester) {

var currentTrack = undefined;

return { play: function(track) { currentTrack = requester.getTrackObject(); }, getTitle: function() { return currentTrack.title; } }; });

Import (main.js)

define('main', ['MusicPlayerModule'], function (MusicPlayer) { var trackId = 'EOUyefhfeaku';

MusicPlayer.play(trackId);

MusicPlayer.getTitle(); });

Page 15: Frontend JS workflow - Gulp 4 and the like

CommonJS

Module (MusicPlayer.js)

var requester = require('../utils/ajax.js');

var currentTrack = undefined;

exports.play = function(track) { currentTrack = requester.getTrackObject(); }; exports.getTitle = function() { return currentTrack.title; }

Import (main.js)

const MusicPlayer = require('./MusicPlayer.js');

var trackId = 'EOUyefhfeaku';

MusicPlayer.play(trackId);

MusicPlayer.getTitle();

Page 16: Frontend JS workflow - Gulp 4 and the like

ES6

Module (MusicPlayer.js)

import requester from '../utils/ajax.js';

let currentTrack = undefined;

export function play(track) { currentTrack = requester.getTrackObject(); } export function getTitle() { return currentTrack.title; }

Import (main.js)

import { play, getTitle } from './MusicPlayer.js';

var trackId = 'EOUyefhfeaku';

play(trackId);

getTitle();

Page 17: Frontend JS workflow - Gulp 4 and the like

Module loader/bundlerShip modules to the browser

Modules Implementation status: in development

Interpreted? More Compiled/Transpiled

Bundle to a single JS file

Page 18: Frontend JS workflow - Gulp 4 and the like

RequireJSBrowserifyWebpackJSPM & SystemJS ( )Rollup

ES6 Module Loader

> Bullet point comparison

Page 19: Frontend JS workflow - Gulp 4 and the like

RequireJS

ProsSyntax: mostly AMD (CommonJS support not ideal)-Works in the browser directly-RequireJS optimizer to bundle/minify-

ConsNot suited for server side/client application-Some cryptic error messages-

Page 20: Frontend JS workflow - Gulp 4 and the like

Browserify

ProsSyntax: CommonJS (+ deAMDify & debowerify)-Backed up by the huge npm community-Client-side and server-side modules-Shim Node.js modules-

(deAMDify translate AMD modules to Node-style modules automatically)

- List of transforms

ConsNeed a tool to watch and bundle ( )- watchifyTightly bound to Node.js ecosystem-

Page 21: Frontend JS workflow - Gulp 4 and the like

Webpack

ProsSyntax: CommonJS and AMD-Doesn't try to be compatible with node.js at all costs-Client-side and server-side modules-

(UglifyJsPlugin)- List of pluginsCons

Configuration over convention-More features in its core (less modular) but also a pro-

> browserify for webpack users

Page 22: Frontend JS workflow - Gulp 4 and the like

JSPM featuring SystemJS

ProsSyntax: - ES6, CommonJS, AMD...Compliant with the ES6 modules specification and future-friendly-No bundling needed (like RequireJS) = no watcher-Bundling optional-

(similar to Webpack loaders plugins)- List of pluginsCons

Needs better performances-...but doesn't matter in dev since bundling is not needed-

Page 23: Frontend JS workflow - Gulp 4 and the like

Rollup

ProsSyntax: - ES6, CommonJS, AMD...... but can only optimize ES6 modules-

- live-code inclusion aka tree-shaking- List of plugins

ConsYet another module bundler-...but will probably be integrated into - SystemJS

> rollup-starter-project

Page 24: Frontend JS workflow - Gulp 4 and the like

Rollup tree shakingutils.js

var foo = {}; foo.a = 1;

var bar = {}; bar.b = 2;

export { foo, bar };

main.js

import { foo, bar } from './utils.js';

console.log( foo.a );

bundle.js

'use strict';

var foo = {}; foo.a = 1;

console.log( foo.a );

Page 25: Frontend JS workflow - Gulp 4 and the like

Task runner / Build systemAutomate

Page 26: Frontend JS workflow - Gulp 4 and the like

gruntgulp

Page 27: Frontend JS workflow - Gulp 4 and the like

Grunt

Page 28: Frontend JS workflow - Gulp 4 and the like

Gulp

Page 29: Frontend JS workflow - Gulp 4 and the like

Other attempts

Broccoli

Brunch

FlyJS

...

Page 30: Frontend JS workflow - Gulp 4 and the like

State of affairsTask Runner Usage

Gulp 44%

Grunt 28%

Others 9%

No task runner 20%

Source: The State of Front-End Tooling – 2015

Page 31: Frontend JS workflow - Gulp 4 and the like

What is new in Gulp 4?What is Gulp?

Changes in Gulp 4

Page 32: Frontend JS workflow - Gulp 4 and the like

What is Gulp?Gulp StreamGulp APIGulp CLI

Page 33: Frontend JS workflow - Gulp 4 and the like

Gulp: The streaming build system.

Grunt: multiple file read/write (requires src and dest)Gulp: streams src.pipe(b).pipe(c).pipe(d)

Page 34: Frontend JS workflow - Gulp 4 and the like

Gulp API

.src() and .dest()

gulp.src([̀${config.src}/images/**/*̀, ̀!${config.src}/images/{sprite,sprite/**}̀])

A 'glob' is a pattern that allow us to select or exclude a set of files.

=> returns a stream that we can 'pipe'

.pipe(imagemin())

=> transforms the files from the stream (minify them)

.pipe(gulp.dest(̀${config.dist}/images̀));

=> writes the minified files to the system

gulp.src([̀${config.src}/images/**/*̀, ̀!${config.src}/images/{sprite,sprite/**}̀]) .pipe(imagemin()) .pipe(gulp.dest(̀${config.dist}/images̀));

Page 35: Frontend JS workflow - Gulp 4 and the like

Gulp API

.task() and .watch()

gulp.task('images', function() {

return gulp.src([̀${config.src}/images/**/*̀, ̀!${config.src}/images/{sprite,sprite/**}̀ .pipe(imagemin()) .pipe(gulp.dest(̀${config.dist}/images̀));

});

=> programmatic API for task dependencies and .watch()

gulp.task('serve', ['images', 'takeABreak', 'smile'], function() { // Serve once the images, takeABreak and smile tasks have completed ... });

gulp.watch(̀${config.src}/images/**/*̀, ['images']);

=> ... and more importantly to the CLI

$ gulp images

Page 36: Frontend JS workflow - Gulp 4 and the like

Gulp CLI

$ gulp <task> <othertask>

$ npm install gulp-cli -g

gulp --gulpfile <gulpfile path> # will manually set path of gulpfile. gulp --cwd <dir path> # will manually set the CWD. gulp --tasks # will display the task dependency tree for the loaded gulpfile. gulp --verify # will verify plugins in package.json against the plugins blacklist

Full list of arguments

Page 37: Frontend JS workflow - Gulp 4 and the like

Changes in Gulp 4$ npm install -g gulpjs/gulp-cli#4.0

package.json

"devDependencies": { "gulp": "github:gulpjs/gulp#4.0", ... }

Slight API changes

New task system

See dmnsgn/gulp-frontend-boilerplate

Page 38: Frontend JS workflow - Gulp 4 and the like

Slight API changes

gulp.src()gulp.dest()gulp.watch()gulp.task() (new syntax) 3 arguments

gulp.parallel()gulp.series()

+ gulp.symlink(), gulp.lastRun(), gulp.tree(), gulp.registry()

Page 39: Frontend JS workflow - Gulp 4 and the like

gulp.series() and gulp.parallel()using run-sequence (Gulp 3)

runSequence( ['markup', 'styles', 'scripts', 'images'], ['serve', 'watch'], callback );

index.js (Gulp 4)

gulp.series( gulp.parallel(markup, 'styles', 'scripts', 'images'), gulp.parallel(serve, watch) )

Page 40: Frontend JS workflow - Gulp 4 and the like

New task system

Gulp 3

gulp.task('serve', ['markup', 'styles', 'scripts'], function(done) {

return browserSync.init({}, done);

});

Gulp 4 (two arguments syntax)images.js

export function optimizeImages() { ... } export function generateSpritesheet() { ... } export function generateFavicons() { ... }

gulpfile.js

import { optimizeImages, generateSpritesheet, generateFavicons } from './images'; ... gulp.task( 'images', gulp.parallel(optimizeImages, generateSpritesheet, generateFavicons) );

Page 41: Frontend JS workflow - Gulp 4 and the like

Gulp 4 (one argument syntax)gulpfile.js

CLI

var gulp = require('gulp'); var del = require('del');

gulp.task(function clean() { return del([̀./dist/**̀, ̀!./dist̀ ,̀!./dist/static/**̀]; });

$ gulp clean

Page 42: Frontend JS workflow - Gulp 4 and the like

Reusable modulesclean.js

gulpfile.js

import 'del' from 'del';

export function clean() { return del([̀./dist/**̀, ̀!./dist̀ ,̀!./dist/static/**̀]); }

import { clean } from './clean'; ... gulp.task(clean);

Page 43: Frontend JS workflow - Gulp 4 and the like

Are task-runner still relevant?What to expect in 2016?

npm scripts to replace task-runner

JS fatigue

Page 44: Frontend JS workflow - Gulp 4 and the like

 scriptsShould we stop using build tools like Gulp?

How to use npm scripts

Are npm scripts the solution?

Page 45: Frontend JS workflow - Gulp 4 and the like

Should we stop using build tools like Gulp?

Plugins often an existing NodeJS packageRely on global dependencies (grunt-cli, gulp-cli, broccoli-cli...)Most tasks can be achieved using basic terminal commands

wrapper around

Page 46: Frontend JS workflow - Gulp 4 and the like

How to use   scripts

$ npm start # default script $ npm run script-name # custom script

package.json

{ "devDependencies": { "babelify": "̂6.1.x", "browser-sync": "̂2.7.x", "browserify": "̂10.2.x", "npm-run-all": "̂1.5.0", ... }, "scripts": { "dev": "npm-run-all --parallel dev:scripts dev:styles serve", "build": "npm-run-all --parallel build:scripts build:styles rimraf dist/*.map", "clean": "rimraf dist/{*.css,*.js,*.map}", "serve": "browser-sync start --server 'dist' --files 'dist/*.css, dist/*.html, dist/*.js' --no-ui" "dev:scripts": "watchify -d src/scripts/main.js -t [babelify] -o dist/main.js", "dev:styles": "stylus src/styles/main.styl -w -o dist/ -m", "build:scripts": "browserify -d src/scripts/main.js -t [babelify] -o dist/main.js && uglifyjs dist/main.js -o dist/main.js" "build:styles": "stylus src/styles/main.styl -o dist/ -c" } }

Page 47: Frontend JS workflow - Gulp 4 and the like

Are npm scripts the solution?

pros

Fast configuration and buildAll config in one place: package.jsonNo extra global dependency

...& cons

Readability of the commandsCompatibility between UNIX and Windows systems

Page 48: Frontend JS workflow - Gulp 4 and the like

2016JavaScript fatigue

Doctor's prescription

Page 49: Frontend JS workflow - Gulp 4 and the like

JS fatigue

A new JS framework a dayToo many tools

2015: JavaScript tool X was useful 2016: Make X easier to install/setup/use for all newusers. Minimize dependency & configuration hell.

— Addy Osmani (@addyosmani) January 8, 2016

Controversial articles (some probably missing the point)- Stop pushing the web forward- Javascript Fatigue- State of the Union.js- Solar system of JS

Page 50: Frontend JS workflow - Gulp 4 and the like

Why it is not a problem if you keep the UX in mind by - The Controversial State of JavaScript Tooling Nicolás

Bevacqua (@ponyfoo) by - Why I love working with the web Remy Sharp (@rem) by - If we stand still, we go backwards Jake Archibald

(@jaffathecake)

Just because it's there, doesn't mean you mustlearn it and use it. [...] No one can be an expert inthe whole web. [...] The great thing about the web

is it doesn't hit 1.0 and stop, it's continual.

Page 51: Frontend JS workflow - Gulp 4 and the like

Piece of advice (my two-penn'orth)

Pick styleguidesPick the right scaffoldStick with it (at least this year)

Stay curious though

Page 52: Frontend JS workflow - Gulp 4 and the like