Skip to content

Instantly share code, notes, and snippets.

@soulcutter
Created September 23, 2013 23:17
Show Gist options
  • Save soulcutter/6678305 to your computer and use it in GitHub Desktop.
Save soulcutter/6678305 to your computer and use it in GitHub Desktop.
Grunt / Angular setup based originally on Yeoman
{
"name": "rick",
"version": "0.0.0",
"dependencies": {
"angular": "~1.0.7",
"json3": "~3.2.4",
"es5-shim": "~2.0.8",
"angular-resource": "~1.0.7",
"angular-cookies": "~1.0.7",
"angular-sanitize": "~1.0.7",
"moment": "~2.2.1",
"bootswatch-scss": "*",
"angular-bootstrap": "~0.6.0",
"sass-bootstrap": "~2.3.2",
"angularjs-rails-resource": "~0.2.2"
},
"devDependencies": {
"angular-mocks": "~1.0.7",
"angular-scenario": "~1.0.7"
}
}
'use strict';
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
require('time-grunt')(grunt);
grunt.loadNpmTasks('grunt-contrib-watch');
// configurable paths
var config = {
src: 'src',
dist: 'dist',
tmp: '.tmp',
jsRoot: function(prefix) {
prefix = prefix || 'src';
return prefix + '/app';
}
};
try {
config.src = require('./bower.json').appPath || config.src;
} catch (e) {}
var mountFolder = function (connect, dir) {
return connect.static(require('path').resolve(dir));
};
var proxySnippet = require('grunt-connect-proxy/lib/utils').proxyRequest;
grunt.initConfig({
config: config,
// grunt-connect will serve the files from the folders listed in `bases`
// on the specified `port` and `hostname`
connect: {
options: {
port: 9000,
livereload: true
},
proxies: [
{
context: '/api',
host: 'localhost',
port: 3000
}
],
dev: {
options: {
hostname: "localhost",
//hostname: "0.0.0.0",
middleware: function (connect) {
return [
proxySnippet,
mountFolder(connect, '.tmp'),
mountFolder(connect, config.src)
];
}
}
},
test: {
options: {
middleware: function (connect) {
return [
mountFolder(connect, '.tmp'),
mountFolder(connect, 'test')
];
}
}
}
},
// grunt-open will open your browser at the project's URL
open: {
server: {
// Gets the port from the connect configuration
path: 'http://localhost:<%= connect.dev.options.port %>'
}
},
watch: {
coffee: {
files: ['<%= config.jsRoot(config.src) %>/**/*.coffee'],
tasks: ['coffee:dist']
},
coffeeTest: {
files: ['test/spec/**/*.coffee'],
tasks: ['coffee:test']
},
styles: {
files: ['<%= config.src %>/styles/**/*.css'],
tasks: ['copy:styles', 'autoprefixer']
},
sass: {
files: ['<%= config.src %>/styles/**/*.scss'],
tasks: ['compass:dev']
},
compiledAssets: {
files: [
'.tmp/**/*',
'<%= config.src %>/**/*.html',
'<%= config.src %>/images/**/*.{png,jpg,jpeg,gif,webp,svg}'
],
tasks: [],
options: {
livereload: true
}
}
},
autoprefixer: {
options: ['last 1 version'],
dist: {
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '**/*.css',
dest: '.tmp/styles/'
}]
}
},
clean: {
dist: {
files: [{
dot: true,
src: [
'.tmp',
'<%= config.dist %>/*',
'!<%= config.dist %>/.git*'
]
}]
},
server: '.tmp'
},
jshint: {
options: {
jshintrc: '.jshintrc'
},
all: [
'Gruntfile.js',
'<%= config.jsRoot(config.src) %>/**/*.js'
]
},
coffee: {
options: {
sourceMap: true,
sourceRoot: ''
},
dist: {
files: [{
expand: true,
cwd: '<%= config.jsRoot(config.src) %>',
src: '**/*.coffee',
dest: '<%= config.jsRoot(config.tmp) %>',
ext: '.js'
}]
},
test: {
files: [{
expand: true,
cwd: 'test/spec',
src: '**/*.coffee',
dest: '.tmp/spec',
ext: '.js'
}]
}
},
compass: {
dist: {
options: {
sassDir: '<%= config.src %>/styles',
cssDir: '<%= config.tmp %>/styles',
importPath: 'src/bower_components',
environment: 'production'
}
},
dev: {
options: {
sassDir: '<%= config.src %>/styles',
cssDir: '<%= config.tmp %>/styles',
importPath: 'src/bower_components'
}
}
},
// not used since Uglify task does concat,
// but still available if needed
/*concat: {
dist: {}
},*/
rev: {
dist: {
files: {
src: [
'<%= config.jsRoot(config.dist) %>/**/*.js',
'<%= config.dist %>/styles/**/*.css',
'<%= config.dist %>/images/**/*.{png,jpg,jpeg,gif,webp,svg}',
'<%= config.dist %>/styles/fonts/*'
]
}
}
},
useminPrepare: {
html: '<%= config.src %>/index.html',
options: {
dest: '<%= config.dist %>'
}
},
usemin: {
html: ['<%= config.dist %>/**/*.html'],
css: ['<%= config.dist %>/styles/**/*.css'],
options: {
dirs: ['<%= config.dist %>']
}
},
imagemin: {
dist: {
files: [{
expand: true,
cwd: '<%= config.src %>/images',
src: '**/*.{png,jpg,jpeg}',
dest: '<%= config.dist %>/images'
}]
}
},
svgmin: {
dist: {
files: [{
expand: true,
cwd: '<%= config.src %>/images',
src: '**/*.svg',
dest: '<%= config.dist %>/images'
}]
}
},
cssmin: {
// By default, your `index.html` <!-- Usemin Block --> will take care of
// minification. This option is pre-configured if you do not wish to use
// Usemin blocks.
// dist: {
// files: {
// '<%= config.dist %>/styles/main.css': [
// '.tmp/styles/**/*.css',
// '<%= config.src %>/styles/**/*.css'
// ]
// }
// }
},
htmlmin: {
dist: {
options: {
/*removeCommentsFromCDATA: true,
// https://github.com/yeoman/grunt-usemin/issues/44
//collapseWhitespace: true,
collapseBooleanAttributes: true,
removeAttributeQuotes: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeOptionalTags: true*/
},
files: [{
expand: true,
cwd: '<%= config.src %>',
src: ['*.html', 'views/**/*.html'],
dest: '<%= config.dist %>'
}]
}
},
// Put files not handled in other tasks here
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= config.src %>',
dest: '<%= config.dist %>',
src: [
'*.{ico,png,txt}',
'bower_components/**/*',
'images/**/*.{gif,webp}',
'styles/fonts/*'
]
}, {
expand: true,
cwd: '.tmp/images',
dest: '<%= config.dist %>/images',
src: [
'generated/*'
]
}]
},
styles: {
expand: true,
cwd: '<%= config.src %>/styles',
dest: '.tmp/styles/',
src: '**/*.css'
}
},
concurrent: {
server: [
'coffee:dist',
'copy:styles',
'compass:dev'
],
test: [
'coffee',
'copy:styles'
],
dist: [
'coffee',
'copy:styles',
'compass:dist',
'imagemin',
'svgmin',
'htmlmin'
]
},
karma: {
unit: {
configFile: 'karma.conf.js',
singleRun: true
}
},
cdnify: {
dist: {
html: ['<%= config.dist %>/*.html']
}
},
ngmin: {
dist: {
files: [{
expand: true,
cwd: '<%= config.jsRoot(config.dist) %>',
src: '*.js',
dest: '<%= config.jsRoot(config.dist) %>'
}]
}
},
uglify: {
dist: {
files: {
'<%= config.jsRoot(config.dist) %>/scripts.js': [
'<%= config.jsRoot(config.dist) %>/scripts.js'
]
}
}
}
});
grunt.registerTask('server', function (target) {
grunt.task.run([
'clean:server',
'concurrent:server', // runs coffee:dist and asset stuff
'autoprefixer',
'configureProxies',
'connect:dev',
'open',
'watch'
]);
});
grunt.registerTask('test', [
'clean:server',
'concurrent:test',
'configureProxies',
'autoprefixer',
'karma'
]);
grunt.registerTask('build', [
'clean:dist',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'copy:dist',
'cdnify',
'ngmin',
'cssmin',
'uglify',
'rev',
'usemin'
]);
grunt.registerTask('default', [
'jshint',
'test',
'build'
]);
};
{
"name": "rick",
"version": "0.0.0",
"dependencies": {},
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-copy": "~0.4.1",
"grunt-contrib-concat": "~0.3.0",
"grunt-contrib-coffee": "~0.7.0",
"grunt-contrib-uglify": "~0.2.0",
"grunt-contrib-compass": "~0.5.0",
"grunt-contrib-jshint": "~0.6.0",
"grunt-contrib-cssmin": "~0.6.0",
"grunt-contrib-connect": "~0.3.0",
"grunt-contrib-clean": "~0.5.0",
"grunt-contrib-htmlmin": "~0.1.3",
"grunt-contrib-imagemin": "~0.2.0",
"grunt-contrib-watch": "~0.5.3",
"grunt-autoprefixer": "~0.2.0",
"grunt-usemin": "~0.1.11",
"grunt-svgmin": "~0.2.0",
"grunt-rev": "~0.1.0",
"grunt-open": "~0.2.2",
"grunt-concurrent": "~0.3.0",
"load-grunt-tasks": "~0.1.0",
"grunt-google-cdn": "~0.2.0",
"grunt-ngmin": "~0.0.2",
"time-grunt": "~0.1.0",
"karma-ng-scenario": "~0.1.0",
"grunt-karma": "~0.6.2",
"karma-script-launcher": "~0.1.0",
"karma-firefox-launcher": "~0.1.0",
"karma-chrome-launcher": "~0.1.0",
"karma-html2js-preprocessor": "~0.1.0",
"karma-jasmine": "~0.1.3",
"karma-requirejs": "~0.1.0",
"karma-coffee-preprocessor": "~0.1.0",
"karma-phantomjs-launcher": "~0.1.0",
"karma": "~0.10.2",
"karma-ng-html2js-preprocessor": "~0.1.0",
"bower": "~1.2.6",
"grunt-connect-proxy": "~0.1.5"
},
"engines": {
"node": ">=0.8.0"
},
"scripts": {
"test": "grunt test"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment