connecting grunt-contrib-sass to yeoman and grunt-contrib-watch - javascript

Very similar to this question.
I've installed the node lib and have it in my package.json:
"devDependencies": {
...
"grunt-contrib-sass": "~0.6.0"
}
and have a block in my Gruntfile.js:
grunt.initConfig({
...
sass: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/styles/scss',
src: ['scss/{,*/}*.scss'],
dest: '<%= yeoman.app %>/styles/css',
ext: '.css'
}]
}
}
My file structure looks like so:
app
styles
css
scss
And I have the sass gem installed.
I'm sure I'm missing something very basic here that needs to be included. My yo serve doesn't seem to be putting the files in the right place to be caught up and used.
I imagine theres something I'm missing in the watch block, but I'm not sure what that is.

so my Gruntfile.js needed to look like this:
sass: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/styles/scss',
src: ['*.scss'],
dest: '.tmp/styles/',
ext: '.css'
}]
}
}
and I needed to add sass to the styles task in the watch block.

Related

How to prevent grunt uglify to override destination folder

I am trying to setup my grunt file to not to override some folders inside the destination folders, but I couldn't figure out how.
My structure
Basically I have 2 folders:
htdocs
htdocs_src
htdocs_src is the folder we use to develop things, and then we run a watch task that copies all the code to htdocs folder.
My problem
We add some libraries directly on the htdocs folder, so we don't want them to be touched by grunt uglify task... The problem is that it is not happening.
The task is configured this way:
uglify: {
options : {
beautify: false,
report: "min",
mangle: {
except: ['jQuery']
},
exclude: ['!/ifc-easy-checkout*/**/*', '!/ifc-events*/**/*', '!/ifc-vendors*/**/*'],
compress: {
global_defs: {
"DEBUG": false
}/*,
dead_code: true*/
}
},
target: {
cwd: '<%= dirs.GENERATED_JS %>',
src: ['**/*.js'],
dest: '<%= dirs.GENERATED_JS %>',
expand: true
},
},
where on the exclude property I try to say to the plugin not to override these folders, but it doesn't work.
I am currently using grunt-contrib-uglify 2.0.0
I tried several different solutions, such as changing the exclude property for exceptionsFiles, but then it searched for these folders inside the htdocs_src, since it is not there, it doesn't work (but it isn't what I want, once what I need is to avoid some folders to be overriden inside the destination folder).
Any ideas how to setup this plugin?
Try putting the excluded files in the src and remove the exclude tag
target: {
cwd: '<%= dirs.GENERATED_JS %>',
src: ['**/*.js','!/ifc-easy-checkout*/**/*', '!/ifc-events*/**/*', '!/ifc-vendors*/**/*'],
dest: '<%= dirs.GENERATED_JS %>',
expand: true
},

Minified all images - Grunt

I have more than 100 images in my images/ folder.
Here is my imagemin - Grunt Config
// The following *-min tasks produce minified files in the dist folder
imagemin: {
dist: {
files: [{
expand: true,
cwd: '<%= config.app %>/images',
src: '{,*/*/}*.{gif,jpeg,jpg,png,ico}',
dest: '<%= config.dist %>/images'
}]
}
}
When I run grunt build I saw this
Running "imagemin:dist" (imagemin) task
Minified 7 images (saved 492.79 kB)
Only 7 of my images got minified. Not all.
I've tried changing the * around in a diff combination, but so far - no luck.
src: '{,*/*/}*.{gif,jpeg,jpg,png,ico}'
How do I fix my src to minified everything in my images folder ?
I think the problem might be in the src globbing pattern. The pattern you are using only matches those images that are in the cwd root or in a two levels deep ones ({,*/*/}).
If you want all the images in the cwd directory to be minified regardless the levels of subdirectories they reside, you should use the **/* globbing pattern instead:
imagemin: {
dist: {
files: [{
expand: true,
cwd: '<%= config.app %>/images',
src: '**/*.{gif,jpeg,jpg,png,ico}',
dest: '<%= config.dist %>/images'
}]
}
}

Grunt is treating folder with a dot as a file

When trying to compile my grunt file and build into my dist folder for deployment I get the following error in the console:
Running "rev:dist" (rev) task
dist/public/app/app.js >> 63decaf3.app.js
dist/public/app/vendor.js >> a09756ab.vendor.js
dist/public/app/app.css >> d2017fc8.app.css
Warning: Unable to read "dist/public/bower_components/animate.css" file (Error code: EISDIR).
The reason for this is that I have a bower component I've got installed named animate.css. This library is of course installed in my bower_components folder, but the matching string I have in my Grunt file only looks for files with an extension of .js, .css, et cetera. Here's my matching string:
// Renames files for browser caching purposes
rev: {
dist: {
files: {
src: [
'<%= yeoman.dist %>/public/{,*/}*.js',
'<%= yeoman.dist %>/public/{,*/}*.css', // Offending line
'<%= yeoman.dist %>/public/assets/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
'<%= yeoman.dist %>/public/assets/fonts/*'
]
}
}
}
And here's the directory structure:
bower_components
-> ...
-> angular-ui-router
-> animate.css // Folder with the error
---> animate.css // File that it should be recognizing
---> animate.min.css // File that it should be recognizing
-> es5-shim
-> ...
In this case, how would I tell Grunt that this is a directory which contains files rather than a file itself?
I have slightly different approach.
bower install animate-css --save
it will grab animate.css but save at:
bower_components/animate-css
Using this method you don't have to play with Gruntfile.js which I personally consider unpleasant to edit and even look at ;)
Exclude the animate.css folder, then include everything inside it. I am not sure about the exact glob options see here, for details. Something like this:
rev: {
dist: {
files: {
src: [
'<%= yeoman.dist %>/public/{,*/}*.js',
'<%= yeoman.dist %>/public/{,*/}*.css',
'!<%= yeoman.dist %>/public/bower_components/animate.css',
'<%= yeoman.dist %>/public/bower_components/animate.css/animate.css',
'<%= yeoman.dist %>/public/assets/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
'<%= yeoman.dist %>/public/assets/fonts/*'
]
}
}
}
You should be able to use a custom filter function with the fs.Stats method. Also, there is the ext option ( Indicates where the period demarcating the extension is located. )
ext: String
src: [
'<%= yeoman.dist %>/public/{,*/}*.js',
'<%= yeoman.dist %>/public/{,*/}*.css', // Offending line
'<%= yeoman.dist %>/public/assets/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
'<%= yeoman.dist %>/public/assets/fonts/*'
],
filter: 'isDirectory',
You may need to use isFile depending on if you only want to match actual files instead.
Example of isFile usage, worked a charm for me.
// Renames files for browser caching purposes
filerev: {
dist: {
src: [
'<%= yeoman.dist %>/**/*.js',
'!<%= yeoman.dist %>/local.js',
'!<%= yeoman.dist %>/web.js',
'<%= yeoman.dist %>/styles/**/*.css',
'<%= yeoman.dist %>/images/**/*.{png,jpg,jpeg,gif,webp,svg}',
'<%= yeoman.dist %>/styles/fonts/*'
],
filter: 'isFile'
}
},

Grunt no longer livereloads

I'm new to web development and I'm trying to build a small webapp. I used yoeman to set everything up and it did pretty well, angular installed perfectly and I installed angular-animate and jquery-ui after with bower. Autoreloading the webpage happend automagically, I really liked it.
After a while it stoped livereloading my changes. I don't know why. I'm not sure what I did.
This is what my gruntfile watch section looks like:
// Watches files for changes and runs tasks based on the changed files
watch: {
js: {
files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
tasks: ['newer:jshint:all'],
options: {
livereload: true
}
},
jsTest: {
files: ['test/spec/{,*/}*.js'],
tasks: ['newer:jshint:test', 'karma']
},
styles: {
files: ['<%= yeoman.app %>/styles/{,*/}*.css'],
tasks: ['newer:copy:styles', 'autoprefixer']
},
gruntfile: {
files: ['Gruntfile.js']
},
livereload: {
options: {
livereload: '<%= connect.options.livereload %>'
},
files: [
'<%= yeoman.app %>/{,*/}*.html',
'.tmp/styles/{,*/}*.css',
'<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
}
}
It looks ok right? No errors showing up when running:
grunt serve
I had the same problem where LiveReload would stop working after a while.
What worked for me was reinstalling the LiveReload Chrome Extension, so if you didn't make any changes to the Gruntfile you can try that.

Copy all files from directory to another with Grunt.js copy

I'm trying to copy all the files in a directory to another directory as part of my build process. It works fine for individual files that I specify explicitly but when I try to copy the whole directory it does weird things like copies the full directory structure (or nothing at all). Here is the relevant part from my GruntFile.js:
copy: {
myvoice: {
files: [
{ src:"src/html/index.html", dest:"dist/myvoice/index.html" },
{ src:"src/html/css/style.css", dest:"dist/myvoice/css/style.css" },
{ src:"src/html/js/require.js", dest:"dist/myvoice/js/require.js" },
{ src:"build/myvoice/main.js", dest:"dist/myvoice/js/main.js" },
{ src:"src/html/css/fonts/*", dest:"dist/myvoice/css/fonts/" }
]
}
},
Specifically it's the last line that I can't get to work:
{ src:"src/html/css/fonts/*", dest:"dist/myvoice/css/fonts/" }
The flatten: true option as in this answer might work for some cases, but it seems to me that the more common requirement (as in my case) is to copy a folder and its sub-folder structure, as-is, to dest. It seems that in most cases if you have sub-folders, they are probably being referenced that way in code. The key to doing this is the cwd option, which will preserve folder structure relative to the specified working directory:
copy: {
files: {
cwd: 'path/to/files', // set working folder / root to copy
src: '**/*', // copy all files and subfolders
dest: 'dist/files', // destination folder
expand: true // required when using cwd
}
}
This task will maintain folder structure if you specify a file glob. What you want is the flatten option which will remove the structure.
{
expand: true,
flatten: true,
src: ['src/html/css/fonts/**'],
dest: 'dist/myvoice/css/fonts/',
filter: 'isFile'
}
Find the rest of the available options in the Github repo. Hope this helps.
I would like to add that changing the format of the glob in src will modify how the copy works.
As pointed out by bmoeskau above, the following will copy everything inside dist/ and move it to path/to/dir (overwriting the destination if it already exists).
copy: {
files: {
expand: true,
dest: 'path/to/dir',
cwd: 'dist/',
src: '**'
}
}
Note however, that:
copy: {
files: {
expand: true,
dest: 'path/to/dir',
cwd: 'dist/',
src: '*'
}
}
Will only copy files inside dist/ as well as directories, but will not copy the contents of those directories to the destination.
Also, the following with src: '*/*' will only copy directories with contents inside dist/. That is, files just inside dist/ will not be copied.
copy: {
files: {
expand: true,
dest: 'path/to/dir',
cwd: 'dist/',
src: '*/*'
}
}
Finally, same as above, but src: '**/**' will copy only files inside dist/ as well as files inside dist/ subdirectories to path/to/dir. So there will be no folders inside the destination.
copy: {
files: {
expand: true,
dest: 'path/to/dir',
cwd: 'dist/',
src: '*/*',
flatten: true,
filter: 'isFile'
}
}
Had to use egdy instead curly braces for the files segment (in Coffeescript)...
copy: {
files: [
cwd: 'path/to/files'
src: '**/*'
dest: 'dist/files'
expand: true
]
}
If you are developing with angular yeoman , then this is the better way to copy with grunt.
expand: true is required when using cwd. <%= yeoman.app %> is just the app route ('.').
{
expand: true,
cwd: '<%= yeoman.app %>/data',
dest: '<%= yeoman.dist %>/data',
src: ['**']
}

Categories