grunt-contrib-jade compiling to single JS with cwd - gruntjs

I am trying to compile multiple jade templates into single JS file using grunt-contrib-jade. Problem I'm facing is that with full path to templates, I get function names with full path. I want to avoid that, so I tried using cwd (without expand). This ended up with the following:
>> Source file "test.jade" not found.
>> Source file "test2.jade" not found.
Is there any way I could achieve what I plan? My grunt config for that task is as following:
jade: {
js: {
options: {
client: true,
amd: true
},
files: [ {
cwd: 'js/views/',
src: ['*.jade'],
dest: 'js/tmp/templates.js'
} ]
}
},
Thanks in advice,
Dracco

Silly me, didn't fully read the documentation of the plugin :(.
The solution is trivial, using the processName option:
options: {
client: true,
amd: true,
processName: function(path) {
var pathChunks = path.split('.')[0].split('/');
return pathChunks[pathChunks.length - 1];
}
}

Related

extra c: added to destination path on windows ((Error code: ENOENT))

Using latest version of grunt if we try to work like copying
copy: {
main: {
files: [
{ expand: true
src: ['/dev/war archive/latestfile/**/*.txt'],
dest: '/fernando/backups/pbuse/war',
filter :'isFile'
}
]
}
}
This will result in Error: Unable to create directory "C:\harikishore\backups\war\C:" (Error code: ENOENT)
In latest version of grunt we need to add the cwd(currentworkingdirectory) where the provided src is located for the action otherwise grunt-action will consider the actual system path included with src,so while creating destination will try to create the systempath which will result in the above error so it will work if change the code as below:
copy: {
main: {
files: [
{ expand: true,
cwd : '/dev/war archive/latestfile/'
src: ['**/*.txt'],
dest: '/fernando/backups/pbuse/war',
filter :'isFile'
}
]
}
}
So,now it will start the dest folder creation from src instead of system path included
Alternative: adding flaten:true property
This will allow us to pass the action since we are not creating the inner folder structure of src in dest just copying all the files and dumping in single outer folder.
If we need inner folder structure of src in dest also then we must need cwd

Looking for Modernizr references

I'm trying to use the grunt-modernizr plugin in my project but I'm receiving the following output when I run tasks:
Running "modernizr:dist" (modernizr) task
>> Explicitly including these tests:
>> pointerevents
Looking for Modernizr references
I'm not receiving any type of error the terminal just goes back to the directory that I'm in, as if it's just giving up.
Here is my grunt file:
module.exports = function(grunt) {
grunt.initConfig ({
// Do grunt-related things in here
pkg: grunt.file.readJSON('package.json'),
modernizr: {
dist: {
"dest": "javascripts/modernizr-custom.js",
"parseFiles": true,
"customTests": [],
"devFile": "javascripts/modernizr-custom.js",
"outputFile": "javascripts/min/modernizr-custom.min.js",
"tests": [
"pointerevents",
"css/pointerevents"
],
"extensibility": [
"setClasses"
],
"uglify": false
}
},
cssmin: {
target: {
files: {
'css/min/bootstrap.min.css': ['css/bootstrap.css']
}
}
},
});
grunt.loadNpmTasks("grunt-modernizr");
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.registerTask('default',['modernizr', 'cssmin']);
};
Output from running grunt --verbose:
Initializing
Command-line options: --verbose
Reading "gruntfile.js" Gruntfile...OK
Registering Gruntfile tasks.
Reading package.json...OK
Parsing package.json...OK
Initializing config...OK
Registering "grunt-modernizr" local Npm module tasks.
Reading /Applications/MAMP/htdocs/bootstrap-three-wordpress/wp-content/themes/brandozz/node_modules/grunt-modernizr/package.json...OK
Parsing /Applications/MAMP/htdocs/bootstrap-three-wordpress/wp-content/themes/brandozz/node_modules/grunt-modernizr/package.json...OK
Loading "modernizr.js" tasks...OK
+ modernizr
Registering "grunt-contrib-cssmin" local Npm module tasks.
Reading /Applications/MAMP/htdocs/bootstrap-three-wordpress/wp-content/themes/brandozz/node_modules/grunt-contrib-cssmin/package.json...OK
Parsing /Applications/MAMP/htdocs/bootstrap-three-wordpress/wp-content/themes/brandozz/node_modules/grunt-contrib-cssmin/package.json...OK
Loading "cssmin.js" tasks...OK
+ cssmin
Loading "gruntfile.js" tasks...OK
+ default
No tasks specified, running default tasks.
Running tasks: default
Running "default" task
Running "modernizr" task
Running "modernizr:dist" (modernizr) task
Verifying property modernizr.dist exists in config...OK
Files: -> javascripts/modernizr-custom.js
Verifying property modernizr exists in config...OK
>> Explicitly including these tests:
>> pointerevents
Looking for Modernizr references
This is something I just came across too and seems to be grunt-modernizr stopping after customizr doesn't find any files to crawl (it crawls by default).
If you add "crawl": false to your modernizr:dist task that should fix the problem.
Also, I think "extensibility": [ "setClasses" ], should be "options": [ "setClasses" ],.
To use the grunt-modernizr task to crawl your code for Modernizr references you'll have to look at the config properties for the customizr task as this is part of grunt-modernizr 's node_modules:
modernizr: {
dist: {
dest: 'bower_components/modernizr/build/modernizr.custom.js',
uglify: false,
options: [
'setClasses',
'addTest'
],
files: {
src: ['js/app/**/*.js', 'js/app/*.js']
}
}
}
devFile: doesn't seem to matter where you point at
dest: instead of outputFile, note I'm just outputting to a build directory that's not part of the package
uglify: false if you have other minifying options like bundleconfig.json
options: to bypass the default options { "setClasses", "addTest", "html5printshiv", "testProp", "fnBind" }
files: to enlist your crawlable director(y|ies), make sure you take care of the root files and/or subdirectories as well
Load the required tasks, in my case:
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-modernizr');
grunt.loadNpmTasks('grunt-contrib-copy');
Refer to the 'modernizr:dist' task => grunt.registerTask('default', ['clean', 'modernizr:dist', 'copy']);
Which results in an unminified 34kb file:
Running "clean:files" (clean) task
19 paths cleaned.
Running "modernizr:dist" (modernizr) task
Looking for Modernizr references
1 match in js/app/classes/yambo.options.js
bgpositionxy
1 match in js/app/modules/yambo.audio.js
audio
Ready to build using these settings:
setClasses, addTest
Building your customized Modernizr...OK
Success! Saved file to bower_components/modernizr/build/modernizr.custom.js
Process terminated with code 0.
Running "copy:main" (copy) task
Copied 11 files
Done, without errors.
This way there's no need to even go to the online build to add a feature test. Simply reference Modernizr throughout your js code:
window.Yambo = (function($, modernizr, ns){
ns.Audio = {
extension: (function () {
return modernizr && modernizr.audio.mp3
? 'mp3'
: modernizr.audio.ogg
? 'ogg'
: 'wav';
}())
};
return ns;
}(window.jQuery, window.Modernizr, window.Yambo || {}));
Make sure to use the correct property name for a feature detection, so customizr can pick it up and provide a test to your custom build.
This should be also possible for css but haven't been testing that for the moment.
It looks like you missed source files.
http://gruntjs.com/configuring-tasks#files-object-format
Try to include
"dist": {
"files": {
"src": ['!<%= appDir %>assets/js/bower/modernizr/**']
}
}

grunt-contrib-copy syntax for process option confusion

I'm trying to replace some placeholders in different files as I copy. My gruntfile works fine, but adding in the process option to do the replacements, it's just not working. Below is the relevant section of my gruntfile:
grunt.initConfig({
copy: {
js: {
files: [{
expand: true,
cwd: 'src/wp-content/themes/pilau-starter/',
src: ['**/*.js'],
dest: 'public/wp-content/themes/pilau-starter/'
}],
options: {
process: function ( content ) {
console.log( content );
content = content.replace( /pilauBreakpointLarge/g, breakpoints.large );
content = content.replace( /pilauBreakpointMedium/g, breakpoints.medium );
return content;
}
}
},
}
});
The paths can be understood in the context of the code on GitHub: https://github.com/pilau/starter (the public directory isn't committed to the repo because it's a starter theme). Those paths are variables in my original Gruntfile, and are working fine in all other tasks.
All the vars are set up OK. I've included the console.log( content ) to check if the process function's actually running - it doesn't seem to be, so I guess it's basic syntax.
There's an answer (https://stackoverflow.com/a/28600474/1087660) which seems to address this, but as far as I can tell, that way of doing it is simply bad JS syntax - not sure how it got marked as right.
--verbose output for running the copy task:
Running "copy:js" (copy) task
Verifying property copy.js exists in config...OK
Files: src/wp-content/themes/pilau-starter/js/admin.js -> public/wp-content/themes/pilau-starter/js/admin.js
Files: src/wp-content/themes/pilau-starter/js/flickity.js -> public/wp-content/themes/pilau-starter/js/flickity.js
Files: src/wp-content/themes/pilau-starter/js/global.js -> public/wp-content/themes/pilau-starter/js/global.js
Files: src/wp-content/themes/pilau-starter/js/modernizr.js -> public/wp-content/themes/pilau-starter/js/modernizr.js
Files: src/wp-content/themes/pilau-starter/js/picturefill.js -> public/wp-content/themes/pilau-starter/js/picturefill.js
Files: src/wp-content/themes/pilau-starter/js/respond.js -> public/wp-content/themes/pilau-starter/js/respond.js
Options: processContent=false, processContentExclude=[], process=undefined
Options: processContent=false, processContentExclude=[], process=undefined
Copying src/wp-content/themes/pilau-starter/js/admin.js -> public/wp-content/themes/pilau-starter/js/admin.js
Reading src/wp-content/themes/pilau-starter/js/admin.js...OK
Writing public/wp-content/themes/pilau-starter/js/admin.js...OK
Your version of grunt-contrib-copy is 0.4.0. As correctly point out by #nemesv above the property name to use in this version would be processContent not process.
I cloned your repo and switched to json-breakpoints branch. And ran grunt copy:js and it replaced the content.
Now,when you run grunt copy:js --verbose it will still show this
processContent is logged undefined because grunt uses JSON.stringify to log a value. And JSON.stringify returns undefined when you pass it a function definition.
If you are interested, here's the method reponsible for logging all the option
Log.prototype.writeflags = function(obj, prefix) {
var wordlist;
if (Array.isArray(obj)) {
wordlist = this.wordlist(obj);
} else if (typeof obj === 'object' && obj) {
wordlist = this.wordlist(Object.keys(obj).map(function(key) {
var val = obj[key];
return key + (val === true ? '' : '=' + JSON.stringify(val));
}));
}
this._writeln((prefix || 'Flags') + ': ' + (wordlist || '(none)'.cyan));
return this;
};
This doesn't appear to be an issue with the process option at all, but more an issue with srcThemeDir. I would log it to make sure you know exactly what it is, as it appears that it is causing the copy task to not find any files (and therefore not call the process function).

Grunt convert markdown to pdf recursively and dynamically

I am stuck writing a Gruntfile which aim is to convert a bunch of Markdown files to PDF dynamically. Giving the current folder hierarchy:
root/
|_subfolder1
| |_filename1.md
|_subfolder2
|_filename2.md
...
|_node_modules
|_subfolderN
|filenameN.md
I would like to run a Markdown to PDF task which would process the md file and ouput a PDF file with the matching filename in the same output directory.
I did create a custom task which is parsing current directory, ignoring the mode_modules folder and get the markdown file, but I don't know how to configure the md2pdf task with the good properties to reflect dynamic folder mapping.
Here's my current Gruntfile:
module.exports = function(grunt) {
// 1 - Configuration
grunt.initConfig({
md2pdf: {
}
});
// 2 - Plugins
grunt.loadNpmTasks('grunt-md2pdf');
// 3 - Task registering
grunt.registerTask('default', 'Get Subfolders', function() {
grunt.file.recurse('.', callback);
function callback(abspath, rootdir, subdir, filename) {
var filenameOutExt;
// if current occurence is a file subdir == undefined
// checking subdir to true means it's not undefined and
// the current path is a directory
if(subdir) {
// excluding node_modules folder
if (!subdir.match('node_modules')) {
// only process markdown files
if(filename.match('.md')) {
filenameOutExt = filename.split('.')[0];
// now for each markdown files, run md2pdf task
// and ouput filenameOutExt.pdf in same folder
// as the input files
}
}
}
}
});
};
I am using this plugin: https://www.npmjs.com/package/grunt-md2pdf
So my questions is how should I configure the md2pdf task to pass it the markdown files and generate matching filename pdf output in same directory.
Output should be:
root/
|_subfolder1
| |_filename1.md
|_filename1.pdf
|_subfolder2
|_filename2.md
|_filename2.pdf
...
|_node_modules
|_subfolderN
|filenameN.md
|_filenameN.pdf
Thanks a lot
According to this line, this task uses the grunt.files utilitary function. This makes things easier for us!
First, it's not usual in grunt to create a different task to find the files you need in any other task.
That is, each task should receive the files it needs to operate on. For example...
coffee:
main:
files: [
expand: true
cwd: 'assets/script'
src: ['**/*.coffee']
dest: "assets/script"
ext: '.js'
]
(Note that this config is in a Gruntfile.coffee file, hence the CoffeeScript syntax)
This type of file configuration using glob expansion is one of the most common. You can find details in the documentation.
It's pretty obvious:
In every directory (**), take everything (/*) from assets/script/ that ends with .coffee. Put it into assets/script. Rename extensions to .js.
So, your task can probably be configured like that:
md2pdf: {
main: {
files: [ {
expand: true,
src: ['**/*.md', '!node_modules/**/*'],
dest: "pdf/"
} ]
}
}
Ok figured it out !
module.exports = function(grunt) {
// 2 - Plugins
grunt.loadNpmTasks('grunt-md2pdf');
grunt.registerTask('default', 'Dynamically generate PDF from MD', function() {
grunt.file.expand("./**/*.md").forEach( function(file) {
if(!file.match('./node_modules')) {
var md2pdf = grunt.config.get('md2pdf') || {};
md2pdf[file] = {
src: file,
dest: file + '.pdf'
};
grunt.config.set('md2pdf', md2pdf);
}
});
grunt.task.run('md2pdf');
});
};

How to get grunt.file.readJSON() to wait until file is generated by another task

I'm working on setting up series of grunt tasks that work with RequireJS r.js compiler:
1) generates a .json file listing of all files in a directory
2) strips the ".js" from the filename (requirejs requires this)
3) use grunt.file.readJSON() to parse that file and use as a configuration option in my requirejs compilation task.
Here is the relevant code from my gruntfile.js:
module.exports = function (grunt) {
grunt.initConfig({
// create automatic list of all js code modules for requirejs to build
fileslist: {
modules: {
dest: 'content/js/auto-modules.json',
includes: ['**/*.js', '!app.js', '!libs/*'],
base: 'content/js',
itemTemplate: '\t{' +
'\n\t\t"name": "<%= File %>",' +
'\n\t\t"exclude": ["main"]' +
'\n\t}',
itemSeparator: ',\n',
listTemplate: '[' +
'\n\t<%= items %>\n' +
'\n]'
}
},
// remove .js from filenames in module list
replace: {
nodotjs: {
src: ['content/js/auto-modules.json'],
overwrite: true,
replacements: [
{ from: ".js", to: "" }
]
}
},
// do the requirejs bundling & minification
requirejs: {
compile: {
options: {
appDir: 'content/js',
baseUrl: '.',
mainConfigFile: 'content/js/app.js',
dir: 'content/js-build',
modules: grunt.file.readJSON('content/js/auto-modules.json'),
paths: {
jquery: "empty:",
modernizr: "empty:"
},
generateSourceMaps: true,
optimize: "uglify2",
preserveLicenseComments: false,
//findNestedDependencies: true,
wrapShim: true
}
}
}
});
grunt.loadNpmTasks('grunt-fileslist');
grunt.loadNpmTasks('grunt-text-replace');
grunt.loadNpmTasks('grunt-contrib-requirejs');
grunt.registerTask('default', ['fileslist','replace', 'requirejs']);
I'm running into a problem where, if the "content/js/auto-modules.json" file doesn't already exist on load of my config file, the file.readJSON() is executed immediately, before the file exists and the entire task fails and throws "Error: Unable to read file " If the file already exists, everything works beautifully.
How can I set this up so that the task configuration waits for that file to be created in the first task, and modified in the second task before it tries to load & parse the JSON in it for the third task? Or is there another way (perhaps using a different plugin) to generate a json object in one task, and then pass that object to another task?
Old post but I had a similar experience.
I was trying to load a some json config like:
conf: grunt.file.readJSON('conf.json'),
but if this file did not exist then it would fall in a heap and not do anything.
So I did the following to load it and populate defaults if it didnt exist:
grunt.registerTask('checkConf', 'ensure conf.json is present', function(){
var conf = {};
try{
conf = grunt.file.readJSON('./conf.json');
} catch (e){
conf.foo = "";
conf.bar = "";
grunt.file.write("./conf.json", JSON.stringify(conf) );
}
grunt.config.set('conf', conf);
});
You still may have some timing issues but this approach may help someone with a readJSON error.

Resources