grunt-angular-templates cache all templates - angularjs

So I ran into an issue when trying to use toastr as a global error notification system in my angular application.
This was logged as an issue with angular-toastr and the proposed solution was to push all templates into the templatecache. Apparently this is a good thing to do and after reading up on why, I have to agree.
My problem is that I am really new to grunt (only just installed it today) and although I have now managed to successfully set up my gruntfile.js and run some tasks (minification, concatination, etc) using grunt-angular-templates is a mystery to me.
I have set up my gruntfile like this:
ngtemplates: {
options: {
module: 'project',
},
dist: {
src: [
'wwwroot/lib/angular-toastr/**.html'
],
dest: 'wwwroot/js/templates.js'
}
}
But my templates file that is generated is empty.
I assume this is because scripts are creating in the JS files.
Does anyone know how I can get access to the them so I can add them to the cache?

I would guess that your source files are not being 'seen'. This worked for me with the following configuration and I am using a similar structure where the output is in a wwwroot/lib folder. I am also using the cwd (source directory option). Make sure that the templates are copied to the wwwroot folder before the grunt task is executed. I have other grunt tasks that 'clean' the wwwroot/lib folder so I store my source html(s) in another folder. That may also help if you are not doing that.
If all else fails, run in verbose -V (like alex said). The task source file is in the following location. You can also add additional debug in this file to further trouble shoot.
node_modules\grunt-angular-templates\tasks\angular-templates.js
this.files.forEach(function(file) {
if (!file.src.length) {
grunt.log.warn('No templates found');
}
This is the setup we use.
Project structure
Source
project/assets/templates/admin/partials/(html files here)
Output
project/wwwroot/lib/templates(html files here)
Grunt Task
ngtemplates: {
app: {
cwd: 'assets/templates',
src: '**/partials/*.html',
dest: 'assets/templates/partials.js',
options: {
module: 'cms.admin'
}
}
},
The Output Generates
angular.module('cms.admin').run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('Admin/partials/navmenu.template.html',
"<nav class=\"navbar navbar-default navbar-fixed-top\">\r" +
"</nav>"
);
}]);

Your problem probably lies with your src: wwwroot/lib/angular-toastr/**.html
Maybe try using this grunt plugin, it's easy to use and does the same thing.
https://github.com/karlgoldstein/grunt-html2js
grunt.initConfig({
html2js: {
options: {
// custom options, see below
},
main: {
src: ['src/**/*.tpl.html'],
dest: 'tmp/templates.js'
},
},
})

Try running the task individually like this: grunt ngtemplates -v. The -v argument stands for verbose mode. You should get the filenames that have been read. If there are no files being read, you might have a file path problem.

For simplicity or to avoid the rabbit whole, you can also manually push the template to the cache so you can test the toastr issue.
Go to http://www.accessify.com/tools-and-wizards/developer-tools/html-javascript-convertor/
Convert the html to javascript
Use the output in the following code to cache manually.
var strVar = "";
strVar += "";
strVar += "<div class=\" container-fluid wrapper-md\">";
strVar += " <h3>Title<\/h3>";
strVar += " <div id=\"markupArea\"> <\/div>";
strVar += " ";
strVar += "<\/div>";
strVar += "";
angular.module('cms.admin').run(['$templateCache', function($templateCache) {
'use strict';
$templateCache.put('<CacheKEy>',strVar );
}]);

Related

setting up ng-htmljs-preprocessor karma preprocessor

I am setting up my Karma configuration file, but I do not fully understand some of options that exist as I am not having success testing templates that have ran through the ngHtml2JsPreprocessor and have been
$templateCached
Inside of the ngHtml2JsPreprocessor I can add a few key value properties involving paths.
ngHtml2JsPreprocessor: {
stripPrefix: ".*/Went all the way back to the root of my application/",
// moduleName: 'templatesCached'//
},
I commented out the templates for now to make sure that I am getting access to each file as module. I am loading the modules with no error. I can find the templateCached version in my dev tools.
beforeEach(module('template'));
My Templates folder sits outside the basepath I created.
basePath: 'Scripts/',
I have it referenced inside the preprocessors object
preprocessors: {
'../Templates/**/*.html' : ['ng-html2js']
},
Again all of my templates are now js files and cached.
I inside of my package.json I saved the files as
save-dev
"karma-chrome-launcher": "^0.2.2",
"karma-jasmine": "^0.2.2",
"karma-ng-html2js-preprocessor": "^0.2.1",
I referenced my installs in the plugins.
plugins: [
'karma-chrome-launcher',
'karma-jasmine',
'karma-sinon',
'karma-ng-html2js-preprocessor'
],
I have all of my files loaded
files: [
//jquery libaries
// angular libraries
// Scripts files
// source app.js
// tests folder and files
]
My tests are running off of Karma start
However, my directive is just an empty string
element.html()
returns ""
I have bard inject set up
bard.inject(
"$compile",
"$controller",
"$rootScope",
'$templateCache',
"haConfig",
"$q"
);
Here is the inside of my beforeEach
bard.mockService(haConfig, {
getTemplateUrl: '/tst!'
});
//bard.mockService(haConfig, {});
console.log('ha config2', haConfig.getTemplateUrl());
var html = angular.element("<div explore-hero></div>");
console.log('htl',haConfig.getTemplateUrl());
scope = $rootScope.$new();
//templateCache
element = $compile(html)(scope);
//console.log(haConfig.getTemplateUrl(html));
scope.$digest(element);
console.log('missing text',haConfig.getTemplateUrl(html));
controller = element.scope();
console.log("element", element);
I have no idea why I am getting an empty string back. I am creating the html file but, nothing is inside of it.
All I can wonder if I should have the the templatesCached files showing up in a folder on my dev tools? Also whether or not the files should be referenced inside of the files array inside karma.conf.js
Right now I have the html files referenced? I have tried the js files but that did not seem to do anything
The problem was actually quite simple fix. I was tempted to delete it but, in case someone has a similar issue I want this to be available.
Inside the karma.conf.js I have a
stripPrefix: 'rootDirectory' // was already in place
stripSuffix: '.js.html' // I had to make a strip on the templatesCached
prependSuffix: '.html' // this is what I was searching for
When the preprocessor ran it templateCached all of my files. However, they did not end the way that I was expecting them and I could not read them. I had the module and other parts set up correctly.

Render all Jade files in large Express application using folder structure?

How can I configure Express to render all Jade files regardless of path? The application I'm on is large with a very complex structure. I'm successfully serving static files however I need many of them to be rendered. We are using Jade for all files needing markup.
I'm worried that the pattern below will force me to create a route alias for every folder that has a Jade file... which would be bad. I would like to tell Express to simply render everything with a .jade extension... OR... allow me to create a route PREFIX for the root that would cause a Render operation instead of Static.
client
app
services
modules
moduleA
itemA
itemAList.jade
itemAList.js
itemADetails.jade
itemADetails.js
itemB
itemBList.jade
itemBList.js
itemBDetails.jade
itemBDetails.js
moduleB
itemC
itemCList.jade
itemCList.js
itemCDetails.jade
itemCDetails.js
itemD
itemDList.jade
itemDList.js
itemDDetails.jade
itemDDetails.js
assets
js
css
server
config
views
Routes.Config.js
module.exports = function(app){
app.get('/*', function(req, res){
res.render('../../client/' + req.params[0]);
});
app.get('/', function(req, res){
res.render('../../client/index', {});
})
}
Express.Config.js
[snip]
app.use(express.static(path.join(constants.rootPath, '/client')));
I would use a Grunt file watcher to kick off a compile any time your .jade files are created or saved. By using the Gruntfile.js below, you can issue the command grunt watch and have this automagically occur in the background:
module.exports = function(grunt){
grunt.initConfig({
jade: {
compile: {
options: {
client: false,
pretty: true
},
files: [{
cwd: "client/app/templates",
src: "**/*.jade",
dest: "client/app/modules",
ext: ".html",
expand: true
}]
}
},
watch: {
html: {
files: 'client/app/templates/**/*.jade',
tasks: ['jade'],
options: {
atBegin: true,
interrupt: true
}
}
}
});
grunt.loadNpmTasks("grunt-contrib-jade");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.registerTask('default', ['jade']);
}
Now, this assumes that you will create a "templates" folder parallel to the "modules" folder and put all of your .jade files there in the structure you want. You may then add your controllers and other .js files to the modules folder structure as normal.
I'm not sure how Grunt will behave with the source and destination both pointing to the same folder. However, if you REALLY want to keep your .jade and .html files in the same folder, or if you don't want to create a "templates" structure, you SHOULD be able to simply change the cwd variable to point to the "modules" folder:
files: [{
cwd: "client/app/modules", // templates folder removed
src: "**/*.jade",
dest: "client/app/modules",
ext: ".html",
expand: true
}]
NOTE:
Sounds like you've misunderstood some of the fundamentals. From what I'm learning, within a typical MEAN application, there is generally a folder structure that is meant to be purely static. In your example, this would be your "client" folder. By specifying special routes, you individually decide how every other case is handled. The example above is meant to accomplish what I think you're asking while still maintaining the purpose of the "static" area.
UPDATE: Don't use same folder!
I went back and tried using the same folder for the source and destination. This caused Grunt to hang without any way to break out of it. This hang does NOT occur when they are different. So, use the file as-is with the "templates" folder.

Any easy way to add build version info to coverage test results

I am using karma-coverage to measure the unit test coverage in my project and everything works in that regard just fine. I use HTML reporter into default directory.
However, I would need to "stamp" the coverage report with the build version information that I do have available using grunt-git-describe, which is currently used in the AngularJS app footer that loads the resulting version.json file. I didn't find any direct way to use this version.json file in the html reports from karma-coverage. So if anybody has a good idea how to do it, I would appreciate a lot.
Thanks in advance!
I did manage to implement this with a sort-of work around. I use text-replace module in grunt after running karma to do this. If some one has a better solution, please share as this is a bit of a hack, but it works ok. As karma-coverage's html reports in my environment goes to the projects' root /coverage/ folder, I made a recursive text replace into every .html file there looking for the default footer and adding my version info there...
First, installed grunt-text-replace
$ npm install grunt-text-replace --save-dev
Then I made a following replace function in gruntfile.js:
grunt.initConfig({
replace: {
coverage: {
src: ['coverage/**/*.html'],
overwrite: true,
replacements: [
{
from: '<div class="meta">Generated by',
to: function(){return grunt.config.get('task.replace.versionString');}
}
]
}
},
// and your other stuff in initConfig()
And I added a new task into grunt for this:
grunt.registerTask('coverage', 'Adds version info to coverage results', function(){
grunt.task.requires('version'); // The 'version' task creates a 'version.json' file
var vers = grunt.file.readJSON('version.json');
// Set the desired string to be used in text-replace -function
grunt.config.set('task.replace.versionString', '<div class="meta">Version ' + vers.version + ', Tag "' + vers.revision[0] + '"<br>Generated by');
grunt.task.run(['replace']);
});
A bit ugly but works like a charm ;-)

Require.js build not concatenation scripts loaded with Jam

Following one of the chapters of "Developing Backbone.js Apllication" by Addy Osmani (O'Reilly) about Grunt-BBB (Backbone Boilerplate Buddy), I just couldn't manage to create a build profile.
Here is the filesystem tree used for this :
/builds
/closure
/rhino
/config
/build.js
build.sh
/development
/* Grunt-BBB files after init */
/app
/styles
index.css
app.js
config.js
main.js
router.js
/test
/* Not important files used for testing */
/vendor
/h5bp
/css
main.css
normalize.css
/jam
/backbone
backbone.js
package.json
/bakbone.layoutmanager
bakbone.layoutmanager.js
package.json
/jquery
jquery.js
package.json
/lodash
lodash.js
lodash.min.js
lodash.underscore.min.js
package.json
require.config.js
require.js
/js
/libs
almond.js
require.js
/distribution
/* Empty dist directory where the optimized / minified / concatenated files should go */
Here are the steps I followed in the /development directory :
1) Install Grunt-BBB (npm install -g bbb)
2) Download r.js, a part of the Require.js project (git clone https://github.com/backbone-boilerplate/grunt-bbb)
3) Initialize the files of the boilerplate (bbb init)
Here is the build.js file I used to configure the r.js AMD loader for the Google Closure compiler :
({
appDir: '../../development',
baseUrl: 'app',
dir: '../../distribution',
optimize: 'closure', // 'uglify2'
paths: {
backbone: '../vendor/jam/backbone/backbone',
'backbone.layoutmanager': '../vendor/jam/backbone.layoutmanager/backbone.layoutmanager',
jquery: '../vendor/jam/jquery/jquery',
lodash: '../vendor/jam/lodash/backbone.min'
},
modules: [
{
name: 'main'
}
],
onBuildRead: function(moduleNames, path, contents) {
return contents;
//return contents.replace(/console\.log\(([^\)]+)\);/g, '')
// .replace(/debugger;/, '');
}
})
and this is the build.sh file I use :
#!/usr/bin/env bash
# r.js directory
RJSDIR="r.js"
RJS="$RJSDIR/dist/r.js"
# Rhino directory
RHINODIR="rhino"
RHINO="$RHINODIR/js.jar"
# Google Closure Compiler directory
CLOSUREDIR="closure"
CLOSURE="$CLOSUREDIR/compiler.jar"
# Build config directory
CONFIGDIR="config"
CONFIG="$CONFIGDIR/build.js"
# Launch compillation
java -Xms256m -Xmx256m -classpath "$RHINO":"$CLOSURE" org.mozilla.javascript.tools.shell.Main "$RJS" -o "$CONFIG" $#
My goal is to optimize, minify, concatenate all the JavaScrit file including the libraries and templates (which I don't have yet, I am only using the boilerplate files) but also CSS files.
The result I get by running ./build.sh is that every files are correctly minimised (besides CSS rule inlining, but that is besides the point) and concatenated but resources that are loaded and managed by the Jam (package manager that combines NPM and Require.js) aren't concatenated.
The reason for that since they are already loaded / managed by Jam, they are not redeclared in the JavaScript files AMD style.
In conclusion, my questions are the following :
How can I rewrite my build.js configuration file so that resources that are loaded by Jam also get included and concatenated in the release / dist file ?
How can I make it so that the concatenated resources aren't copied in the realse / dist directory ? Is it possible to configure this in the build.js file or should this go in my build.sh file ?
Edit : New build.js file :
({
appDir: '../../development',
baseUrl: 'app',
dir: '../../distribution',
optimize: 'closure', // 'uglify2'
paths: {
requirejs : '../vendor/jam/require',
backbone: '../vendor/jam/backbone/backbone',
'backbone.layoutmanager': '../vendor/jam/backbone.layoutmanager/backbone.layoutmanager',
jquery: '../vendor/jam/jquery/jquery',
lodash: '../vendor/jam/lodash/backbone.min'
},
name: 'main',
include: ['requirejs'],
onBuildRead: function(moduleNames, path, contents) {
return contents;
//return contents.replace(/console\.log\(([^\)]+)\);/g, '')
// .replace(/debugger;/, '');
}
})
And here is the error :
file:///vendor/js/libs/require.jsFailed to load resource: The requested URL was not found on this server.
file:///app/styles/index.cssFailed to load resource: The requested URL was not found on this server.
require.js is never included by r.js unless you instruct it to do so. See this link:
http://requirejs.org/docs/optimization.html#onejs
The link refers to command-line options, but the build file options are broadly the same:
you need to define a dummy module for require.js in your paths:
paths: {
requireLib : '/path/to/require.js'
backbone: '../vendor/jam/backbone/backbone',
'backbone.layoutmanager': '../vendor/jam/backbone.layoutmanager/backbone.layoutmanager',
jquery: '../vendor/jam/jquery/jquery',
lodash: '../vendor/jam/lodash/backbone.min'
},
and include it:
name "main",
include: ["requireLib"],
You can ensure that allnested dependencies are resolved by setting:
findNestedDependencies: true,
You can configure an output path using 'out' in your build file
out: "path/to/my/builtfile-1.0.0.js",
Sorry I don't know enough about jam to say whether jam would override this setting
_Pez

Uglifying a RequireJS/Backbone project into one single .js file?

I worked along the following tutorial to try to optimize my project into one single .js file, but unfortunately I can't seem to get the expected results. I get r.js to create an optimized folder for me, but instead of a single file, I get uglified copies of each individual .js file in their respective folders. Seems like that last concatenation step is somehow missing.
I'm trying to leverage an existing config file instead of using paths, I don't know if that specific step is breaking it.
My build/app.build.js is:
({
appDir: '../',
baseUrl: 'js',
mainConfigFile: '../js/config.js',
dir: '../../my-app-build',
modules: [{
name: 'main'
}]
})
My main.js file has the config file as its dependency:
require(["config"], function() {
require(['underscore', [...]
[...]
}
}
And the config file is where all of my project dependencies are declared:
require.config({
baseUrl: "js",
paths: {[...]},
shim: {...]},
});
Does anyone have insight into why I might not be getting that single file output that I'm looking for? I tried the other approach in this post, but that only ever produces main.js for me with the config file prepended to it.
Thanks!
The issue was caused by the following option missing from the r.js build configuration file:
findNestedDependencies: true
Without it, r.js would not go past the first require in main.js, thus loading only config.js and none of the next level of dependencies. Just for reference (note that it saves the product of optimization in the same source folder, which is not ideal) looks like this:
({
baseUrl: '.',
mainConfigFile: 'config.js',
name: 'main',
out: 'main-build.js',
findNestedDependencies: true,
})
I had the same problem and got the solution from the Github Issue list. May be this configuration parameters will help you too
https://github.com/jrburke/r.js/issues/379
If you only want one JS file built, instead of using dir: use out: for a single JS file build.
Specify output filepath:
({
// ...
out: '../main.min.js'
})

Resources