Grunt htmlmin errors - javascript

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'
}
}
}

Related

How to tell Lineman to copy all files from /dist to a different directory?

When I run lineman build it generates all the minified CSS and JS in the /dist directory. I can't figure out how to make it copy those minified files into a different directory( My Public Directory at path - ../lib/app/public).
My Lineman configuration file looks like this.
# Exports an object that defines
# all of the configuration needed by the projects'
# depended-on grunt tasks.
#
# You can familiarize yourself with all of Lineman's defaults by checking out the parent file:
# https://github.com/testdouble/lineman/blob/master/config/application.coffee
#
module.exports = require(process.env['LINEMAN_MAIN']).config.extend('application', {
removeTasks:
common: [ "webfonts:dev", "images:dev"]
dist: ["images:dist", "webfonts:dist", "pages:dist"]
server:
apiProxy:
enabled: true
host: 'localhost'
port: 4567
# enableSass: true
# configure lineman to load additional angular related npm tasks
loadNpmTasks: [ "grunt-ngmin"]
# task override configuration
prependTasks:
dist: ["ngmin"] # ngmin should run in dist only
watch:
scripts:
files: ["generated/**"],
tasks: ['copy:dev']
copy:
dev:
files: [expand: true, cwd: 'generated', src: ['css/**', 'js/**', '!**/spec.js',
'!**/*.less*', '!**/*.coffee*', '!**/*.*.map'], dest: '../lib/app/public' ]
# configuration for grunt-ngmin, this happens _after_ concat once, which is the ngmin ideal :)
ngmin: {
js: {
src: "<%= files.js.concatenated %>",
dest: "<%= files.js.concatenated %>"
}
},
})
I know there is a copy:dist default task in Lineman but not sure how it works and can't understand it properly from the documentation at http://linemanjs.com/
I solved this problem, with Lineman's help:
Wrote a custom task, tasks/dl-dev-copy.js, to copy the files:
module.exports = function(grunt) {
return grunt.registerTask('dl-dev-copy', 'Copy UI artifacts to wildfly deployment folder', ['copy:dl-dev-copy']);
};
Updated the application.js file (the key part is important, I was only able to figure it out after the Lineman folks helped me out):
loadNpmTasks: lineman.config.application.loadNpmTasks.concat('grunt-contrib-copy'),
copy: {
'dl-dev-copy': {
files: [{
expand: true,
cwd: 'generated/',
src: ['**'],
dest: '../../../target/iq/'
}]
}
},
watch: {
target: {
"files": ["app/**/*", "spec/**/*", 'spec-e2e/**/*'],
"tasks": 'dl-dev-copy'
}
},
appendTasks: {
common: ["dl-dev-copy"]
}
See below for the output of lineman run (it is similar when a file is being watched changes, and we I run lineman build):
lineman run
Running "common" task
...
Running "copy:dl-dev-copy" (copy) task
Created 6 directories, copied 23 files
...
Running "watch" task
Waiting...

Why is grunt-contrib-imagemin not using the option I set?

I have imagemin working through grunt.
As show below in the Gruntfile, I have things like optimisationLevel: 7 and so on.
The use: command tells it to use a different algo for compressing the images. It listens to all of my options except for the use one.
Anyone know why this is? Am I doing something wrong syntax wise?
Gruntfile:
module.exports = function(grunt) {
var mozjpeg = require('imagemin-mozjpeg');
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
imagemin: {
dynamic: { // Task // Target
options: {
optimizationLevel: 7,
progressive: false,
svgoPlugins: [{ removeViewBox: false }],
use: [mozjpeg({fastcrush: true})]
},
files: [{
expand: true, // Enable dynamic expansion
cwd: 'src/', // Src matches are relative to this path
src: ['**/*.{png,jpg,gif}'], // Actual patterns to match
dest: 'build/img' // Destination path prefix
}]
}
}
});
// Load the plugins
//grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-imagemin');
// Default tasks
grunt.registerTask('default', ['imagemin']);
};
CLI - You can see on line 40 it says use null.
It seems to be a logging issue of the grunt.verbose.writeFlags function which grunt use to log the task options in verbose mode.
If you will add the following code to you gruntfile.js, you will notice it incorrectly logs the value of 'use' as null:
grunt.verbose.writeflags({use: [mozjpeg()]}, 'Test');
The cause might be this reported issue, although it is not exactly the same case.

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.

Write Grunt task to console

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'
}

What files to watch with grunt-contrib-watch when wanting to reload Javascript files?

I have an app written in Coffeescript. My grunt.js file looks like this:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
clean: {
test: {
files: [{
src: ['.tmp']
}]
}
},
coffee: {
compileScripts: {
expand: true,
flatten: true,
src: '*/*.coffee',
dest: '.tmp/scripts',
ext: '.js'
},
},
jst: {
compile: {
files: {
'.tmp/scripts/templates.js': ['scripts/**/*.ejs']
}
}
},
watch: {
all: {
options: {
livereload: true,
spawn: false
},
files: ['scripts/*.coffee', 'scripts/*.ejs', 'index.html'],
tasks: ['compile'],
}
},
connect: {
server: {
options: {
port: 8000,
hostname: 'localhost',
open: true,
livereload: true
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-coffee');
grunt.loadNpmTasks('grunt-contrib-jst');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.registerTask('compile', ['clean', 'coffee', 'jst']);
grunt.registerTask('default', ['compile', 'connect', 'watch']);
}
After much tinkering, I finally got the 'watch' working where my JS files are live reloading, but I'm not clear on what goes in the 'files' section of the watch task? Did I do it right?
Do I have to watch the coffeescript files only? Or do I also have to watch index.html so that if one of the coffeescript files change, the index.html will refresh and reload the new JS? (All of my JS files are scripts in my index.html.)
The files property of the watch task contains a list of file patterns to watch and perform some action on when changed (most commonly run certain tasks).
The tasks property contains the tasks you want to run when the corresponding files have been changed.
Any target which has the livereload options configured on it will feed the files as they are changed to the live reload server. So if you have *.coffee files, they will be fed to the live reload server upon change. The live reload server only knows how to interpret js, css files so a .coffee file would refresh the entire page, instead of just the javascript.
The tasks property is optional with the watch task so a common solution to better configuring the live reload is this:
watch: {
options: { spawn: false },
all: {
files: ['scripts/*.coffee', 'scripts/*.ejs'],
tasks: ['compile'],
},
livereload: {
options: { livereload: true },
files: ['.tmp/**/*.{html,js,css}']
}
},
So as your compile task runs it will trigger the watch:livereload target and live reload by feeding the correct files.
Regarding the index.html, in your instance you probably don't need to watch that file within the watch:all target. As it doesn't have any tasks that do any building from it (at least from the config I see above).

Categories

Resources