Grunt task not running - javascript

I'm working on a grunt script to copy some files from 'dev' into 'dist' and modify the folder structure slightly. There are html files present inside dev/html/eas1/ and dev/html/eas2. The script uses grunt.config.set in order to change the src and dest locations of the copy and the script is running without errors, but nothing is being copied over. Can anyone help?
module.exports = function(grunt) {
grunt.initConfig({
projectCodes: {
eas: ['eas1', 'eas2', 'eas3', 'eas4', 'eas5', 'eas6']
},
copy: {
main: {
files: [{
expand: true,
src: 'dev/eas/html/eas1/*',
dest: 'dist/eas/eas1/html/',
filter: 'isFile'
}]
}
}
});
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.registerTask('dev', function(p) {
var projectCodes = grunt.config.get('projectCodes');
for(code in projectCodes[p]) {
grunt.config.set('copy.main.files.0.src', 'dev/'+p+'/html/'+projectCodes[p][code]+'/*');
grunt.config.set('copy.main.files.0.dest', 'dist/'+p+'/'+projectCodes[p][code]+'/html/');
grunt.task.run('copy:main');
}
});
};

Related

Grunt in sails.js failing to recognise new task

I am trying to add a new grunt task in a sails.js application.
To keep my test case simple i have copied the copy task to a new file copy-tests.js, which is also in the tasks/config folder.
I have modified copy-tests.js to update the first param of the set method to 'copy-tests', so it now reads
module.exports = function(grunt) {
grunt.config.set('copy-tests', {
dev: {
files: [{
expand: true,
cwd: './assets',
src: ['**/*.!(coffee|less)'],
dest: '.tmp/public'
}]
},
build: {
files: [{
expand: true,
cwd: '.tmp/public',
src: ['**/*'],
dest: 'www'
}]
}
});
grunt.loadNpmTasks('grunt-contrib-copy');
};
I have updated compileAssets.js to add my new tasks, so it now reads
module.exports = function (grunt) {
grunt.registerTask('compileAssets', [
'clean:dev',
'jst:dev',
'less:dev',
'copy:dev',
'copy-tests:dev',
'coffee:dev',
'jade:dev'
]);
};
When i try to lift the sails app i get 'Task "copy-tests:dev" not found'
I know that grunt can see my file as i have added a log statement to Gruntfile.js as follows
var taskConfigurations = loadTasks('./tasks/config'),
registerDefinitions = loadTasks('./tasks/register');
console.log(taskConfigurations);
I can see copy-tests in among the other tasks when this statement logs
Can anyone help with why grunt claims it can't find copy-tests:dev ?
Alternatively maybe i am going about this the wrong way. What i am trying to achieve is having two copy tasks, one to copy my main build content to the .tmp folder, and a second one to copy my client side tests to the .tmp folder. Later i will make sure that only my dev builds run both copy tasks, my prod one will only run the first one. I thought the best way to do this would be with two grunt tasks in the config folder, but maybe there is another way...
Rather than define a second task to have an alternative copy, i needed to add to the Copy task as follows
module.exports = function(grunt) {
grunt.config.set('copy', {
dev: {
files: [{
expand: true,
cwd: './assets',
src: ['**/*.!(coffee|less)'],
dest: '.tmp/public'
}]
},
devTests: {
files: [{
expand: true,
cwd: './tests',
src: ['**/*.*'],
dest: '.tmp/public/tests'
}]
},
build: {
files: [{
expand: true,
cwd: '.tmp/public',
src: ['**/*'],
dest: 'www'
}]
}
});
grunt.loadNpmTasks('grunt-contrib-copy');
};
My compileAssets then looks like
module.exports = function (grunt) {
grunt.registerTask('compileAssets', [
'clean:dev',
'jst:dev',
'less:dev',
'copy:dev',
'copy:devTests',
'coffee:dev',
'jade:dev'
]);
};
I realised this when i looked at the sails-linker.js task and saw how many targets there were in that. I had been thinking of the targets as build targets and assuming they would have values like dev, test, prod etc, but it appears that they are a broader concept and every type of copy i might want to do should be a target in the copy.js task.

Grunt Sass - Multiple css style outputs

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.

pass middleman variable to grunt file

My middleman template has an 'id' variable that I put my html emails job name into.
I know if I change my middleman erb file from index.html.erb to newName.html.erb it will output that as the final files name.
My problem is that most of my grunt tasks require the file name I want them to run on (I've tried using *.html, but it only works for some tasks) and short of editing that in the grunt file prior to starting grunt up they won't execute if I change the erb file name.
Is there a way to pass grunt that 'id' variable to name the file middleman is outputting and also plug that variable into the various tasks so they too accept that as what the filename?
Here is my grunt config:
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// Build html
middleman: {
options: {
useBundle: true
},
server: {},
build: {
options: {
command: "build"
}
}
},
// Format html file
prettify: {
options: {
// Task-specific options go here.
},
one: {
src: 'build/index.html',
dest: '_output/index.html'
}
},
// Run the text converter
execute: {
simple_target_with_args: {
options: {
// execute node with additional arguments
args: ['_output/index.html']
},
src: ['node_modules/node-text-converter/converter.js']
}
},
'special-html': {
compile: {
files: {
'_output/index.html': '_output/index.html',
}
}
},
'phantomjs_screenshot': {
main: {
options: {
delay: 1000
},
files: [{
expand: true,
cwd: '_output',
src: ['**/*.html'],
dest: '_output/screenshots/',
ext: '.jpg'
}]
}
}
});
You should store your variable in a JSON file and import it both into Middleman and Grunt.

How can I specify all typescript files inside a folder as a source for grunt?

I am trying to run this gruntfile:
module.exports = function (grunt) {
grunt.initConfig({
typescript: {
base: {
src: ['/app/*.ts'],
dest: 'wwwroot/app.js',
options: {
module: 'amd',
target: 'es5'
}
}
}
});
grunt.loadNpmTasks("grunt-typescript");
};
This works for files in /app/*.ts but how can I make it so that every .ts file (including those in subdirectories under /app) is run?
This should do it:
src: ['/app/**/*.ts'],

grunt htmlmin: don't specify filename in the gruntfile.js

my task is the following:
htmlmin : {
dist : {
options : {
removeComments : true,
collapseWhitespace : true
},
files : {
'index.html' : 'index-src.html'
}
}
},
this works fine when i have just one html file on my site, so this processes index-src.html into minified index.html.
what if i have 100 other html files to process? i don't want to manually list them in my gruntfile.
how can i abstract the file name and tell grunt to minify my src file to the corresponding production file? in my case they are:
source file is [name]-src.html
production file is [name].html
i'm guessing it's just a matter of syntax, but i don't know what to write.
thanks! :)
See the Globbing Patterns section of the Grunt Documentation.
I believe you'll just have to change your param files object to:
'index.html' : '*-src.html'
Update
Re-reading your question, I realized you needed a 1-1 file conversion for dynamic source and destination file names.
For that see Building the files object dynamically
I have yet to use this in my project but the syntax looks straight forward. You may need to change your src vs production naming convention to a folder based convention.
/source/name.html (source folder)
/build/name.html (destination folder)
Example
files: [
{
expand: true, // Enable dynamic expansion.
cwd: 'source/', // Src matches are relative to this path.
src: ['*-src.html'], // Actual pattern(s) to match.
dest: 'build/', // Destination path prefix.
ext: '.html', // Dest filepaths will have this extension.
extDot: 'first' // Extensions in filenames begin after the first dot
}
]
module.exports = function (grunt) {
// 1. All configuration goes here
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
controlCss: {
src: ['UI.controls/assets/css/*.css'],
dest: 'UI.controls/assets/css/min/production.css'
},
controlJs: {
src: ['UI.controls/assets/js/*.js'],
dest: 'UI.controls/assets/js/min/production.js'
},
coreJs: {
src: ['UI.core/assets/js/*.js'],
dest: 'UI.core/assets/js/min/production.js'
},
dist: {
src: ['UI.controls/assets/templates/*.htm'],
dest: 'UI.controls/assets/templates/min/production.min.htm'
}
},
cssmin: {
controlCss: {
src: 'UI.controls/assets/css/min/production.css',
dest: 'UI.controls/assets/css/min/production.min.css'
}
},
uglify: {
controlJs: {
src: 'UI.controls/assets/js/min/production.js',
dest: 'UI.controls/assets/js/min/production.min.js'
},
coreJs: {
src: 'UI.core/assets/js/min/production.js',
dest: 'UI.core/assets/js/min/production.min.js'
}
},
htmlmin: {
dist: {
options: {
removeComments: true,
collapseWhitespace: true
},
expand: true,
cwd: 'build',
src: ['UI.controls/assets/templates/*.htm'],
dest: 'UI.controls/assets/templates/min/production.min.htm'
}
}
});
// 2. Where we tell Grunt we plan to use this plug-in.
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-htmlmin');
// 3. Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask('default', ['concat', 'cssmin', 'uglify', 'htmlmin']);
};

Categories

Resources