Last active
October 27, 2016 16:40
-
-
Save mariohmol/c52bf7ae7266a8b6fb9f to your computer and use it in GitHub Desktop.
Configure Build grunt tasks for Strongloop + AngularJS + Bower modules
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
/* | |
* https://github.com/angular-fullstack/generator-angular-fullstack/blob/master/Gruntfile.js | |
* https://docs.strongloop.com/display/public/LB/AngularJS+Grunt+plugin | |
* http://amsterdam.luminis.eu/2014/12/10/improve-my-angularjs-project-with-grunt/ | |
* https://github.com/olov/ng-annotate | |
* https://github.com/mgol/grunt-ng-annotate | |
* https://oclazyload.readme.io/docs | |
https://github.com/strongloop/loopback-example-offline-sync/blob/master/Gruntfile.js | |
NPM: Remember to include export PATH=$PATH:~/.npm-packages/bin/ | |
Packages to install | |
* npm install grunt-contrib-clean --save-dev | |
* npm install grunt-contrib-concat --save-dev | |
* npm install grunt-contrib-copy --save-dev | |
* npm install grunt-contrib-cssmin --save-dev | |
* npm install grunt-contrib-jshint --save-dev | |
* npm install grunt-contrib-nodeunit --save-dev | |
* npm install grunt-contrib-uglify --save-dev | |
* npm install grunt-usemin --save-dev | |
* npm install grunt-angular-templates --save-dev | |
* npm install load-grunt-tasks --save-dev | |
* npm install jshint-stylish --save-dev | |
* npm install time-grunt --save-dev | |
* | |
EDITOR: Sublime 2 - | |
* Install addons package manager: https://packagecontrol.io/installation#st2 | |
* Add SubliemHint: https://github.com/victorporof/Sublime-JSHint | |
* Use command B to build and give Lint erros | |
To make firt fix in your JS fils: | |
* To teset: https://github.com/jshint/fixmyjs | |
Run task to check and fix remaining erros: | |
*/ | |
'use strict'; | |
//var buildClientBundle = require('./client/lbclient/build'); | |
var fs = require('fs'); | |
var path = require('path'); | |
// # Globbing | |
// for performance reasons we're only matching one level down: | |
// 'test/spec/{,*/}*.js' | |
// use this if you want to recursively match all subfolders: | |
// 'test/spec/**/*.js' | |
module.exports = function (grunt) { | |
// Load grunt tasks automatically | |
require('load-grunt-tasks')(grunt); | |
// Time how long tasks take. Can help when optimizing build times | |
require('time-grunt')(grunt); | |
grunt.loadNpmTasks('grunt-loopback-sdk-angular'); | |
// Configurable paths for the application | |
var appConfig = { | |
app: require('./bower.json').appPath || 'client', | |
dist: 'client/dist' | |
}; | |
// Define the configuration for all the tasks | |
grunt.initConfig({ | |
// Project settings | |
yeoman: appConfig, | |
loopback_sdk_angular: { | |
services: { | |
options: { | |
input: '../server/server.js', | |
output: 'js/lb-services.js' | |
} | |
} | |
}, | |
docular: { | |
groups: [ | |
{ | |
groupTitle: 'LoopBack', | |
groupId: 'loopback', | |
sections: [ | |
{ | |
id: 'lbServices', | |
title: 'LoopBack Services', | |
scripts: [ 'js/lb-services.js' ] | |
} | |
] | |
} | |
] | |
}, | |
// Watches files for changes and runs tasks based on the changed files | |
watch: { | |
bower: { | |
files: ['bower.json'], | |
tasks: ['wiredep'] | |
}, | |
js: { | |
files: ['<%= yeoman.app %>/scripts/{,*/}*.js'], | |
tasks: ['newer:jshint:all'], | |
options: { | |
livereload: '<%= connect.options.livereload %>' | |
} | |
}, | |
jsTest: { | |
files: ['<%= yeoman.app %>/test/spec/{,*/}*.js'], | |
tasks: ['newer:jshint:test', 'karma'] | |
}, | |
styles: { | |
files: ['<%= yeoman.app %>/styles/{,*/}*.css'], | |
tasks: ['newer:copy:styles', 'autoprefixer'] | |
}, | |
gruntfile: { | |
files: ['Gruntfile.js'] | |
}, | |
livereload: { | |
options: { | |
livereload: '<%= connect.options.livereload %>' | |
}, | |
files: [ | |
'<%= yeoman.app %>/{,*/}*.html', | |
'.tmp/styles/{,*/}*.css', | |
'<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}' | |
] | |
}, | |
lbclient: { | |
files: [ | |
'lbclient/models/*', | |
'lbclient/app*', | |
'lbclient/datasources*', | |
'lbclient/models*', | |
'lbclient/build.js' | |
], | |
tasks: ['build-lbclient'], | |
options: { | |
livereload: '<%= connect.options.livereload %>' | |
}, | |
}, | |
config: { | |
files: ['<%= yeoman.app %>/config/*.json'], | |
tasks: ['build-config'], | |
options: { | |
livereload: '<%= connect.options.livereload %>' | |
}, | |
}, | |
}, | |
// The actual grunt server settings | |
connect: { | |
options: { | |
port: 3000, | |
// Change this to '0.0.0.0' to access the server from outside. | |
hostname: 'localhost', | |
livereload: 35729 | |
}, | |
test: { | |
options: { | |
port: 9001, | |
middleware: function (connect) { | |
return [ | |
connect.static('.tmp'), | |
connect.static('test'), | |
connect().use( | |
'/bower_components', | |
connect.static('./bower_components') | |
), | |
connect().use( | |
'/lbclient', | |
connect.static('./lbclient') | |
), | |
connect.static(appConfig.app) | |
]; | |
} | |
} | |
} | |
}, | |
// Make sure code styles are up to par and there are no obvious mistakes | |
jshint: { | |
options: { | |
jshintrc: '.jshintrc', | |
reporter: require('jshint-stylish') | |
}, | |
all: { | |
src: [ | |
'Gruntfile.js', | |
'<%= yeoman.app %>/scripts/{,*/}*.js' | |
] | |
}, | |
test: { | |
options: { | |
jshintrc: '<%= yeoman.app %>/test/.jshintrc' | |
}, | |
src: ['test/spec/{,*/}*.js'] | |
} | |
}, | |
// Empties folders to start fresh | |
clean: { | |
dist: { | |
files: [{ | |
dot: true, | |
src: [ | |
'.tmp', | |
'<%= yeoman.dist %>/{,*/}*', | |
'!<%= yeoman.dist %>/.git*' | |
] | |
}] | |
}, | |
server: '.tmp', | |
lbclient: 'lbclient/browser.bundle.js', | |
config: '<%= yeoman.app %>/config/bundle.js' | |
}, | |
// Add vendor prefixed styles | |
autoprefixer: { | |
options: { | |
browsers: ['last 1 version'] | |
}, | |
dist: { | |
files: [{ | |
expand: true, | |
cwd: '.tmp/styles/', | |
src: '{,*/}*.css', | |
dest: '.tmp/styles/' | |
}] | |
} | |
}, | |
/** Automatically inject Bower components into the app*/ | |
wiredep: { | |
options: { | |
cwd: '<%= yeoman.app %>', | |
bowerJson: require('./bower.json'), | |
directory: './client/vendor' //require('./.bowerrc').directory | |
}, | |
app: { | |
src: ['<%= yeoman.app %>/index.html'], | |
ignorePath: /..\// | |
} | |
}, | |
// Renames files for browser caching purposes | |
filerev: { | |
dist: { | |
src: [ | |
'<%= yeoman.dist %>/scripts/{,*/}*.js', | |
'<%= yeoman.dist %>/styles/{,*/}*.css', | |
'<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}', | |
'<%= yeoman.dist %>/styles/fonts/*' | |
] | |
} | |
}, | |
// Reads HTML for usemin blocks to enable smart builds that automatically | |
// concat, minify and revision files. Creates configurations in memory so | |
// additional tasks can operate on them | |
useminPrepare: { | |
html: '<%= yeoman.app %>/index.html', | |
options: { | |
dest: '<%= yeoman.dist %>', | |
flow: { | |
html: { | |
steps: { | |
js: ['concat', 'uglifyjs'], | |
css: ['cssmin'] | |
}, | |
post: {} | |
} | |
} | |
} | |
}, | |
// Performs rewrites based on filerev and the useminPrepare configuration | |
usemin: { | |
html: ['<%= yeoman.dist %>/{,*/}*.html'], | |
css: ['<%= yeoman.dist %>/styles/{,*/}*.css'], | |
options: { | |
assetsDirs: ['<%= yeoman.dist %>','<%= yeoman.dist %>/images'] | |
} | |
}, | |
// The following *-min tasks will produce minified files in the dist folder | |
// By default, your `index.html`'s <!-- Usemin block --> will take care of | |
// minification. These next options are pre-configured if you do not wish | |
// to use the Usemin blocks. | |
cssmin: { | |
dist: { | |
files: { | |
'<%= yeoman.dist %>/css/main.css': [ | |
'.tmp/styles/{,*/}*.css' | |
] | |
} | |
} | |
}, | |
// uglify: { | |
// dist: { | |
// files: { | |
// '<%= yeoman.dist %>/scripts/scripts.js': [ | |
// '<%= yeoman.dist %>/scripts/scripts.js' | |
// ] | |
// } | |
// } | |
// }, | |
// concat: { | |
// dist: {} | |
// }, | |
imagemin: { | |
dist: { | |
files: [{ | |
expand: true, | |
cwd: '<%= yeoman.app %>/images', | |
src: '{,*/}*.{png,jpg,jpeg,gif}', | |
dest: '<%= yeoman.dist %>/images' | |
}] | |
} | |
}, | |
svgmin: { | |
dist: { | |
files: [{ | |
expand: true, | |
cwd: '<%= yeoman.app %>/images', | |
src: '{,*/}*.svg', | |
dest: '<%= yeoman.dist %>/images' | |
}] | |
} | |
}, | |
htmlmin: { | |
dist: { | |
options: { | |
collapseWhitespace: true, | |
conservativeCollapse: true, | |
collapseBooleanAttributes: true, | |
removeCommentsFromCDATA: true, | |
removeOptionalTags: true | |
}, | |
files: [{ | |
expand: true, | |
cwd: '<%= yeoman.dist %>', | |
src: ['*.html', 'views/{,*/}*.html'], | |
dest: '<%= yeoman.dist %>' | |
}] | |
} | |
}, | |
// ngAnnotate tries to make the code safe for minification automatically by | |
// using the Angular long form for dependency injection. It doesn't work on | |
// things like resolve or inject so those have to be done manually. | |
ngAnnotate: { | |
dist: { | |
files: [{ | |
expand: true, | |
cwd: '.tmp/concat/scripts', | |
src: '*.js', | |
dest: '.tmp/concat/scripts' | |
}] | |
} | |
}, | |
// Replace Google CDN references | |
cdnify: { | |
dist: { | |
html: ['<%= yeoman.dist %>/*.html'] | |
} | |
}, | |
// Copies remaining files to places other tasks can use | |
copy: { | |
dist: { | |
files: [{ | |
expand: true, | |
dot: true, | |
cwd: '<%= yeoman.app %>', | |
dest: '<%= yeoman.dist %>', | |
src: [ | |
'*.{ico,png,txt}', | |
'.htaccess', | |
'*.html', | |
'views/{,*/}*.html', | |
'images/{,*/}*.{webp}', | |
'fonts/*' | |
] | |
}, { | |
expand: true, | |
cwd: '.tmp/images', | |
dest: '<%= yeoman.dist %>/images', | |
src: ['generated/*'] | |
}] | |
}, | |
styles: { | |
expand: true, | |
cwd: '<%= yeoman.app %>/styles', | |
dest: '.tmp/styles/', | |
src: '{,*/}*.css' | |
} | |
}, | |
// Run some tasks in parallel to speed up the build process | |
concurrent: { | |
server: [ | |
'copy:styles' | |
], | |
test: [ | |
'copy:styles' | |
], | |
dist: [ | |
'copy:styles', | |
'imagemin', | |
'svgmin' | |
] | |
}, | |
// Test settings | |
karma: { | |
unit: { | |
configFile: '<%= yeoman.app %>/test/karma.conf.js', | |
browsers: [ 'PhantomJS' ], | |
singleRun: true | |
} | |
}, | |
// Server Tests | |
mochaTest: { | |
common: { | |
options: { | |
reporter: 'spec', | |
quiet: false, | |
clearRequireCache: false | |
}, | |
src: ['common/models/test/**/*.js'] | |
}, | |
server: { | |
options: { | |
reporter: 'spec', | |
quiet: false, | |
clearRequireCache: false | |
}, | |
src: ['server/test/**/*.js'] | |
} | |
} | |
}); | |
grunt.registerTask('build-lbclient', 'Build lbclient browser bundle', function() { | |
var done = this.async(); | |
done(); | |
//buildClientBundle(process.env.NODE_ENV || 'development', done); | |
}); | |
grunt.registerTask('build-config', 'Build confg.js from JSON files', function() { | |
var ngapp = path.resolve(__dirname, appConfig.app); | |
var configDir = path.join(ngapp, 'config'); | |
var config = {}; | |
fs.readdirSync(configDir) | |
.forEach(function(f) { | |
if (f === 'bundle.js') return; | |
var extname = path.extname(f); | |
if (extname !== '.json') { | |
grunt.warn('Ignoring ' + f + ' (' + extname + ')'); | |
return; | |
} | |
var fullPath = path.resolve(configDir, f); | |
var key = path.basename(f, extname); | |
config[key] = JSON.parse(fs.readFileSync(fullPath), 'utf-8'); | |
}); | |
var outputPath = path.resolve(ngapp, 'config', 'bundle.js'); | |
var content = 'window.CONFIG = ' + | |
JSON.stringify(config, null, 2) + | |
';\n'; | |
fs.writeFileSync(outputPath, content, 'utf-8'); | |
}); | |
grunt.registerTask('run', 'Start the app server', function() { | |
var done = this.async(); | |
var connectConfig = grunt.config.get().connect.options; | |
process.env.LIVE_RELOAD = connectConfig.livereload; | |
process.env.NODE_ENV = this.args[0]; | |
var keepAlive = this.flags.keepalive || connectConfig.keepalive; | |
var server = require('./server'); | |
server.set('port', connectConfig.port); | |
server.set('host', connectConfig.hostname); | |
server.start() | |
.on('listening', function() { | |
if (!keepAlive) done(); | |
}) | |
.on('error', function(err) { | |
if (err.code === 'EADDRINUSE') { | |
grunt.fatal('Port ' + connectConfig.port + | |
' is already in use by another process.'); | |
} else { | |
grunt.fatal(err); | |
} | |
}); | |
}); | |
grunt.registerTask('serve', 'Compile then start the app server', function (target) { | |
if (target === 'dist') { | |
return grunt.task.run(['build', 'run:dist:keepalive']); | |
} | |
grunt.task.run([ | |
'clean:server', | |
'build-lbclient', | |
'build-config', | |
'wiredep', | |
'concurrent:server', | |
'autoprefixer', | |
'run:development', | |
'watch' | |
]); | |
}); | |
grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) { | |
grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.'); | |
grunt.task.run(['serve:' + target]); | |
}); | |
grunt.registerTask('test:client', [ | |
'clean:server', | |
'build-lbclient', | |
'build-config', | |
'concurrent:test', | |
'autoprefixer', | |
'connect:test', | |
'karma' | |
]); | |
grunt.registerTask('test:common', [ | |
'mochaTest:common' | |
]); | |
grunt.registerTask('test:server', [ | |
'mochaTest:server' | |
]); | |
grunt.registerTask('test', [ | |
'test:server', | |
'test:common', | |
'test:client' | |
]); | |
grunt.registerTask('build', [ | |
'clean:dist', | |
'build-lbclient', | |
'build-config', | |
'wiredep', | |
'useminPrepare', | |
'concurrent:dist', | |
'autoprefixer', | |
'concat', | |
'ngAnnotate', | |
'copy:dist', | |
'cdnify', | |
'cssmin', | |
'uglify', | |
'filerev', | |
'usemin', | |
'htmlmin' | |
]); | |
grunt.registerTask('default', [ | |
'jshint', | |
'test', | |
'build' | |
]); | |
}; |
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
{ | |
"name": "project", | |
"version": "1.0.0", | |
"main": "server/server.js", | |
"scripts": { | |
"pretest": "jshint ." | |
}, | |
"dependencies": { | |
"angular-animate": "^1.4.8", | |
"async": "^1.5.2", | |
"compression": "^1.0.3", | |
"cors": "^2.5.2", | |
"email-templates": "^2.1.0", | |
"loopback": "^2.22.0", | |
"loopback-boot": "^2.6.5", | |
"loopback-component-explorer": "^2.1.0", | |
"loopback-connector-mongodb": "^1.13.3", | |
"loopback-connector-mysql": "^2.2.0", | |
"loopback-datasource-juggler": "^2.39.0", | |
"prerender-node": "^2.2.0", | |
"serve-favicon": "^2.0.1" | |
}, | |
"devDependencies": { | |
"bower": "^1.3.8", | |
"browserify": "~4.2.3", | |
"chai": "^3.4.1", | |
"connect-livereload": "^0.4.0", | |
"grunt": "^0.4.5", | |
"grunt-autoprefixer": "^0.8.2", | |
"grunt-cli": "^0.1.13", | |
"grunt-concurrent": "^0.5.0", | |
"grunt-contrib-clean": "^0.5.0", | |
"grunt-contrib-concat": "^0.5.0", | |
"grunt-contrib-connect": "^0.8.0", | |
"grunt-contrib-copy": "^0.5.0", | |
"grunt-contrib-cssmin": "^0.10.0", | |
"grunt-contrib-htmlmin": "^0.3.0", | |
"grunt-contrib-imagemin": "^0.8.1", | |
"grunt-contrib-jshint": "^0.10.0", | |
"grunt-contrib-uglify": "^0.5.1", | |
"grunt-contrib-watch": "^0.6.1", | |
"grunt-filerev": "^0.2.1", | |
"grunt-google-cdn": "^0.4.0", | |
"grunt-karma": "^0.8.3", | |
"grunt-loopback-sdk-angular": "^1.1.2", | |
"grunt-mocha-test": "^0.12.6", | |
"grunt-newer": "^0.7.0", | |
"grunt-ng-annotate": "^0.8.0", | |
"grunt-svgmin": "^0.4.0", | |
"grunt-usemin": "^2.3.0", | |
"grunt-wiredep": "^1.8.0", | |
"jshint": "^2.8.0", | |
"jshint-stylish": "^0.4.0", | |
"karma": "^0.12.17", | |
"karma-chrome-launcher": "^0.1.4", | |
"karma-jasmine": "^0.1.5", | |
"karma-phantomjs-launcher": "^0.1.4", | |
"load-grunt-tasks": "^0.6.0", | |
"mocha": "^2.1.0", | |
"supertest": "^1.1.0", | |
"time-grunt": "^0.4.0" | |
}, | |
"repository": { | |
"type": "", | |
"url": "" | |
}, | |
"description": "netexamesweb" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment