Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Streamlining Frontend Development with Node.js

Avatar for Phil Mander Phil Mander
November 26, 2014

Streamlining Frontend Development with Node.js

In recent years the Node.js ecosystem has transformed frontend development. In this talk we'll discuss how Node based tools like Gulp, Grunt, Browserify and Bower can help improve your productivity and create better quality web frontends.

Avatar for Phil Mander

Phil Mander

November 26, 2014
Tweet

Other Decks in Technology

Transcript

  1. What is ? • More than just “JS on the

    server” • Node.JS makes Javascript run anywhere! • Great tools available for frontend developers • Many choices...
  2. Common tools • Linting: JSHint, JSLint, ESLint • Minify JS:

    UglifyJS, JSMin, Closure compiler (JVM) • Preprocessors: Coffeescript, Typescript, Traceur (ES6) • CSS Preprocessors: SASS, LESS • Testing: Karma, Jasmine, Mocha, etc • Dependency Management: Bower, NPM • Packaging: Browserify, Webpack • Scaffolding: Yeoman ...and easy to create your own tooling
  3. Grunt ★8,780 grunt.initConfig({ jshint: { files: ['./lib/**/*.js'], jshintrc: './.jshintrc' },

    browserify: { main: { src: ['./lib/index.js'], dest: './dist/calc.js', options: { standalone: ['calc'] } } } }); grunt.loadNpmTasks('grunt-jshint'); grunt.loadNpmTasks('grunt-browserify'); grunt.registerTask('default', ['jshint', 'browserify']); • Similar to Ant, but Javascript and JSON like config • Easy to use • Can get bloated, can be slow
  4. Gulp ★9,890 • Task runner like Grunt • Connects plugins

    within tasks using Node streams (fast) • Unix philosophy of plugins doing one thing well var gulp = require('gulp'); var jshint = require('gulp-jshint'); var browserify = require('browserify'); gulp.task('lint', function() { return gulp.src('./lib/**/*.js') .pipe(jshint()) .pipe(jshint.reporter(‘default’)) }); gulp.task('package', [ 'jshint' ], function() { return browserify({ entries: './lib/index.js', standalone: ‘calc’ }) .bundle() .pipe(vinylStream('calc.js') .pipe(gulp.dest('./dist')); }); gulp.task('default', [ 'package' ]);
  5. Broccoli ★1,694 var compileSass = require('broccoli-sass'); var pickFiles = require('broccoli-static-compiler');

    var styles = 'styles'; styles = pickFiles(styles, { srcDir: '/', destDir: 'styles' }); var sourceTrees = [ styles ]; var appCss = compileSass(sourceTrees, 'styles/calc.scss', 'styles/calc. css'); module.exports = appCss; • Inspired by Rails Asset Pipeline • Adopted by Ember.js • Goal to achieve better performance compiling file trees like SASS • Run it standalone or from within a task runner • File format not very intuitive
  6. Focus on Gulp: How it works Gulp = Orchestrator +

    Node Streams + Vinyl • Orchestrator: the task runner • Node streams: node streams • Vinyl: virtual file wrapper to pass through streams
  7. Focus on Gulp: How it works pipe pipe Filesystem Vinyl

    Adapters + globs Plugins gulp.src(**/*.js) gulp.dest(./dest)
  8. Focus on Gulp: Creating Plugins //extend Node Transform stream function

    AlertStream(alertMessage) { //call super stream.Transform.call(this, { objectMode: true }); //the message to append as an alert this.alertMessage = alertMessage; } util.inherits(AlertStream, stream.Transform); //implement the _transform method AlertStream.prototype._transform = function(chunk, encoding, callback) { //implementation here }; //export factory to create instance module.exports = function(opt) { return new AlertStream(opt); }; • https://github.com/philmander/node4fe/blob/master/gulp/gulp-alert.js • Look! No Gulp… Just streams • Consider using through2 for real Gulp plugins
  9. Bower npm install bower -g bower install react-bower <script src=/bower_components/react/react.min.js></script>

    ★11,249 • Now ubiquitous frontend package manager • Very simple ◦ manage dependencies in bower.json ◦ resolved published Bower packages ◦ or point to a Github repo
  10. NPM • Possible to use as a browser-side dependency manager

    <script src=/node_modules/react/react.js> • Problems: ◦ node_modules isn’t arranged the way front-end packages need it to be ◦ Front-end dependencies have different conflict- resolution needs ◦ Maintaining multiple package manifests is annoying ◦ Finding browser-compatible packages is a pain http://blog.npmjs.org/post/101775448305/npm-and-front-end-packaging
  11. Browserify • Author Frontend apps in Node. • Use CommonJS

    module system + NPM • Parses require calls and outputs all dependencies to one file • Shims Node JS specific APIs for the browser • You may externalize shared libraries • Beware of performance implications when requiring external modules ★5,834
  12. Webpack • Similar to Browserify • Supports more features: ◦

    Different module formats (e.g. AMD) ◦ Can split output across files ★2,375
  13. #4 Unit testing • Karma ◦ X-browser unit testing harness

    ◦ Runs nicely with Phantom.JS on command line • Run tests in Node with Browserify ◦ Unit tests test logic, not browser compatibility ◦ Encourages you to Mock things (JSDom, etc) • Jasmine, Mocha, QUnit
  14. Don’t forget your users! • Your users don’t care about

    your build tooling! • Don’t lose focus on the end-product • Watch this video:
  15. TL;DL • Lots of tools out there, the hard part

    is choosing your stack • Build tools ◦ My preference Gulp ◦ But make your own decision based on your context • Use Bower (or similar) • Checkout Browserify or Webpack • Automation is good! But approach with caution