How do I make sure grunt only selects files (not folders)? - gruntjs

I'm trying to concatenate all the JS libraries in our project into a single file. So I've set up a concat task in grunt, with the following file selector:
dist : {
src : ["public/lib/**/*.js"],
dest : "public/lib.concat.js"
}
So far so good. However, we use sprintf.js in our project. So there is a sprintf.js directory inside of public/lib and that directory is matched by the src selector in grunt.
The result of that is:
$ grunt
Running "concat:dist" (concat) task
Warning: Unable to read "public/lib/sprintf.js" file (Error code: UNKNOWN). Use --force to continue.
I'm aware that I could simply pick a different name for the sprintf.js directory, but I would like to know if there is a way to tell grunt to only select actual files, not directories.

Use filter option to ignore directories:
dist : {
src : ["public/lib/**/*.js"],
dest : "public/lib.concat.js",
filter: function(filepath) {
return !grunt.file.isDir(filepath);
}
}

it should be even easier. you can just exclude with an exclamation pointer:
dist : {
src : ["public/lib/**/*.js", "!public/lib/sprintf.js" ],
dest : "public/lib.concat.js"
}

Related

Grunt how to run task with different arguments

The source config example below processes files from src dir. There is src2 dir which also should be processed with the same tasks and putted to build2. What changes required in config.
module.exports = function (grunt) {
var saveLicense = require('uglify-save-license');
grunt.initConfig({
clean : {
build : {
src : ['build']
},
},
copy : {
files : {
cwd : 'src',
src : '**/*',
dest : 'build',
expand : true
}
},
...
Both grunt-contrib-copy and grunt-contrib-clean, like many other grunt plugins, allow multiple Targets to be specified in each Task.
For your scenario you can simply configure two Targets in the copy task (one Target to copy the src folder and another Target to copy the src2 folder).
You can also configure two Targets in the clean task (one Target to clean the build folder and another Target to clean the build2 folder).
Gruntfile.js
Your Gruntfile.js can be configured as ass follows:
module.exports = function(grunt) {
var saveLicense = require('uglify-save-license');
grunt.initConfig({
// The 'clean' task now includes two targets.
// named 'build1' and 'build2'
clean: {
build1: {
src: ['build']
},
build2: {
src: ['build2']
}
},
// The 'copy' task now includes two targets.
// named 'src1' and 'src2'
copy: {
src1: {
cwd: 'src',
src: '**/*',
dest: 'build',
expand: true
},
src2: {
cwd: 'src2',
src: '**/*',
dest: 'build2',
expand: true
}
}
// ...
});
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-clean');
// Registering the Targets in the Tasks....
grunt.registerTask('copySrc1', ['copy:src1']);
grunt.registerTask('cleanBuild1', ['clean:build1']);
grunt.registerTask('copySrc2', ['copy:src2']);
grunt.registerTask('cleanBuild2', ['clean:build2']);
grunt.registerTask('copyBoth', ['copy']);
grunt.registerTask('cleanBoth', ['clean']);
};
Running the Grunt Tasks
You'll notice that there are six calls to the .registerTask(...) function at the end of the snippet. Namely; copySrc1, cleanBuild1, copySrc2, cleanBuild2, copyBoth, and cleanBoth.
They allow you to run the following commands via your command line:
$ grunt copySrc1
(This will copy the src folder to the build folder)
$ grunt cleanBuild1
(This will clean the build folder)
$ grunt copySrc1
(This will copy the src2 folder to the build2 folder)
$ grunt cleanBuild2
(This will clean the build2 folder)
$ grunt copyBoth
(This will copy the src folder to the build folder and copy the src2 folder to the build2 folder)
$ grunt cleanBoth
(This will clean both the build and build2 folders)
Notes
You probably only need to keep the two .registerTask(...) functions as follows:
grunt.registerTask('copyBoth', ['copy']);
grunt.registerTask('cleanBoth', ['clean']);
However, I included the other four .registerTask(...) functions as they demonstrate how you can call a single Target inside a Task using the semicolon notation (:). For example:
grunt.registerTask('copySrc1', ['copy:src1']);
In the above snippet the ['copy:src1'] part simply runs only the Target named src1 inside the copy Task.
Whereas:
grunt.registerTask('copyBoth', ['copy']);
... does not reference any Targets in the copy task, (i.e. no semicolon notation is used), therefore all Targets will be run.
To further understand Tasks, Targets, you can read my answer to this post.
Hope that helps!

Compiling files with laravel + elixir

I am taking over a laravel project that uses elixir to compile various sass, coffeescript, and javascript files:
elixir(function(mix) {
mix.sass('main.scss')
.coffee(['methods.coffee', 'details.coffee', 'cars.coffee', 'context-menu.coffee', 'content.coffee', 'projects.coffee', 'main.coffee'])
.styles(['main.css'], 'public/css/all.css', 'public/css')
.scripts(['app.js'], 'public/js/all.js', 'public/js')
.version(['css/all.css', 'js/all.js']);
});
My questions:
What is the destination of the files below after they are compiled?
.coffee(['methods.coffee', 'details.coffee', 'cars.coffee', 'context-menu.coffee', 'content.coffee', 'projects.coffee', 'main.coffee'])
Does the line below compile the app.js file as all.js and store it in public/js?
.scripts(['app.js'], 'public/js/all.js', 'public/js')
Similarly, does the line below compile the main.css file as all.css and store it in public/css?
.styles(['main.css'], 'public/css/all.css', 'public/css')
Thanks in advance!
By default, the task will place the compiled in:
sass = public/css/app.css
coffee = public/js/app.js
scripts= public/js/all.js
styles = public/css/all.css
UPDATE
To change the output path just pass a second argument to the method
e.g.
mix.styles([
'bundle.css'
], 'public/css/aloha');

Task not found when grunt is run using load-grunt-config

I am learning Grunt and want to use load-grunt-config to start with. Here is my code :
Gruntfile.js
module.exports = function (grunt){
var path = require('path');
require('load-grunt-config')(grunt, {
configPath: path.join(process.cwd(), 'grunt-tasks'),
});
grunt.registerTask('install',['test']);
};
I have grunt-tasks folder in root directory of my project along with Gruntfile.js and in that I have included test.js
test.js
module.exports = {
test :{
local : {
}
}
};
Now when I say grunt install from command line and using CWD as my project's root directory I get following error :
Warning: Task "test" not found. Use --force to continue.
and when I include following segment in Gruntfile.js
loadGruntTasks : {
pattern : '*'
}
I get following error :
>> Local Npm module "load-grunt-config" not found. Is it installed?
Warning: Task "test" not found. Use --force to continue.
May I know what I don't understand here?

Can I call js module in grunt configuration file gruntfile.coffee?

I'm using gruntjs to building my project. I want to utilize js module for multi-projects i.e. multi-gruntfile.
I see the API and search grunt plugins but not find what I want. It seems the only way is taking advantage of grunt.config and load-grunt-tasks plugin.
So I created js module file in the tasks folder and set configuration data in it like the following(by coffeescript):
module.exports = (grunt) ->
_ret=null
environmentObj=
test: "test"
verify: "beta"
formal: "release"
grunt.config.set('executeCustomTasks', (arg, arg1, arr) ->
str = constructPromptStr();
_ret = getVerInfo(arg1, arg)
setArg()
...
)
setArg = ->
if _ret.verName is 'formal'
_ret.verName = ''
grunt.config.set('state',_ret.verName)
grunt.config.set('date',_ret.verNum)
and call it like this:
grunt.task.registerTask('default', 'execute tasks by param by grunt cli', (arg, arg1) ->
grunt.config.get('executeCustomTasks')(arg, arg1,getTasksArr(arg))
)
Is what I do correct? Is it the best practice?
Best Regards
I understand now. grunt.task.loadTasks(path) can Load task-related files so I can create and reference the files in the path.
reference links:
http://gruntjs.com/api/grunt.task
https://github.com/cowboy/wesbos/commit/5a2980a7818957cbaeedcd7552af9ce54e05e3fb

Grunt Concat cannot write to file

Just installed latest Grunt on Ubuntu 12.04. Here is my gruntfile:
module.exports = function(grunt){
//project configuration
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
slides : {
src : ['src/top.html', 'src/bottom.html'],
dest : ['build/index.html']
}
}
});
//enable plugins
grunt.loadNpmTasks('grunt-contrib');
grunt.registerTask('default', ['concat:slides']);
}
This creates the build/ directory fine, but gives me the output of:
Running "concat:slides" (concat) task Warning: Unable to write
"build/index.html" file (Error code: undefined). Use --force to
continue.
I tried running chmod 777 on the directory, as I thought it might have something to do with permissions, but that didn't seem to change anything.
How can I make it so Grunt will write to build/index.html?
Figured it out:
//Does not work
dest : ['build/index.html']
Works as a string, but not an array:
//Works
dest : 'build/index.html'
I changed tasks/concat.js to accept arrays for dest:
// Write the destination file.
// If f.dest is an array take the first element
var dest = ([].concat(f.dest))[0]
grunt.file.write(dest, src);
but later I decided to use the files form instead of src/dest:
files: { 'dest.js': ['a.js', 'b.js'] }

Resources