Categories: Uncategorized

[Grunt][CoffeeScript]Make minified JS from CoffeeScript when source file is updated

Contents


Target

Make a system to monitor source files, do tests, compile and minify when the files are updated.
We can realize it using grunt.

Install

Let’s install modules with package.json and “npm install”.
Following grunt are needed.
{
  "name": "sample",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "mocha": "1.14.0",
    "chai":  "*",
    "coffee-script": "1.6.3",
    "sinon": "1.7.3",
    "grunt": "0.4.2",
    "grunt-cli": "0.1.11",
    "grunt-contrib-watch": "0.5.3",
    "grunt-coffeelint": "0.0.7",
    "grunt-contrib-coffee": "0.7.0",
    "grunt-simple-mocha": "0.4.0",
    "grunt-contrib-uglify": "0.2.7"
  }
}

Gruntfile.coffee

Following is Grunt config file.
module.exports = (grunt) ->

  grunt.initConfig
    pkg: grunt.file.readJSON 'package.json'

    coffeelint:
      app:
        files:
          src: [
            'models/*.coffee'
            'specs/*.coffee'
          ]

    simplemocha:
      all:
        src: ['specs/*.coffee']
      options:
        reporter: 'nyan'
        ui: 'bdd'

    coffee:
      compile:
        files: [
          'libs/something.js': 'models/something.coffee',
          'libs/something2.js': 'models/something2.coffee'
        ]
      options:
        bare: yes

    uglify:
      compress_target:
        options:
          sourceMap: (fileName) ->
            fileName.replace /\.js$/, '.js.map'
        files: [
          expand: true,
          cwd: 'libs/',
          src: ['*.js'],
          dest: 'libs/',
          ext: '.min.js'
        ]
 watch:
      scripts:
        files: [
          'models/*.coffee'
          'specs/*.coffee'
        ]
        tasks: [
          #'coffeelint'
          'coffee'
          'simplemocha'
          'uglify'
        ]
        options:
          interrupt: yes

  grunt.loadNpmTasks 'grunt-coffeelint'
  grunt.loadNpmTasks 'grunt-simple-mocha'
  grunt.loadNpmTasks 'grunt-contrib-coffee'
  grunt.loadNpmTasks 'grunt-contrib-watch'
  grunt.loadNpmTasks 'grunt-contrib-uglify'

  grunt.registerTask 'default', [
    #'coffeelint'
    'coffee'
    'simplemocha'
    'uglify'
  ]

watch

Following watch part is monitoring files.
watch:
      scripts:
        files: [
          'models/*.coffee'
          'specs/*.coffee'
        ]
        tasks: [
          #'coffeelint'
          'coffee'
          'simplemocha'
          'uglify'
        ]
        options:
          interrupt: yes

“files” specialize files for monitoring.
“tasks” specialize tasks which are done when files are updated.

coffee

Following part is compiling coffee scripts.
 coffee:
      compile:
        files: [
          'libs/something.js': 'models/something.coffee',
          'libs/something2.js': 'models/something2.coffee'
        ]
      options:
        bare: yes

Left part of “:” in files is path of output compiled file.
Right part of “:” in files is compile target;

simplemocha

Following is test part.
“src:” part specializes mocha test file.
    simplemocha:
      all:
        src: ['specs/*.coffee']
      options:
        reporter: 'nyan'
        ui: 'bdd'

uglify

Following part is minifying source code.
Files of src in cwd are output to dest path.
The files extension is ext.
    uglify:
      compress_target:
        options:
          sourceMap: (fileName) ->
            fileName.replace /\.js$/, '.js.map'
        files: [
          expand: true,
          cwd: 'libs/',
          src: ['*.js'],
          dest: 'libs/',
          ext: '.min.js'
        ]

Result

Terminal shows like following when source files are updated with grunt watch command.
$grunt watch
Waiting...
OK
>> File "specs/something1.coffee" changed.

Running "coffee:compile" (coffee) task
File libs/something1.js created.
File libs/something2.js created.

Running "simplemocha:all" (simplemocha) task
 5   -_-_-__,------,
 0   -_-_-__|  /\_/\
 0   -_-_-_~|_( ^ .^)
     -_-_-_ ""  ""

  5 passing (66ms)

Running "uglify:compress_target" (uglify) task
Source Map "libs/something2.min.js.map" created.
File "libs/something1.min.js" created.
Source Map "libs/something1.min.js.map" created.
File "libs/something1.min.js" created.

Done, without errors.
Completed in 2.046s at Sun Nov 24 2013 18:14:35 GMT+0900 (JST) - Waiting...
zuqqhi2