Here is my grunt config file:
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-karma');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.initConfig({
uglify: {
build: {
src: 'app/concat.js',
dest: 'app/concat.min.js'
}
},
concat: {
options: {
separator: ';',
},
dist: {
src: ['app/js/**/*.js', '!app/concat.js',
dest: 'app/concat.js'
}
},
watch: {
karma: {
files: ['app/js/**/*.js', 'jasmine/spec/**/*.js'],
tasks: ['karma:unit:run']
},
concat: {
files: ['app/js/**/*.js', '!app/concat.js'],
tasks: ['concat']
},
live: {
files: ['app/js/**/*.js', '!app/concat.js', 'app/partials/**/*.html', 'WEB-INF/jsp/panther.html', 'css/new_style.css', 'css/style.css'],
options: {
livereload: true
}
}
},
karma: {
unit: {
configFile: 'jasmine/karma.conf.js',
background: true
}
},
sass: {
dist: {
files: {
'css/new_style.css': 'css/sass/new_style.scss'
}
}
}
});
grunt.registerTask('default', ['karma:unit:start', 'concat', 'watch']);
}
I do a watch and on code change i trigger the unit testing and concatenation,
My feeling is that this line:
src: ['app/js/**/*.js', '!app/concat.js',
is not working properly (at least for the second part)
It looks like you're building to the same directory/files as your source. I think that's a bad idea.
You should keep the files you're working on in one directory (for instance src) and let Grunt tasks output to another (for instance app). That would at least decrease the risk of duplication.
If you have one task that needs to work on the output of another task, let the first task output to a temporary directory and let the second task read from it.
Related
I have a folder with differents design project, on each one I may have scss files to compile. So I did a Gruntfile to watch on all this folders for the scss files and I want to compile them in their directory. But it' actually not working because of this error :
Running "sassAll" task
Running "sass:animating-rocket" (sass) task
Verifying property sass.animating-rocket exists in config...ERROR
>> Unable to process task.
Warning: Required config property "sass.animating-rocket" missing. Use --force to continue.
Aborted due to warnings.
It seems that a variable is not define on the config scope...
My Gruntfile looks like this :
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dist: {
options: {
style: 'compressed'
},
files: [{
src: ['<%= grunt.task.current.args[0] %>/*.scss'],
dest: '<%= grunt.task.current.args[0] %>',
ext: '.css'
}]
}
},
watch: {
options: {
livereload: true
},
css: {
files: ['**/*.scss'],
tasks: ['sassAll'],
options: {
spawn: false
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('sassAll', function () {
gruntUtils.sassTasks.forEach(function (param) {
grunt.task.run('sass:' + param);
});
});
var gruntUtils = {
sassTasks: ['animating-rocket', 'hamburger-animation']
};
grunt.registerTask('default', ['sassAll', 'watch']);
};
I can't get my grunt watch, sass, concat, nor uglify to load properly.
This is my Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig ({
pkg: grunt.file.readJSON('package.json'),
watch: {
files: ['src/*.js'],
tasks: ['jshint']
},
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
[
'src/*.css': 'main.scss',
'widgets.css': 'widgets.scss'
]
}
}
},
concat: {
js: {
src: 'src/*.js',
dest: 'src/build/concatenated.js'
}
},
uglify: {
build: {
src: 'src/build/concatenated.js',
dest: 'src/build/concatenated.min.js'
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.registerTask('default',['watch']);
grunt.registerTask('concat',['concat','uglify']);
};
In my terminal, when I type in 'grunt' I get the error message:
Loading "Gruntfile.js" tasks...ERROR
>> SyntaxError: Unexpected token :
Warning: Task "default" not found. Use --force to continue.
Aborted due to warnings.
I don't see an extra semi-colon listed anywhere. Can someone help?
files: {
[
'src/*.css': 'main.scss',
'widgets.css': 'widgets.scss'
]
}
should be
files: {
'src/*.css': 'main.scss',
'widgets.css': 'widgets.scss'
}
I've done a fair bit of searching but can't seem to come up with a full answer to this.
I'm using grunt to manage my sass flow and I've been trying to find a way to output multiple css styles from grunt.
For example:
base.scss should have two outputs the first being style.css which has the expanded css style.
The second should be style.min.css which has the compressed css style.
How can I configure my gruntfile to do this for me?
You can do this by having two configurations, one outputting expanded CSS and the other compressed. Then register your task to run both. Your grunt file should look something like this:
Example
module.exports = function(grunt) {
'use strict';
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// Sass
sass: {
dev: { // This outputs the expanded css file
files: {
'style.css': 'base.scss'
}
},
prod: { // This outputs the compressed css file
options: {
outputStyle: 'compressed' // Minify output
},
files: {
'style.min.css': 'base.scss'
}
}
}
});
grunt.registerTask('default', ['sass:dev', 'sass:prod']); // Task runs both
}
Here is a more complete solution of what belongs in gruntfile.js, improving upon what Colin Bacon has already posted. By default grunt's pkg is already set to read package.json in the current directory, so no need to write that. You just need to install the jit-grunt plugin (besides the watch and sass plugins of course) to get my answer working.
module.exports = function(grunt) {
require('jit-grunt')(grunt);
grunt.initConfig({
sass: {
expanded: { // Target
options: { // Target options
style: 'expanded'
},
files: { // Dictionary of files
'style.css': 'style.scss' // 'destination': 'source'
}
},
compressed: { // Target
options: { // Target options
style: 'compressed'
},
files: { // Dictionary of files
'style.min.css': 'style.scss' // 'destination': 'source'
}
}
},
watch: {
styles: {
files: ['**/*.scss'], // which files to watch
tasks: ['sass'],
options: {
spawn: false // speeds up watch reaction
}
}
}
});
grunt.registerTask('default', ['sass', 'watch']);
};
Just add a new manifest file in your styles folder. For example, you have normally main.scss, if you create main2.scss and import some files in there. It will create a file for each manifest file you have.
If your sass task looks something like this (default yeoman webapp generator):
sass: {
options: {
sourceMap: true,
includePaths: ['bower_components']
},
dist: {
files: [{
expand: true,
cwd: '<%= config.app %>/styles',
src: ['*.{scss,sass}'],
dest: '.tmp/styles',
ext: '.css'
}]
},
server: {
files: [{
expand: true,
cwd: '<%= config.app %>/styles',
src: ['*.{scss,sass}'],
dest: '.tmp/styles',
ext: '.css'
}]
}
}
The file section sass read all .scss/.sass files and copy those to .tmp/styles. Later, copy task move those to dist/styles.
On my MEAN stack application, I'm trying make changes to the HTML view files and see those changes as I make them using Grunt's livereload.
Grunt's livereload is working fine in the sense that it detects changes in my HTML files and refreshes the page during development. However, the actual changes are not reflecting on the page. If I push the files up the server, and reload the publicly available site, the changes are there. But I still can't see the changes while I'm developing.
I'm 99% sure that the problem has to do with the server is using the "build" files or something rather than the files located in the /public folder. However, I'm new to using the back-end and the MEAN stack and can't figure out what file the browser is showing or where this file is. Could anyone give any guidance on how to figure out what file the browser is displaying and what I can do to show HTML changes I make as I make them?
Here is my gruntfile if this helps. The below files I'm making changes to are watchFiles.clientViews.
'use strict';
module.exports = function(grunt) {
// Unified Watch Object
var watchFiles = {
serverViews: ['app/views/**/*.*'],
serverJS: ['gruntfile.js', 'server.js', 'config/**/*.js', 'app/**/*.js'],
clientViews: ['public/modules/**/views/**/*.html'],
clientJS: ['public/js/*.js', 'public/modules/**/*.js'],
clientCSS: ['public/modules/**/*.css'],
mochaTests: ['app/tests/**/*.js']
};
// Project Configuration
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
options: { livereload: true },
serverViews: {
files: [watchFiles.serverViews],
options: {
livereload: true
}
},
serverJS: {
files: watchFiles.serverJS,
tasks: ['jshint'],
options: {
livereload: true
}
},
clientViews: {
files: watchFiles.clientViews,
options: {
livereload: true,
}
},
clientJS: {
files: watchFiles.clientJS,
tasks: ['jshint'],
options: {
livereload: true
}
},
clientCSS: {
files: watchFiles.clientCSS,
tasks: ['csslint'],
options: {
livereload: true
}
}
},
jshint: {
all: {
src: watchFiles.clientJS.concat(watchFiles.serverJS),
options: {
jshintrc: true
}
}
},
csslint: {
options: {
csslintrc: '.csslintrc',
},
all: {
src: watchFiles.clientCSS
}
},
uglify: {
production: {
options: {
mangle: false
},
files: {
'public/dist/application.min.js': 'public/dist/application.js'
}
}
},
cssmin: {
combine: {
files: {
'public/dist/application.min.css': '<%= applicationCSSFiles %>'
}
}
},
nodemon: {
dev: {
script: 'server.js',
options: {
nodeArgs: ['--debug'],
ext: 'js,html',
watch: watchFiles.serverViews.concat(watchFiles.serverJS)
}
}
},
'node-inspector': {
custom: {
options: {
'web-port': 1337,
'web-host': 'localhost',
'debug-port': 5858,
'save-live-edit': true,
'no-preload': true,
'stack-trace-limit': 50,
'hidden': []
}
}
},
ngAnnotate: {
production: {
files: {
'public/dist/application.js': '<%= applicationJavaScriptFiles %>'
}
}
},
concurrent: {
default: ['nodemon', 'watch'],
debug: ['nodemon', 'watch', 'node-inspector'],
options: {
logConcurrentOutput: true,
limit: 10
}
},
env: {
test: {
NODE_ENV: 'test'
}
},
mochaTest: {
src: watchFiles.mochaTests,
options: {
reporter: 'spec',
require: 'server.js'
}
},
karma: {
unit: {
configFile: 'karma.conf.js'
}
}
});
// Load NPM tasks
require('load-grunt-tasks')(grunt);
// Making grunt default to force in order not to break the project.
grunt.option('force', true);
// A Task for loading the configuration object
grunt.task.registerTask('loadConfig', 'Task that loads the config into a grunt option.', function() {
var init = require('./config/init')();
var config = require('./config/config');
grunt.config.set('applicationJavaScriptFiles', config.assets.js);
grunt.config.set('applicationCSSFiles', config.assets.css);
});
// Default task(s).
grunt.registerTask('default', ['lint', 'concurrent:default']);
// Debug task.
grunt.registerTask('debug', ['lint', 'concurrent:debug']);
// Lint task(s).
grunt.registerTask('lint', ['jshint', 'csslint']);
// Build task(s).
grunt.registerTask('build', ['lint', 'loadConfig', 'ngAnnotate', 'uglify', 'cssmin']);
// Test task.
grunt.registerTask('test', ['env:test', 'mochaTest', 'karma:unit']);
};
In addition, here is the file structure to my MEAN stack. The highlighted below is where the HTML file that I'm making changes to is located.
Please let me know if there is any other code or info I could provide that would make solving this problem easier. Thank you.
Update: Content of Server.js
Here is my server.js content:
'use strict';
/**
* Module dependencies.
*/
var init = require('./config/init')(),
config = require('./config/config'),
mongoose = require('mongoose');
/**
* Main application entry file.
* Please note that the order of loading is important.
*/
// Bootstrap db connection
var db = mongoose.connect(config.db, function(err) {
if (err) {
console.error('\x1b[31m', 'Could not connect to MongoDB!');
console.log(err);
}
});
// Init the express application
var app = require('./config/express')(db);
// Bootstrap passport config
require('./config/passport')();
// Start the app by listening on <port>
app.listen(config.port);
// Expose app
exports = module.exports = app;
// Logging initialization
console.log('MEAN.JS application started on port ' + config.port);
It's hard to tell exactly what your "server.js" is serving without seeing the contents of it, but if my assumption is correct and you are serving the contents of the "public" directory, you don't have any sort of task being fired by watch that facilitates copying the contents of your changed files into your "public" directory. It looks like this happens initially when your server is started (by running the build task), but not run subsequently whenever something is changed.
I would suggest modifying your watch tasks to perform some of the build-related tasks on your files as they are changed. Since your build-related tasks are physically copying the changes to the "public" directory for you as part of their jobs, you should finally see the results of your changes. Here's an example of your watch task list that's modified to copy your JS and CSS files on change:
watch: {
options: { livereload: true },
serverViews: {
files: [watchFiles.serverViews],
options: {
livereload: true
}
},
serverJS: {
files: watchFiles.serverJS,
tasks: ['jshint', 'loadConfig', 'ngAnnotate', 'uglify'],
options: {
livereload: true
}
},
clientViews: {
files: watchFiles.clientViews,
options: {
livereload: true,
}
},
clientJS: {
files: watchFiles.clientJS,
tasks: ['jshint', 'loadConfig', 'ngAnnotate', 'uglify'],
options: {
livereload: true
}
},
clientCSS: {
files: watchFiles.clientCSS,
tasks: ['csslint', 'cssmin'],
options: {
livereload: true
}
}
},
One last thing: Assuming your views don't need to have any modifications done to them post-change, you can simply straight-up copy them to the public directory when they are changed. Take a look at grunt-contrib-copy for doing simple file copying between directories.
I was facing the same issue and solved it by disabling the cache in the network tab
Go to Inspect -> Network and make sure disable cache is checked.
Hope this helps someone in future :)
I'm new to setting up my own grunt, and this is what I have come up with. I was just wondering if someone could look it over and give me some hints/advice.
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
coffee: {
compile: {
expand: true,
flatten: true,
cwd: 'src/coffee',
src: ['*.coffee'],
dest: 'src/js/',
ext: '.js'
}
},
concat: {
css: {
src: [
'src/css/*'
],
dest: 'css/.css'
},
js: {
src: [
'src/js/*'
],
dest: 'js/package.js'
}
},
cssmin: {
css: {
src: 'css/package.css',
dest: 'css/package.min.css'
}
},
uglify: {
js: {
files: {
'js/package.min.js': ['js/package.js']
}
}
},
watch: {
aspx: {
files: ['*.aspx', '*.master']
},
css: {
files: ['src/css/*'],
tasks: ['concat:css', 'cssmin']
},
coffee: {
files: ['src/coffee/*'],
tasks: ['coffee:compile']
},
js: {
files: ['src/js/*'],
tasks: ['concat:js', 'uglify']
},
livereload: {
files: ['*.aspx', '*.master', 'css/*.css', 'js/*.js'],
options: { nospawn: true, livereload: true }
}
}
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-coffee');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask('default', ['coffee:compile','concat:css', 'cssmin:css', 'concat:js', 'uglify:js', 'watch']);
};
It does work, and reloads and compiles perfectly. I was just wondering if there may be a more effiecent way to handle this. Being my first gruntfile I know it is very far from perfect.
I would recommend load-grunt-tasks in order to cut down on the complexity of the main Gruntfile.js. It's incredibly simple to use. It allows you to split up the Gruntfile.js into a number of smaller JS files stored in a separate Grunt folder, for example:
/root
/Grunt
cssmin.js
coffee.js
watch.js
...
And then your main Gruntfile.js to load in your tasks is simply, again for example:
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
}
It's all held together with YAML file called aliases.yaml that sits in the Grunt folder that details the Grunt commands and their associated processes. So with this in the YAML file:
lint:
- clear
- jshint
- jscs
You could run grunt lint and it would run those tasks.
I've found it a) a complete lifesaver, and b) helped me understand Grunt at a whole different level.
I've made an example repo for you to help explain what I'm talking about. I hope it's of some help.