Using grunt to compile jade templates to javascript functions in sails.js - javascript

I am building an application in Sails.js and i want to compile some jade templates to javascript functions for use from the client. I have found a few articles explaining how to do this, but when i try to implement their steps they don't seem to work for me
I am trying to compile files located in App/Views/Client and put the compiled javascript files into App/.tmp/public/templates
My grunt task is in App/tasks/config and is based on the coffeescript grunt task that comes with sails.js. My grunt task looks like this
module.exports = function(grunt) {
grunt.config.set('jade', {
dev: {
templates:{
options: {
pretty: true,
client: true,
namespace: 'Templates'
},
files: [{
expand: true,
cwd: 'views/client/',
src: ['**/*.jade'],
dest: '.tmp/public/templates/',
ext: '.js'
}]
}
}
});
grunt.loadNpmTasks('grunt-contrib-jade');
};
I have added it to the compileAssets.js grunt task that comes with sails.js, and i can see it being run when i run the sails lift command.
When it runs it reports 0 files created, which suggests to me that there is a problem with my paths. However i have defined them based on the same working folder as the other grunt tasks in sails.js. I have tried a number of variations on the paths, including putting ./ at the start of them, but none seem to work.
Can anyone help explain what is wrong with my grunt file? Or how to make it output the folder it is looking at to the console so i can figure out whether my path is correct or not?

Your configuration object is one level too deep.
dev is already the task's target and Grunt will start looking for the files property in there. templates is quietly ignored.
So the configuration object should look like this:
dev: {
options: {
pretty: true,
client: true,
namespace: 'Templates'
},
files: [{
expand: true,
cwd: 'views/client/',
src: ['**/*.jade'],
dest: '.tmp/public/templates/',
ext: '.js'
}]
}

Related

Can I change .less to a.min.css with a source map and still be able to view the .less files in Dev Tools?

I am using this gruntfile to change my .less file to .css files.
module.exports = function (grunt) {
grunt.initConfig({
less: {
development: {
files: [{
expand: true,
cwd: 'assets/less',
src: ['*.less'],
dest: 'wwwroot/content/css/',
ext: '.css'
}]
},
production: {
files: {
"wwwroot/content/css/script.css": ["assets/less/*.less"]
},
options: {
cleancss: true
}
}
}
});
grunt.loadNpmTasks("grunt-contrib-less");
};
For my development build if I have ten .less files then this will create ten .css files and then I will be able to view these in the Chrome Development Tools and easily debug.
The reason I am doing this is so that I will be able to debug and look at those ten .css
files in the Chrome development tools.
Is my reasoning correct? I heard about source maps but how could I use these in my
development build and if I used these then would I still be able to see the source
.css file names or even better the ten .less files?
TL;DR yes to all of your questions ;)
To use source maps with your Gruntfile, simply add the option like this
less: {
development: {
options: {
sourceMap: true
},
files: [{
expand: true,
cwd: 'assets/less',
src: ['*.less'],
dest: 'wwwroot/content/css/',
ext: '.css'
}]
},
See grunt-contrib-less page for more info on the option available. Maybe, depending on your working environment, you should add the sourceMapRootpath option to specify where are your files.
In the end, your .css file should have a long commented line at the end. That's the source map.
There are two bit-old-but-great introduction to source maps: Debug LESS With Chrome Developer Tools and Introduction to JavaScript Source Maps

Requirejs and Grunt: mainConfigFile vs grunt task options

I find there to be a lot of confusion/lack a specific way of handling building with require in grunt. I'm just confused what configuration should go directly in Grunt task options:
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
requirejs: {
compile: {
options: {
baseUrl: './js',
mainConfigFile: 'config.js',
optimize: 'none',
include: ['./main'],
out: 'optimized.js'
}
}
}
});
And then in config file:
({
appDir: './',
baseUrl: './js',
dir: './dist',
optimize: 'none',
optimizeCss: 'standard',
removeCombined: true,
paths: {
jquery: './js/jQuery/jquery',
}
})
Obviosuly there seems to be some redundancy but that is mostly what I've found. Can someone explain why or if I'm mistaken? Can I place all config in one or the other? I'm only planning on working off of the optimized single file with almond.
Also do I only state the initial single point of entry to build the dependency chain from ie my main.js file and any require calls in there or can I state a wildcard list of files that calls modules:
include: ['./variousFiles/*.js']
Any and all clarifications of how to best utilize require with Grunt will be appreciated. Thank you!
When you use RequireJS' r.js optimizer there are two configurations to speak of:
The runtime configuration which is what is described in the RequireJS documentation. This is where you tell RequireJS where to find modules at runtime.
The build configuration, which is what is described with r.js' documentation. This tells r.js how to build bundles from your modules.
The mainConfigFile option is for the build configuration, it tells r.js where to find the runtime configuration you plan to use when you run the bundles it will create. This is to prevent having to duplicate shim and paths options from the runtime configuration to the build configuration.
In your description, it looks like you are making mainConfigFile point to a build configuration. This is useless.

Grunt target subdirectories only

Is it possible with Grunt to target only subdirectories? I have a javascript folder in my project and it contains a few .js files and within this folder I also have a few subdirectories.
MainDirectory
/javascript
global.js
modal.js
/subdirectory1
somescripts.js
/subdirectory2
otherscrips.js
So in my grunt config I am using concat to grab only the files in the javascript folder and ignore the subdirectories. So what I need is to copy the files in the subdirectory and ignore the files outside the subdirectory, in this case global.js and modal.js. Here is my copy code (Gruntfile.js):
copy: {
subdirs: {
expand: true,
dot: true,
cwd: 'javascript',
dest: 'app/assets/javascript',
src: '**/*.js'// I know this grabs files and subdirectories
}
}
I'm sure there is a way to do this but after Googling and reading Grunt docs I still cant figure out a proper solution. Any help would be appreciated. Thanks.
The basic approach would be to specify all files in the current and any subdirectories, then explicitly ignore all files in the current directory.
reference grunt globbing patterns
Change your src property to:
src: ['**/*.js', '!*.js'],

How to package bower_components with only required resources?

I'm using Bower and Grunt on my application. Thus, I have a bower_components directory with several sub-directories, containing all my dependencies.
Currently, on my Gruntfile.js, I have something like that:
copy: {
bower: {
files: [
{
expand: true,
cwd: 'app/',
dest: 'dist/',
src: [ 'bower_components/**/*' ]
}
]
},
...
which means that I copy everything under bower_components to finally package my application. The problem is that I don't need everything under this directory, for example there are non minified JS, resources, documentation, etc.
Is there a way to make an intelligent filter that only takes the required elements in the bower_components directory (i.e. without selecting the files myself)?
Am I missing some good practices regarding the packaging of an application with bower and grunt?
Thanks
ps: as it is for an intranet application, I prefer not to use CDN.

Gruntfile issue with grunt-contrib-requirejs

I'm configuring my Gruntfile and I'm stuck on something I feel should be possible but I'm not able to find the right configuration for it. I'm trying to copy my bower components to my dist on build with the grunt-contrib-requirejs module. The part I'm stuck on is keeping the folder structure in tact when copying to dist.
My app's basic structure, and dist/ should build the same way
Gruntfile.js
app/
- assets/
- bower_components/
- js/
- img/
- etc/
- index.html
Currently, I define each file in the copy module and it copy's them all over
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: 'app',
dest: 'dist',
src: [
'*.{ico,png}',
'.htaccess',
'partials/**/*',
// Bower Components
'assets/bower_components/requirejs/require.js',
'assets/bower_components/fastclick/lib/fastclick.js',
'assets/bower_components/jquery/dist/jquery.min.js',
'assets/bower_components/modernizr/modernizr.js'
]
}]
}
},
But I want to eliminate this and use the paths I've already defined in main.js to copy these files over. Less hardcoded stuff, more automation.
My require task
requirejs: {
dist: {
options: {
mainConfigFile: app + '/assets/js/main.js',
dir: dist + '/assets/js',
optimize: 'uglify',
paths: {
modernizr: 'empty:',
jquery: 'empty:',
fastclick: 'empty:'
}
}
}
},
This current configuration combined with copy moves them all over properly. If I could eliminate the paths property all together and use directory properties only that would be great. If I have to copy my paths from my main.js into here thats ok... if it's the only way to do it.
Let me know if you need any more info!
The JS files in your bower directory should be included in the optimized output of requirejs, as long as they are configured and referenced in your require js app. If they're not referenced as dependencies, I don't think they get included.
The ico, png, htaccess and other files may need to be copied over manually.
Depending on your partials, the text plugin and hbs plugin could compile those into the optimized file I think.
I think defining empty: in paths are for using network resources (e.g. when using CDNs instead of using local bower libraries), so the paths config is probably unnecessary

Categories