Grunt jade error - javascript

Whenever I run grunt jade I get an error:
Warning: pattern.indexOf is not a function Use --force to continue.
Now here is my jade task:
jade: {
options: {
pretty: true
},
all: {
files: {
expand:true,
cwd: 'src/static/jade',
ext: "html",
src: ['src/static/jade/**/*.jade', '!src/static/jade/_includes'],
dest: 'build/'
}
}
}
So basically I am trying to take the jade files in src/static/jade (including subdirs, except _include) and put them in build, keeping the directory structure. I have tryed commenting the expand line, however it gives me:
Warning: Unable to read "src/static/jade" file (Error code: EISDIR). Use --force to continue.
Perhaps I am going about this the wrong way. How should I fix this?

Your initial issues is that files should be an array of objects, not just an object: files: [{...}].
But then you have other troubles with your file definition:
if you specify cwd, your src should not repeat it
your ext needs a starting .
your ! pattern needs to specify files instead of a dir
So you need:
files: [{
expand:true,
cwd: 'src/static/jade/',
ext: ".html",
src: ['**/*.jade', '!_includes/**/*.jade'],
dest: 'build/'
}]

Related

How to read an external file list with grunt

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

Grunt watch pattern.indexOf is not a function

I'm trying to use Grunt's grunt-contrib-watch plugin to watch some files and then run the tasks, just what it was made for, this is my Gruntfile.js
module.exports = function(grunt){
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
options: {
sourceMap: true,
outputStyle: 'compressed'
},
dist: {
files: {
'static/stylesheets/main.min.css': 'static/stylesheets/sass/main.scss',
/*'bower_components/foundation-sites/dist/foundation.min.css': 'bower_components/foundation-sites/scss/foundation.scss'*/
}
}
},
uglify: {
dist: {
files: {
'static/javascript/main.min.js': 'static/javascript/main.js'
}
}
},
watch: {
files: [
'<%= sass.dist.files %>',
'<%= uglify.dist.files %>'
],
tasks: [
'sass',
'uglify'
]
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('default', ['watch']);
};
When I run it, it runs over and over and over again, and when I stop it, I see I have this message:
Running "watch" task
Waiting...
Warning: pattern.indexOf is not a function
I really don't know what's the problem. Does anybody know what happens here?
UPDATE:
Apparently, the problem is because of the way I call the files, because I changed it to: 'static/stylesheets/sass/*.scss' and it worked well, but I would like to know why the other way doesn't work, because I think is a more useful way to do it.
grunt-contrib-watch expects either a single pattern string or an array of pattern strings as the value of its files config. However, the templates you are using in your config evaluate to objects. Your watch.files value evaluates to the following:
files: [
{ 'static/stylesheets/main.min.css': 'static/stylesheets/sass/main.scss' },
{ 'static/javascript/main.min.js': 'static/javascript/main.js' }
]
When the pattern matching tries to run it fails because there is no indexOf method on an Object. Due to the fact that grunt-contrib-watch runs forever, there is an infinite loop of the trying and failing to build the list of watched files.
You would normally configure your watch files with something like the following:
files: [
'static/**/*.scss',
'static/**/*.js'
]
But the above will cause issues in your case because your minified JS file is in the same folder as your source JS file. You could probably get around this by adding '!static/**/*.min.js' to your files array, but a better solution would be to put all of your compiled files into a separate folder.
Extract the values from the object:
watch: {
files: [
'<%= sass.dist.files.values() %>',
'<%= uglify.dist.files.values() %>'
],

Error running simple copy task with grunt

why cant I run this simple defined task with grunt? :
copy: {
templates: {
files: [{
expand: true,
cwd: ['src/tpl'],
src: ['**/*.tpl'],
dest: 'dist/assets/tpl'
}]
}
}
but when i try to run that task i get this warning:
$ grunt copy:templates
Running "copy:templates" (copy) task
Verifying property copy.templates exists in config...ERROR
>> Unable to process task.
Warning: Required config property "copy.templates" missing. Use --force to continue.
Aborted due to warnings.
is a very simple task, uglify and other tasks i had made works perfect.
The cwd property of files should be an string not an Array.
Fixed task:
copy: {
templates: {
files: [{
expand: true,
cwd: 'src/tpl',
src: ['**/*.tpl'],
dest: 'dist/assets/tpl'
}]
}
}
Output:
C:\Foo>grunt copy
Running "copy:templates" (copy) task
Done, without errors.
Reference: http://gruntjs.com/configuring-tasks#building-the-files-object-dynamically

grunt sass and js autoloader

I've tried a few things but can't come to a good solution.
I'm using grunt to compile my sass and minify my javascript.
Is it possible to autoload every .sass file and every .js file in a specific directory?
I've tried stuff like this
sass: {
options: {
sourceMap: false
},
dist: {
src: 'src/sass/**/*.sass',
dest: 'dist/css/style.css'
}
}
but this will only load the very first sass file.
I'm not sure what concat even does but I tried it aswell and didn't find the solution I was looking for.
Basicly all files in the folder sass/ should be compiled to 1 big style.css file the same with javascript.
Sure I could manually import each file in a main.sass file or so, but I would love a autoload function so I don't get lazy and don't create new files because I would have to add them.
edit:
So with this
files: [{
expand: true,
cwd: "src/sass/",
src: ["**/*.sass"],
dest: "dest/css",
ext: ".css"
}]
I can actually do what I want. The problem is my mixins get loaded too late and it's thorwing an error because it doesn't find the mixin I wanted to include.
This is a format to generate a single output file from multiple source files:
concat: {
whatever: {
options: { separator: '\n' },
src: ['src/sass/**/*.sass'],
dest: 'build/tmp.sass' // make sure the temporary build/ dir exists!
}
}
It only works on tasks supporting combining multiple files; in this case the grunt-contrib-concat task.
It produces dist/css/sass.tmp, which you will need to process with the sass task:
sass: {
dist: {
files: [{
src: 'build/tmp.sass',
dest: 'dist/css/style.css'
}]
}
}
You would make sure they are run in sequence with something like this:
grunt.registerTask( 'default', ['concat', 'sass'] ); // add your uglify/cssmin here
However, I don't recommend this, because the order of the sass files is uncontrollable, and it won't make mixin's available, even if they are compiled to css first - which is pointless, because they loose their 'mixin' format. It's best to run sass on a single source file and import your other files in that source file.
Update
Regarding auto-loading of mixin files,
the SASS Reference does mention you can use custom importers (written in Ruby) that take care of #import; I'm not sure whether this is only for top-level importing of files, or also for #import mixin-name(foo) within rules, but I don't think so.
There is an alternative approach you could use, based on concat, assuming that you have one main sass file. You would need to add a single #import 'all-mixins' to it. This all-mixins.sass is a generated file:
concat: {
all_mixins: {
options: { separator: '\n' },
src: ['src/sass/mixins/*.sass'],
dest: 'build/all-mixins.sass'
}
}
And you would specify the sass option loadPath to add build/ to the path:
sass: {
dist: {
options: {
loadPath: 'build/'
},
files: [{
src: 'build/tmp.sass',
dest: 'dist/css/style.css'
}]
}
}
This is as close to auto-loading as it gets without extending sass itself.

Concat a single file to every file in a directory using grunt

Using Grunt, I want to concat one file to all of the files in a build directory. The purpose of doing so is to append (or potentially prepend) IE specific CSS files to a build CSS file.
To task this:
build/
file1.css
file2.css
file3.css
And create this:
build/
file1.css
file1.ie.css
file2.css
file2.ie.css
file3.css
file3.ie.css
I thought that the expand option might be what I was looking for but I can't figure out how to get it to do what I want.
Try the banner option in grunt-contrib-concat:
concat: {
dist: {
options: {
banner: '/* IE specific things here */',
},
expand: true,
cwd: 'build/',
ext: '.ie.css',
src: ['**/*.css'],
dest: 'build/',
},
},

Categories