Created
July 22, 2014 22:09
-
-
Save jswartwood/b0e097812b4adf6da0ed to your computer and use it in GitHub Desktop.
Sails v0.9.x Gruntfile to include support for Web Components and Jade, Stylus, & ES6 preprocessing (including within components)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Gruntfile | |
* | |
* If you created your Sails app with `sails new foo --linker`, | |
* the following files will be automatically injected (in order) | |
* into the EJS and HTML files in your `views` and `assets` folders. | |
* | |
* At the top part of this file, you'll find a few of the most commonly | |
* configured options, but Sails' integration with Grunt is also fully | |
* customizable. If you'd like to work with your assets differently | |
* you can change this file to do anything you like! | |
* | |
* More information on using Grunt to work with static assets: | |
* http://gruntjs.com/configuring-tasks | |
*/ | |
module.exports = function (grunt) { | |
/** | |
* CSS files to inject in order | |
* (uses Grunt-style wildcard/glob/splat expressions) | |
* | |
* By default, Sails also supports LESS in development and production. | |
* To use SASS/SCSS, Stylus, etc., edit the `sails-linker:devStyles` task | |
* below for more options. For this to work, you may need to install new | |
* dependencies, e.g. `npm install grunt-contrib-sass` | |
*/ | |
var cssFilesToInject = [ | |
'linker/**/*.css' | |
]; | |
/** | |
* Javascript files to inject in order | |
* (uses Grunt-style wildcard/glob/splat expressions) | |
* | |
* To use client-side CoffeeScript, TypeScript, etc., edit the | |
* `sails-linker:devJs` task below for more options. | |
*/ | |
var jsFilesToInject = [ | |
// Below, as a demonstration, you'll see the built-in dependencies | |
// linked in the proper order order | |
// Bring in the socket.io client | |
'linker/scripts/socket.io.js', | |
// then beef it up with some convenience logic for talking to Sails.js | |
'linker/scripts/sails.io.js', | |
// A simpler boilerplate library for getting you up and running w/ an | |
// automatic listener for incoming messages from Socket.io. | |
'linker/scripts/app.js', | |
// *-> put other dependencies here <-* | |
// All of the rest of your app scripts imported here | |
'linker/**/*.js' | |
]; | |
/** | |
* Client-side HTML templates are injected using the sources below | |
* The ordering of these templates shouldn't matter. | |
* (uses Grunt-style wildcard/glob/splat expressions) | |
* | |
* By default, Sails uses JST templates and precompiles them into | |
* functions for you. If you want to use jade, handlebars, dust, etc., | |
* edit the relevant sections below. | |
*/ | |
var templateFilesToInject = [ | |
'linker/**/*.html' | |
]; | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
// | |
// DANGER: | |
// | |
// With great power comes great responsibility. | |
// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
///////////////////////////////////////////////////////////////// | |
// Modify css file injection paths to use | |
cssFilesToInject = cssFilesToInject.map(function (path) { | |
return '.tmp/public/' + path; | |
}); | |
// Modify js file injection paths to use | |
jsFilesToInject = jsFilesToInject.map(function (path) { | |
return '.tmp/public/' + path; | |
}); | |
templateFilesToInject = templateFilesToInject.map(function (path) { | |
return 'assets/' + path; | |
}); | |
// Get path to core grunt dependencies from Sails | |
var depsPath = grunt.option('gdsrc') || 'node_modules/sails/node_modules'; | |
grunt.loadTasks(depsPath + '/grunt-contrib-clean/tasks'); | |
grunt.loadTasks(depsPath + '/grunt-contrib-copy/tasks'); | |
grunt.loadTasks(depsPath + '/grunt-contrib-concat/tasks'); | |
grunt.loadTasks(depsPath + '/grunt-sails-linker/tasks'); | |
grunt.loadTasks(depsPath + '/grunt-contrib-jst/tasks'); | |
grunt.loadTasks(depsPath + '/grunt-contrib-watch/tasks'); | |
grunt.loadTasks(depsPath + '/grunt-contrib-uglify/tasks'); | |
grunt.loadTasks(depsPath + '/grunt-contrib-cssmin/tasks'); | |
grunt.loadTasks(depsPath + '/grunt-contrib-coffee/tasks'); | |
grunt.loadNpmTasks('grunt-contrib-stylus'); | |
grunt.loadNpmTasks('grunt-contrib-jade'); | |
grunt.loadNpmTasks('grunt-esnext'); | |
grunt.loadNpmTasks('grunt-inline'); | |
// Project configuration. | |
grunt.initConfig({ | |
pkg: grunt.file.readJSON('package.json'), | |
copy: { | |
dev: { | |
files: [ | |
{ | |
expand: true, | |
cwd: './assets', | |
src: ['**/*.!(coffee)'], | |
dest: '.tmp/public' | |
} | |
] | |
}, | |
build: { | |
files: [ | |
{ | |
expand: true, | |
cwd: '.tmp/public', | |
src: ['**/*'], | |
dest: 'www' | |
} | |
] | |
} | |
}, | |
clean: { | |
dev: ['.tmp/public/**'], | |
build: ['www'] | |
}, | |
jst: { | |
dev: { | |
// To use other sorts of templates, specify the regexp below: | |
// options: { | |
// templateSettings: { | |
// interpolate: /\{\{(.+?)\}\}/g | |
// } | |
// }, | |
files: { | |
'.tmp/public/jst.js': templateFilesToInject | |
} | |
} | |
}, | |
jade: { | |
dev: { | |
options: { | |
}, | |
files: [ | |
{ // Jade on Web Components too! | |
expand: true, | |
cwd: 'assets/components/', | |
src: ['**/*.jade'], | |
dest: '.tmp/public/components/', | |
ext: '.html' | |
}, { | |
expand: true, | |
cwd: 'assets/linker/components/', | |
src: ['**/*.jade'], | |
dest: '.tmp/public/linker/components/', | |
ext: '.html' | |
} | |
] | |
} | |
}, | |
stylus: { | |
dev: { | |
options: { | |
paths: [ | |
'assets/styles/lib/' | |
], | |
import: [ | |
'nib', | |
'colors' | |
] | |
}, | |
files: [ | |
{ | |
expand: true, | |
cwd: 'assets/styles/', | |
src: ['*.styl'], | |
dest: '.tmp/public/styles/', | |
ext: '.css' | |
}, { | |
expand: true, | |
cwd: 'assets/linker/styles/', | |
src: ['*.styl'], | |
dest: '.tmp/public/linker/styles/', | |
ext: '.css' | |
}, { // Stylus on Web Components too! | |
expand: true, | |
cwd: 'assets/components/', | |
src: ['**/*.styl'], | |
dest: '.tmp/public/components/', | |
ext: '.css' | |
}, { | |
expand: true, | |
cwd: 'assets/linker/components/', | |
src: ['**/*.styl'], | |
dest: '.tmp/public/linker/components/', | |
ext: '.css' | |
} | |
] | |
} | |
}, | |
esnext: { | |
dev: { | |
options: { | |
includeRuntime: false | |
}, | |
files: [ | |
{ | |
expand: true, | |
cwd: 'assets/scripts/', | |
src: ['**/*.js'], | |
dest: '.tmp/public/scripts/', | |
ext: '.js' | |
}, { | |
expand: true, | |
cwd: 'assets/linker/scripts/', | |
src: ['**/*.js'], | |
dest: '.tmp/public/linker/scripts/', | |
ext: '.js' | |
}, { // ESNext on Web Components too! | |
expand: true, | |
cwd: 'assets/components/', | |
src: ['**/*.js'], | |
dest: '.tmp/public/components/', | |
ext: '.js' | |
}, { | |
expand: true, | |
cwd: 'assets/linker/components/', | |
src: ['**/*.js'], | |
dest: '.tmp/public/linker/components/', | |
ext: '.js' | |
} | |
] | |
} | |
}, | |
coffee: { | |
dev: { | |
options:{ | |
bare:true | |
}, | |
files: [ | |
{ | |
expand: true, | |
cwd: 'assets/scripts/', | |
src: ['**/*.coffee'], | |
dest: '.tmp/public/scripts/', | |
ext: '.js' | |
}, { | |
expand: true, | |
cwd: 'assets/linker/scripts/', | |
src: ['**/*.coffee'], | |
dest: '.tmp/public/linker/scripts/', | |
ext: '.js' | |
} | |
] | |
} | |
}, | |
inline: { | |
dev: { | |
src: [ | |
'.tmp/public/components/**/*.html', | |
'.tmp/public/linker/components/**/*.html', | |
] | |
} | |
}, | |
concat: { | |
js: { | |
src: jsFilesToInject, | |
dest: '.tmp/public/concat/production.js' | |
}, | |
css: { | |
src: cssFilesToInject, | |
dest: '.tmp/public/concat/production.css' | |
} | |
}, | |
uglify: { | |
dist: { | |
src: ['.tmp/public/concat/production.js'], | |
dest: '.tmp/public/min/production.js' | |
} | |
}, | |
cssmin: { | |
dist: { | |
src: ['.tmp/public/concat/production.css'], | |
dest: '.tmp/public/min/production.css' | |
} | |
}, | |
'sails-linker': { | |
devJs: { | |
options: { | |
startTag: '<!--SCRIPTS-->', | |
endTag: '<!--SCRIPTS END-->', | |
fileTmpl: '<script src="%s"></script>', | |
appRoot: '.tmp/public' | |
}, | |
files: { | |
'.tmp/public/**/*.html': jsFilesToInject, | |
'views/**/*.html': jsFilesToInject, | |
'views/**/*.ejs': jsFilesToInject | |
} | |
}, | |
prodJs: { | |
options: { | |
startTag: '<!--SCRIPTS-->', | |
endTag: '<!--SCRIPTS END-->', | |
fileTmpl: '<script src="%s"></script>', | |
appRoot: '.tmp/public' | |
}, | |
files: { | |
'.tmp/public/**/*.html': ['.tmp/public/min/production.js'], | |
'views/**/*.html': ['.tmp/public/min/production.js'], | |
'views/**/*.ejs': ['.tmp/public/min/production.js'] | |
} | |
}, | |
devStyles: { | |
options: { | |
startTag: '<!--STYLES-->', | |
endTag: '<!--STYLES END-->', | |
fileTmpl: '<link rel="stylesheet" href="%s">', | |
appRoot: '.tmp/public' | |
}, | |
// cssFilesToInject defined up top | |
files: { | |
'.tmp/public/**/*.html': cssFilesToInject, | |
'views/**/*.html': cssFilesToInject, | |
'views/**/*.ejs': cssFilesToInject | |
} | |
}, | |
prodStyles: { | |
options: { | |
startTag: '<!--STYLES-->', | |
endTag: '<!--STYLES END-->', | |
fileTmpl: '<link rel="stylesheet" href="%s">', | |
appRoot: '.tmp/public' | |
}, | |
files: { | |
'.tmp/public/index.html': ['.tmp/public/min/production.css'], | |
'views/**/*.html': ['.tmp/public/min/production.css'], | |
'views/**/*.ejs': ['.tmp/public/min/production.css'] | |
} | |
}, | |
// Bring in JST template object | |
devTpl: { | |
options: { | |
startTag: '<!--TEMPLATES-->', | |
endTag: '<!--TEMPLATES END-->', | |
fileTmpl: '<script type="text/javascript" src="%s"></script>', | |
appRoot: '.tmp/public' | |
}, | |
files: { | |
'.tmp/public/index.html': ['.tmp/public/jst.js'], | |
'views/**/*.html': ['.tmp/public/jst.js'], | |
'views/**/*.ejs': ['.tmp/public/jst.js'] | |
} | |
}, | |
/******************************************* | |
* Jade linkers (TODO: clean this up) | |
*******************************************/ | |
devJsJADE: { | |
options: { | |
startTag: '// SCRIPTS', | |
endTag: '// SCRIPTS END', | |
fileTmpl: 'script(type="text/javascript", src="%s")', | |
appRoot: '.tmp/public' | |
}, | |
files: { | |
'views/**/*.jade': jsFilesToInject | |
} | |
}, | |
prodJsJADE: { | |
options: { | |
startTag: '// SCRIPTS', | |
endTag: '// SCRIPTS END', | |
fileTmpl: 'script(type="text/javascript", src="%s")', | |
appRoot: '.tmp/public' | |
}, | |
files: { | |
'views/**/*.jade': ['.tmp/public/min/production.js'] | |
} | |
}, | |
devStylesJADE: { | |
options: { | |
startTag: '// STYLES', | |
endTag: '// STYLES END', | |
fileTmpl: 'link(rel="stylesheet", href="%s")', | |
appRoot: '.tmp/public' | |
}, | |
files: { | |
'views/**/*.jade': cssFilesToInject | |
} | |
}, | |
prodStylesJADE: { | |
options: { | |
startTag: '// STYLES', | |
endTag: '// STYLES END', | |
fileTmpl: 'link(rel="stylesheet", href="%s")', | |
appRoot: '.tmp/public' | |
}, | |
files: { | |
'views/**/*.jade': ['.tmp/public/min/production.css'] | |
} | |
}, | |
// Bring in JST template object | |
devTplJADE: { | |
options: { | |
startTag: '// TEMPLATES', | |
endTag: '// TEMPLATES END', | |
fileTmpl: 'script(type="text/javascript", src="%s")', | |
appRoot: '.tmp/public' | |
}, | |
files: { | |
'views/**/*.jade': ['.tmp/public/jst.js'] | |
} | |
} | |
/************************************ | |
* Jade linker end | |
************************************/ | |
}, | |
watch: { | |
api: { | |
// API files to watch: | |
files: ['api/**/*'] | |
}, | |
assets: { | |
// Assets to watch: | |
files: ['assets/**/*'], | |
// When assets are changed: | |
tasks: ['compileAssets', 'linkAssets'] | |
} | |
} | |
}); | |
// When Sails is lifted: | |
grunt.registerTask('default', [ | |
'compileAssets', | |
'linkAssets', | |
'watch' | |
]); | |
grunt.registerTask('compileAssets', [ | |
'clean:dev', | |
'jst:dev', | |
'jade:dev', | |
'stylus:dev', | |
'copy:dev', | |
'coffee:dev', | |
'esnext:dev', | |
'inline:dev', | |
]); | |
grunt.registerTask('linkAssets', [ | |
// Update link/script/template references in `assets` index.html | |
'sails-linker:devJs', | |
'sails-linker:devStyles', | |
'sails-linker:devTpl', | |
'sails-linker:devJsJADE', | |
'sails-linker:devStylesJADE', | |
'sails-linker:devTplJADE' | |
]); | |
// Build the assets into a web accessible folder. | |
// (handy for phone gap apps, chrome extensions, etc.) | |
grunt.registerTask('build', [ | |
'compileAssets', | |
'linkAssets', | |
'clean:build', | |
'copy:build' | |
]); | |
// When sails is lifted in production | |
grunt.registerTask('prod', [ | |
'clean:dev', | |
'jst:dev', | |
'jade:dev', | |
'stylus:dev', | |
'copy:dev', | |
'coffee:dev', | |
'esnext:dev', | |
'inline:dev', | |
'concat', | |
'uglify', | |
'cssmin', | |
'sails-linker:prodJs', | |
'sails-linker:prodStyles', | |
'sails-linker:devTpl', | |
'sails-linker:prodJsJADE', | |
'sails-linker:prodStylesJADE', | |
'sails-linker:devTplJADE' | |
]); | |
// When API files are changed: | |
// grunt.event.on('watch', function(action, filepath) { | |
// grunt.log.writeln(filepath + ' has ' + action); | |
// // Send a request to a development-only endpoint on the server | |
// // which will reuptake the file that was changed. | |
// var baseurl = grunt.option('baseurl'); | |
// var gruntSignalRoute = grunt.option('signalpath'); | |
// var url = baseurl + gruntSignalRoute + '?action=' + action + '&filepath=' + filepath; | |
// require('http').get(url) | |
// .on('error', function(e) { | |
// console.error(filepath + ' has ' + action + ', but could not signal the Sails.js server: ' + e.message); | |
// }); | |
// }); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment