Skip to content

Instantly share code, notes, and snippets.

@julienhay
Created January 13, 2015 09:08
Show Gist options
  • Save julienhay/26e70f3b6b682455431d to your computer and use it in GitHub Desktop.
Save julienhay/26e70f3b6b682455431d to your computer and use it in GitHub Desktop.
gulp litcoffee

Gulpfile

Create React component using:

  • Coffescript

    • Preprocessing for javascript language
  • React / JSX

    • Javascript library that allow to create component that mixed View (HTML) and Controller (JS) with the MVVM pattern
  • Browserify

    • Allow to refresh the browser on files changes

Here is what happen in the build directory:

  1. Coffescript files are transformed in JSX
  2. JSX files are transformed in JS
  3. JS files are bundled with Browserify
  4. Bundle file is obfuscated with UglifyJS2

Required node modules

gulp        = require("gulp")
gutil       = require("gulp-util")
coffee      = require("gulp-coffee")
react       = require("gulp-react")
compass     = require('gulp-compass')
jade        = require("gulp-jade")
source      = require("vinyl-source-stream")
uglify      = require("gulp-uglify")
del         = require("del")
exec        = require("child_process").exec
browserify  = require("browserify")
watchify    = require('watchify')
browserSync = require('browser-sync')
reload      = browserSync.reload
nodemon     = require('gulp-nodemon')
mkdirp      = require('mkdirp')
touch       = require("touch")

Paths

Configure paths for your project

paths = {}

All your sources that should remain private

paths.src        = {}
paths.src.dir    = "src"
paths.src.coffee = "#{paths.src.dir}/coffee/"
paths.src.jade   = "#{paths.src.dir}/jade/"
paths.src.sass   = "#{paths.src.dir}/sass/"

All your files that can be public

paths.public            = {}
paths.public.html       = "ressources/public/dashboard/"
paths.public.css        = "#{paths.public.html}/css/"
paths.public.javascript = "#{paths.public.html}/js/"

Temporary files, useful for debugging

paths.build     = {}
paths.build.dir = "build/"

paths.build.react     = {}
paths.build.react.jsx = "#{paths.build.dir}/jsx/"
paths.build.react.js  = "#{paths.build.dir}/js/"

paths.build.browserify             = {}
paths.build.browserify.main_coffee = "#{__dirname}/#{paths.src.coffee}/main.coffee"
paths.build.browserify.main_js     = "#{__dirname}/#{paths.build.react.js}/main.js"
paths.build.browserify.bundle      = "bundle.js"

Init tasks

gulp.task "init", ->
  mkdirp paths.src.coffee, ->
    touch "#{paths.build.browserify.main_coffee}"
  mkdirp paths.src.jade, ->
    touch "#{paths.src.jade}/index.jade"
  mkdirp paths.src.sass, ->
    touch "#{paths.src.sass}/screen.scss"

Serve tasks

Execute coffee-gulp serve to run a webserver using Browserify

gulp.task "serve", ->
  browserSync
    open: false
    notify: false

    # Run as an https by uncommenting 'https: true'
    # Note: this uses an unsigned certificate which on first access
    #       will present a certificate warning in the browser.
    # https: true,
    server: [
      "#{paths.public.html}"
    ]

Watch task

Execute coffee-gulp watch to watch for any changes in src directory and generate public/js/bundle.js

gulp.task "watch", ['serve'], ->
  nodemon
    # verbose: true
    script: 'lib/server.js'
    ext: 'js coffee'
    ignore: ['node_modules/', 'src/', 'ressources/', 'log/']
  .on 'restart', ->
    bundle()
    console.log('Server restarted!')

  gulp.watch "#{paths.src.jade}/**/*.jade", ["jade", reload]
  gulp.watch "#{paths.src.sass}/**/*.scss", ["compass", reload]

  bundler = browserify
    cache: {}, packageCache: {}, fullPaths: true,
    entries: "#{paths.build.browserify.main_coffee}"
    extensions: ['.coffee']
    debug: true

  # Mandatory for minifyify
  # watchify.args.debug = true

  bundler.transform "coffeeify"
  bundler.transform "reactify"
  bundler.transform "cssify"
  bundler.transform "brfs" # Allow to use fs.readFileSync
  # bundler.transform { global: true }, "uglifyify"

  # bundler.plugin('minifyify', {map: 'bundle.js.map', output: "#{__dirname }/public/js/bundle.js.map"});

  bundle = ->
    bundler
      .bundle()
      .on('error', gutil.log.bind(gutil, "Browserify Error"))
      .pipe(source("#{paths.build.browserify.bundle}"))
      .pipe(gulp.dest("#{paths.public.javascript}"))
      .on('end', reload)

  bundler = watchify(bundler)
  bundler.on('update', bundle)

  bundle()

Compass

Compile SASS file using Compass !! sass parameter must be relative like "src/sass", not "./src/sass" !!

gulp.task "compass", ->
  gulp.src("#{paths.src.sass}/*.scss")
  .pipe(compass({
    config_file: 'config.rb',
    sass: "#{paths.src.sass}",
    css: "#{paths.public.css}",
  }))
  .pipe gulp.dest("#{paths.public.css}")

Jade

Generate jade template in src/jade/ to public

gulp.task "jade", ->
  YOUR_LOCALS = {}
  gulp.src("#{paths.src.jade}/**/*.jade")
    .pipe(jade(locals: YOUR_LOCALS, pretty: true))
    .pipe gulp.dest("#{paths.public.html}")

STEP 1

Transform all coffeescript files in src to JSX files into build/jsx

gulp.task "coffee", ->
  gulp.src("#{paths.src.coffee}/**/*.coffee")
    .pipe(coffee(bare: true).on("error", console.log))
    .pipe gulp.dest("#{paths.build.react.jsx}")

STEP 2

Transform all JSX files in build/jsx to JS files into build/js

gulp.task "react", ["coffee"], ->
  gulp.src("#{paths.build.react.jsx}/**/*.js")
    .pipe(react())
    .pipe gulp.dest("#{paths.build.react.js}")

STEP 3

Bundle all JS files to a single build/bundle.js file

gulp.task "browserify", ["react"], ->
  browserify("#{paths.build.browserify.main_js}")
    .bundle()
    .pipe(source("#{paths.build.browserify.bundle}"))
    .pipe gulp.dest("#{paths.build.dir}")

STEP 4

Obfuscated build/bundle.js file and publish it to public/js/bundle.js

gulp.task "compress", ["browserify"], ->
  gulp.src("#{paths.build.dir}/*.js")
  .pipe(uglify())
  .pipe gulp.dest("#{paths.public.javascript}")

Utilities task

###Cleanup task

gulp.task "clean", ->
  del ["#{paths.build.dir}"]

###Doc generation task

gulp.task "doc", ->
  exec "docco gulpfile.litcoffee"

Responsive Framework integration

###Compass

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment