I have added the Sass task to my grunt process using the grunt-contrib-sass plugin. Here is my gruntfile:
module.exports = function ( grunt ) {
grunt.loadNpmTasks('grunt-contrib-sass');
/**
* Load in our build configuration file.
*/
var userConfig = require( './build.config.js' );
/**
* This is the configuration object Grunt uses to give each plugin its
* instructions.
*/
var taskConfig = {
/**
* We read in our `package.json` file so we can access the package name and
* version. It's already there, so we don't repeat ourselves here.
*/
pkg: grunt.file.readJSON("package.json"),
sass: {
dev: {
files: [{
expand: true,
cwd: 'css',
src: ['**/*.scss'],
dest: 'css',
ext: '.css'
}]
},
prod: {
files: [{
expand: false,
cwd: 'css',
src: ['**/*.scss'],
dest: 'css',
ext: '.css'
}]
}
},
};
grunt.initConfig( grunt.util._.extend( taskConfig, userConfig ) );
grunt.registerTask('default', [ 'sass:prod' ]);
grunt.registerTask('dev-build', [ 'sass']);
grunt.registerTask('sass', [ 'sass:dev' ]);
grunt.event.on('watch', function(action, filepath, target) {
grunt.log.writeln(target + ': ' + filepath + ' has ' + action);
});
};
I have Ruby 1.9.3 and the Sass Gem 3.3.2 installed and working from the command line and IntelliJ 13. But when I try to run grunt sass or apply a grunt watch to my scss files, I get the following trace output:
<c:\users\[proj_dir_path]>grunt sass --verbose
Initializing
Command-line options: --verbose
Reading "gruntfile.js" Gruntfile...OK
Registering Gruntfile tasks.
Registering "grunt-contrib-sass" local Npm module tasks.
Reading C:\Users\[proj_path]\node_modules\grunt-contrib-sass\package.json...OK
Parsing C:\Users\[proj_path]\node_modules\grunt-contrib-sass\package.json...OK
Loading "sass.js" tasks...OK
+ sass
Reading package.json...OK
Parsing package.json...OK
Initializing config...OK
Loading "gruntfile.js" tasks...OK
+ sass
Running tasks: sass
Running "sass" task
[About 500 more repeats of this]
Running "sass" task
Warning: Maximum call stack size exceeded Use --force to continue.
Aborted due to warnings.
To run the SCSS Gem, I have to execute the scss.bat command with the arguments. My best guess is that the Grunt Sass plugin is trying to execute the Ruby EXE with arguments while on my system I have to run it with the the bat. This is just my guess combing through the sass.js Task code. Has anyone else had a similar issues and is there any workaround or solve for this?
I think it is a recursion problem, the registered task is running itself in a loop.
mine works without
grunt.registerTask('sass', [ 'sass:dev' ]);
as it appears anything set in the initConfig is automatically a task. If removing that line doesn't work try renaming it
grunt.registerTask('my-sass', [ 'sass:dev' ]);
and running
grunt my-sass
Try changing -
grunt.registerTask('sass', [ 'sass' ]);
to
grunt.registerTask('sass', [ 'sass:dev' ]);
or
grunt.registerTask('sass', [ 'sass:prod' ]);
Related
I'm trying to concatenate and then babelify and uglify files with Grunt.
I'd like to read an external file list, from a file where the files are written one for each line, newline separated.
I'm trying to use the following GruntFile.js, but Grunt says (after I added the src=['<%= jsFiles.toString().split("\n") %>'] line):
Running "browserify:dist1" (browserify) task
Warning: An error occurred while processing a template (Invalid or unexpected token). Use --force to continue.
Where is the error?
This is the GruntFile.js
module.exports = function(grunt) {
grunt.initConfig({
jsFiles: grunt.file.read('scripts/s.list'),
env: {
prod: {
NODE_ENV: 'production'
}
},
browserify: {
dist1: {
options: {
transform: [
['babelify', {presets: ['es2015']}]
]
},
src: ['<%= jsFiles.toString().split("\n") %>'],
dest: '/WebContent/js/libs/s.bundle.js'
},
},
uglify: {
my_target1: {
files: {
'/WebContent/js/libs/s.bundleuglified.js': ['/WebContent/js/libs/s.bundle.js']
}
},
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-browserify');
grunt.loadNpmTasks('grunt-env');
grunt.registerTask('default', ['release']);
grunt.registerTask('release', ['env', 'browserify', 'uglify']);
};
Edit: I added a backslash to \n and the error has gone, but the babelify task gives me an empty file...
Edit2: I was able to read the file list using the following two lines at the beginning of the GruntFile.js
const jsFiles = grunt.file.read('scripts/s.list');
const jsFilesArray = jsFiles.toString().split("\n");
and then
src: jsFilesArray.slice(0, jsFilesArray.length-1),
because the last element was '' and it gave the error Warning: must provide pattern” as Beniamin H suggested.
Edit3: I found that the babelify task was reading the files in alphabetical order, so I had to first concat them, as explained here, and then babelify and uglify
You don't need to use any '<%= %>'. The file is read synchronously into jsFiles property and it can be used immediately. You may want to specify encoding for grunt.file.read to get a string: https://gruntjs.com/api/grunt.file#grunt.file.read
I have the following gruntfile.js. Using grunt-contrib-concat and grunt-contrib-uglify together.
This is an extention of a developement asked #Dynamic Mapping and Concat with Grunt Uglify
I use banner in the uglify task to reference a file created in the concat task.
module.exports = function(grunt){
// Configure task(s)
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// setup concats
concat: {
options: {
separator: ';\n',
},
dev: {
files: [{
src: [
'sports.js',
'salon.js',
'offRoad.js',
],
dest: 'src/js/concat/car-dev.js'
}],
},
},
// setup uglify task
// this will produce a car js file (which includes car-dev.js) for every car js file located within scr/js/cars/
uglify: {
// dev - use in development mode, global overrides section
dev: {
options: {
// include concat dev.js
banner: grunt.file.read('src/js/concat/car-dev.js'),
beautify: true,
mangle: false,
compress: false,
preserveComments: 'all'
},
files: [{
expand: true,
cwd: 'src/js/cars/',
src: '*.js',
dest: 'javascript/dev',
ext: '.dev.js',
extDot: 'first'
}],
},
},
});
// Load the plugins
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-sass');
// Register task(s)
grunt.registerTask('default',
'concat:dev'
'uglify:dev'
]);
};
My issue is that if src/js/concat/car-dev.js doesn't exist, I get the following error:
Error: Unable to read "src/js/concat/car-dev.js" file <Error code: ENOENT).
If I create an empty file #src/js/concat/car-dev.js the grunt command works fine.
However this is not always possible. I want uglify to reference the car-dev.js file even if it doesn't exist. What I'm looking for is someway to reference the grunt->concat->dev->files->dest file.
I've tried adding the following
banner: grunt.file.read(grunt.concat.dev.files.dest),
and
banner: grunt.concat.dev.files.dest
but neither work. Is this possible?
This is not a task dependency issue - the error gets thrown before any tasks are run because banner: src/js/concat/car-dev.js does not exist.
Any help - much appreciated.
I'm looking into npm, grunt and bower, and I've made my first task which looks like this.
module.exports = function(grunt){
grunt.initConfig({
concat: {
options: {
separator: ';',
},
dist: {
src: ['node_modules/jquery/dist/jquery.js', 'node_modules/handlebars/dist/handlebars.js'],
dest: 'dist/scripts.js',
},
},
});
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('default', ['concat']);
};
I was wondering if there's an easier/better way of adding the scripts. So that instead of typing the whole path you could just do src: [jquery, 'handlebars'],
and if bower is of any use regarding this?
Thank you.
I have the following Gruntfile.js:
module.exports = function(grunt) {
var config = {
pkg: grunt.file.readJSON('package.json'),
/* Some other tasks... */
uglify: {
options: {
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */\n'
},
def: {
files: {
'out/src.js': 'out/src.min.js'
}
}
}
};
grunt.initConfig(config);
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('default', [/* <other-tasks>, */ 'uglify:def']);
};
Folder structure is as follows:
project
|
+-out (folder)
+-Gruntfile.js
Important: I run grunt from the project folder.
When running grunt, there is a task before uglify:def which is responsible for generating src.js into project/out.
When I run grunt I can see src.js being generated into project/out, but when Grunt runs uglisy:def I get the following error:
Running "uglify:def" (uglify) task.
Destination out/src.js not written because src files were empty.
No files created.
What am i doing wrong?
Log
When running with --verbose I get:
Running "uglify:def" (uglify) task
Verifying property uglify.def exists in config...OK
Files: [no src] -> out/src.js
Options: banner="/*! My Pack 2015-07-19 */\r\n", footer="", compress={"warnings":false}, mangle={}, beautify=false, report="
min", expression=false, maxLineLen=32000, ASCIIOnly=false, screwIE8=false, quoteStyle=0
>> Destination out/src.js not written because src files were empty.
>> No files created.
I've a configuration like the following, and it works fine for me.
// uglify javascript
uglify: {
dev: {
options: {
mangle: true
},
files: {
'js/dest.min.js': 'js/source.js'
}
}
},
Probably you confused the destination with the source. Try to switch them.
It were happening due to, you are not registering above given tasks.
OK, lets start with concatenation in grunt:
concat: {
css: {
src: ['./assets/css/*.css', './assets/css/**/*.css'],
dest: './dist/css/style.css'
},
js: {
src: ['./assets/js/*.js', './assets/js/**/*.js'],
dest: './dist/js/script.js'
}
},
so, this concat is supposed to collect all css files from above given url / directories and concatenate to given destination in one place and so with js.
this will be simple concatenated style.css and script.js at dest destination directory.
but it won't work, till you not register this concat task inside below line:
grunt.registerTask('default', ['concat', 'cssmin', 'uglify']);
So, till concat will not concatenate those files in dest directory, how the uglify will collect and work!
Conclusion: task won't get execute till you not mention them inside grunt.registerTask function.
My problem was that the path to my source file was incorrect. So it wasn't so much that the file is "empty" but that it can't be found.
I'm new to Grunt, and am trying to configure grunt-contrib-sass to work alongside Compass.
I'm using the grunt-contrib-sass plugin, as I need to export my .scss files to two separate destinations and I couldn't get that to work with grunt-contrib-compass.
The problem that I'm having, is that on compile of .scss files I get 'ERROR: Cannot load compass' in the terminal.
Here's a copy of my gruntfile.js;
module.exports = function(grunt){
grunt.initConfig({
uglify: {
my_target: {
files: {
'wp-content/themes/mytheme/js/functions.js' : [ 'components/js/*.js' ]
}
}
}, // uglify
sass:{
dist:{
files: {
'wp-content/themes/mytheme/style.css' : 'components/sass/style.scss',
'wp-content/themes/mytheme/css/ie.css' : 'components/sass/ie.scss '
},
options: {
compass: true,
}
}
},
watch: {
scripts : {
files: ['components/js/*.js'],
tasks: ['uglify']
},
css: {
files: [ 'components/sass/*.scss'],
tasks: [ 'sass' ],
options: { livereload: true }
},
livereload: {
options: { livereload: true },
files: ['wp-content/themes/mytheme/'],
},
} // watch
})
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask( 'default', 'watch' );
} // exports
Thanks!
Grunt-contrib-sass doesn't support Compass versions less than v1.0.0 (which is in alpha at the time of writing).
After updating Compass with;
gem install compass --pre
everything appears to work fine on compilation. The same gruntfile.js was used as above.
Removing all versions of sass except of known working version 3.2.19 solved the problem for me.
$ sudo gem uninstall sass
Select gem to uninstall:
1. sass-3.2.3
2. sass-3.2.5
3. sass-3.2.19
4. sass-3.3.5
5. All versions
> 4
According to the grunt-contrib-compass github page you need to have Ruby, Sass and Compass installed as prerequisite. You are using grunt-contrib-sass instead of grunt-contrib-compass. See examples on the contrib-compass github.
I found another way to get compass to work without the ruby gem. (it is a bit of work though).
Go to https://github.com/Compass/compass and get the code.
Copy the contents of core/stylesheets/compass into your sass/scss folder. Now you can use the normal import-rules from the compass-website.
BUT:
You probably have to change some imports from compass like import "compass/support"; in _transitions.scss to import "../support";
grunt-contrib-sass perfectly works with compass, just add compass: true to options. I read this point on oficial git repository.
Example
sass: {
dist: {
options: {
style: 'expanded',
compass: true
},
files: [
{
expand: true,
cwd: 'ipa-framework/src/css/scss',
src: ['*.scss'],
dest: 'ipa-framework/src/css',
ext: '.css'
}
]
}
}
So none of the answers worked exactly for me but it did help me solve the issue.
When you install compass using
gem install compass --pre
it installs another version of sass, so dont install sass at all let the compass install do it for you.
So to get it to work
gem uninstall sass
gem install compass --pre
And for reference this is the npm libraries I needed to have to get this working
npm install -g grunt grunt-contrib-sass grunt-contrib-watch grunt-livereload sass grunt-contrib-cssmin grunt-contrib-compass