Write Grunt task to console - javascript

This is relevant to any Grunt task which has a source file and a destination (output file).
When I run grunt in my command line, I don't want Grunt to write anything to file, I just want to view (return) the output to my console, be it Bash, CMD or any CLI.
Lets take uglify for example.
module.exports = function(grunt) {
grunt.initConfig({
uglify: {
options: {
mangle: true,
sourceMap: true,
},
build: {
src: 'js/foo.js',
dest: 'js/foo.min.js' <-- Don't need this.
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('default', ['uglify']);
};
Instead of Done, without errors, when successful, I want to view the uglifed code in the console.
For context, I need this for a command line application which won't need anything written to disk. I just need to use the output on the fly (I'm trying to avoid writing to file and re-reading from the CLI).

You could write directly to /dev/stdout ( not on windows tough ):
build: {
src: 'js/foo.js',
dest: '/dev/stdout'
}

Related

Grunt htmlmin errors

I'm using grunt-contrib-htmlmin plugin. This is how my Gruntfile.js looks like:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
htmlmin: {
dist: {
options: {
removeComments: true,
collapseWhitespace: true
},
files: {
'/views/build/404.html': '/view/src/404.html'
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-htmlmin');
grunt.registerTask('default', ['htmlmin']);
};
Nothing special, really. My 404.html is also pretty simple, but even on simpler HTML files, grunt doesn't work. For example, let's say take following HTML file:
<html>
<head>
</head>
<body>
</body>
</html>
It doesn't even work on that. What I get as a result in console is:
Running "htmlmin:dist" (htmlmin) task
Minified 0 files (1 failed)
Done, without errors.
Where can I see why it failed?
I tried really many things like removing options and I also tried changing file structure where I ended up with this:
files: {
expand: true,
cwd: 'views/src/',
src: '404.html',
build: 'views/build/404.html'
}
But that doesn't work either and error that I'm getting now is this:
Running "htmlmin:dist" (htmlmin) task
Warning: pattern.indexOf is not a function Use --force to continue.
Aborted due to warnings.
What am I doing wrong?
I don't know the actual reason for the error. But modifying the source by adding square brackes, as below, worked for me.
files: [{
expand: true,
cwd: 'views/src/',
src: '404.html',
build: 'views/build/404.html'
}]
To see the logs run command:
grunt task:target --verbose
In your case it will be: grunt htmlmin:dist --verbose
The error seems to be in your file path: '/views/build/404.html'. '/' means that plugin will start to search from the root folder in unix systems. Use relative path:
'views/build/404.html': 'view/src/404.html'
OR
'./views/build/404.html': './view/src/404.html'
P.S. For all others please note that in 'files' you should specify DESTINATION path first and only then SRC path.
htmlmin: {
dist: {
options: {
/* options here*/
},
files: {
'path/to/destination/folder/404.html': 'path/to/src/folder/404.html'
}
}
}

Running grunt.file.copy returns Error code: ENOENT

I want to copy a directory to a different location using a Grunt task. I don't want this to be run in my default task, where copy is run, so I am registering a new task for it called "myTask" using the following code:
grunt.registerTask('myTask', 'Make new dir and copy "src" there', function() {
grunt.file.copy('src/*','../dest/');
});
Whenever I run myTask, it tells me:
Warning: Unable to read "src/*" file (Error code: ENOENT). Use --force to continue.
Is there a certain syntax I'm missing for the source directory I'm copying from?
You mention that you already use the copy task, but don't want to include this specific copying in your default task... so I would recommend using multiple targets in your config and just specifying which to perform in your default task array:
grunt.initConfig({
copy: {
js: {
files: [{
expand: true,
src: ['path/to/js/*.js'],
dest: 'dest/js'
}]
},
otherstuff: {
files: [{
expand: true,
src: ['src/**'],
dest: 'dest/'
}]
}
},
// ...
});
// notice that in our default task we specify "copy:js"
grunt.registerTask('default', ['jshint', 'concat', /* etc, */ 'copy:js']);
Now you can run ~$ grunt copy:otherstuff separately from ~$ grunt copy:js and when you just run ~$ grunt it will run the default task which only runs copy:js.

Grunt concat files on a different domain or on different server

Edit working version and explanation
I want to concat files from different server into my destination folder using grunt, and grunt-concat and with something like that:
concat: {
options: {
separator: ';'
},
dist: {
src: ['dev.staticcontent.com/media/clientcontent/library/*.js', 'js/*.js'],
dest: 'dist/<%= pkg.name %>.js'
}
},
each time I tried, I received no error from grunt, but my dist/marketing-home.js file is empty... Like it didn't find anything.
Console:
C:\Project\My>grunt
Running "jshint:files" (jshint) task
>> 1 file lint free.
Running "concat:dist" (concat) task
File dist/marketing-home.js created.
Running "uglify:dist" (uglify) task
Done, without errors.
New Version
After the help of Kris, I was able to do it without passing through the web using grunt-exec and doing using COPY or XCOPY shell command.
ex.
exec: {
copy : {
cmd: function () {
var path = "\\\\dev-server123\\WebSites\\Static_Contents\\Media\\clientcontent";
return "copy dist\\*.min.js " + path + " /y";
}
}
}
Doesn't look like concat task handles absolute paths or files from remote locations. However I was able to get it to work using curl task combined with the concat task.
EXAMPLE:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
curl: {
'download/jquery.js': 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js',
},
concat: {
js: {
src: ['download/jquery.js'],
dest: 'output/test.js'
},
}
});
grunt.loadNpmTasks('grunt-curl');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('default', ['curl', 'concat']);
};
DEMO DIRECTORY STRUCTURE:
I used this Node Module Package for CURL. https://github.com/twolfson/grunt-curl, there may be better ones out there. But this one seemed to work fine.

grunt watch executes tasks multiple times

I've the following Grunfile.js File:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
'css/build/style.css': 'css/style.scss'
}
}
},
watch: {
stylesheets: {
files: ['css/*.scss'],
tasks: ['newer:sass']
}
}
});
// Load the plugin that compiles sass
grunt.loadNpmTasks('grunt-contrib-sass');
// watch for, and run grunt if files change
grunt.loadNpmTasks('grunt-contrib-watch');
// Plugin for Grunt tasks to run with newer files only.
grunt.loadNpmTasks('grunt-newer');
// Grunt Tasks:
grunt.registerTask('default', ['newer:sass']);
};
After running grunt watch and saving my scss File, the console output is the following:
Running "watch" task
Waiting...
>> File "css\style.scss" changed.
Running "newer:sass" (newer) task
Running "newer:sass:dist" (newer) task
Running "sass:dist" (sass) task
File css/build/style.css created.
Running "newer-postrun:sass:dist:1:D:\xampp\htdocs\grunt-test\node_modules\grunt-newer\.cache" (newer-postrun) task
Done, without errors.
The problem is, the .scss file is compiled every time. Even if there was no change.
I don't understand why grunt is running 3 tasks (newer:sass, newer:sass:dist, sass:dist), instead of only running the task defined under watch (newer:sass).
Hope someone has an idea to fix this. :)
I'm not positive this is the problem, but try specifying that you don't want to run all of sass, just sass:dist. So try: grunt.registerTask('default', ['newer:sass:dist']);

grunt: Watch and synchronize files

I want to run a local sync daemon.
It should watch src directory and copy any changed file to dst directory. There are many subdirectories in src, so the relative paths should be preserved. All necessary subdirectories in dst are already created.
I want to filter for *.js files only.
I've found a grunt-sync tool. The documentation is so short that I even don't know if it fits me. Here's my Gruntfile:
module.exports = function (grunt) {
grunt.initConfig({
sync: {
main: {
files: [{
cwd: src,
src: ['**/*.js'],
dest: dst
}]
}
}
});
grunt.loadNpmTasks('grunt-sync');
grunt.registerTask('default', 'sync');
};
When I run grunt, I see no watch task. Grunt freezes for several seconds, then copies all files and exits. And I want a watch-sync daemon.
I created a tool called duplicate which will do what you want (though a year later), it copies all matching files when start, and keep watching if there would be any changes.
It's not written as a Gulp or Grunt plugin because it doesn't need to be, but of course you may easily run it in a Gulp or Grunt task.
Check out https://github.com/vilic/duplicate
Probably a bit late but.. I had the same question. What I´ve done is to combine both tools.. grunt-sync and grunt-contrib-watch..
module.exports = function (grunt) {
grunt.initConfig({
sync: {
main: {
files: [{
cwd: src,
src: ['**/*.js'],
dest: dst
}]
}
},
watch: {
jsxfiles: {
files: ['**/*.js'],
tasks: ['sync:main'],
} //this means that when any of the pattern files changes, the sync task will be run...
}
});
grunt.loadNpmTasks('grunt-sync');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', 'watch'); //run the watch task isntead of just the sync once..
};
I hope this is helpful
KR Jon

Categories

Resources