How to create api documents with grunt-ngdocs - node.js

I'm trying to create API documents through grunt-ngdocs.
The partials are created but the index.html doesn't have the correct links to it.
I have in my gruntfile.js:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
karma: {
unit: {
configFile: 'karma.conf.js'
}
},
uglify: {
options: {
// the banner is inserted at the top of the output
banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'
},
dist: {
files: {
'web/js/app.min.js': ['web/js/app.js']
}
}
},
ngdocs: {
options: {
dest: 'docs',
scripts: ['web/js/app.js'],
title: 'My Documentation'
},
api: {
src: ['web/**/*.js'],
title: 'API Documentation'
}
},
clean:['docs','testResult']
});
grunt.loadNpmTasks('grunt-karma');
grunt.loadNpmTasks('grunt-ngdocs');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.registerTask('default', ['clean','uglify', 'ngdocs', 'karma']);
};
and my js file like this
/**
* #ngdoc overview
* #ngdoc directive
* #name myApp.maincontroller:controller
* #description
*
* # myApp
* The factoryName is my favorite service in the world.
*
*/
var myApp = angular.module('myApp',[]);
myApp.controller("MainController", function($scope) {
$scope.model = {
myValue: "Run you fools!"
};
});
/**
* #ngdoc function
* #name mySuperFunction
* #returns {int} The int representing a Firebase resource
*/
function mySuperFunction() {
var i = 5;
var j = 5;
i += j;
return i;
}
but when I run
grunt
in the command line, the result is this
C:\Users\Lino Simões\Documents\bitbucket\test>grunt -d --force
Running "clean:0" (clean) task
[D] Task source: C:\Users\Lino Simões\Documents\bitbucket\test\node_modules\grun
t-contrib-clean\tasks\clean.js
Cleaning docs...OK
Running "clean:1" (clean) task
[D] Task source: C:\Users\Lino Simões\Documents\bitbucket\test\node_modules\grun
t-contrib-clean\tasks\clean.js
Cleaning testResult...OK
Running "uglify:dist" (uglify) task
[D] Task source: C:\Users\Lino Simões\Documents\bitbucket\test\node_modules\grun
t-contrib-uglify\tasks\uglify.js
File web/js/app.min.js created: 796 B → 210 B
Running "ngdocs:api" (ngdocs) task
[D] Task source: C:\Users\Lino Simões\Documents\bitbucket\test\node_modules\grun
t-ngdocs\tasks\grunt-ngdocs.js
Generating Documentation...
DONE. Generated 2 pages in 256ms.
Running "karma:unit" (karma) task
[D] Task source: C:\Users\Lino Simões\Documents\bitbucket\test\node_modules\grun
t-karma\tasks\grunt-karma.js
INFO [karma]: Karma v0.12.17 server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9.7 (Windows 7)]: Connected on socket dFX-dKGVINA6PBjB5Gu9 wit
h id 91061839
PhantomJS 1.9.7 (Windows 7): Executed 8 of 8 SUCCESS (0.008 secs / 0.004 secs)
Done, without errors.
so, this generates 2 files, but when I go to the index.html under docs I have this:
but in my docs/partials/api/ I have the partials created by the ngdocs.
my project tree is like this:

Did you have angular.js and angular-animate.js in your web/js/app.js? Check it. And add to "options" html5Mode: false

for ng1.6 works for me:
ngdocs: {
all: ['app/**/*.js']
}
you will see the old version of angular 1.2.* in
cat docs/js/angular.min.js | grep v1
AngularJS v1.2.16
but it does not affect your source files.
also, dont forget run server
for generated folder docs:
e.g using python
pushd ./dist; python -m SimpleHTTPServer 9000; popd #v 2.*
pushd ./dist; python -m http.server 9000; popd #v 3.*
unfortunately, adding angular.js and angular-animate.js to scripts option doesn't work for me

Related

grunt cssmin different target files for style.min.css and above-the-fold.min.css

In an older version of cssmin it was possible to create to different target files. I minified a style.min.css and an above-the-fold.min.css. Now I updated to a newer version of nodejs, npm, grunt and cssmin and it is not possible to minify to different outputfiles anymore. Since the update grunt only minifies the second task and skip the first task. Do you have a hint for me to minify both tasks?
cssmin: {
options: {
mergeIntoShorthands: false,
roundingPrecision: -1
},
target: {
files: {
'data/style.min.css': ['a.css', 'b.css', 'c.css', 'd.css', 'e.css', 'f.css', 'g.css']
}
}
},
penthouse: {
extract : {
outfile : 'data/above-the-fold.temp.css',
css : './data/style.min.css',
url : 'http://localhost/',
width : 1280,
height : 500
},
},
cssmin: {
options: {
mergeIntoShorthands: false,
roundingPrecision: -1
},
target: {
files: {
'data/above-the-fold.min.css': ['data/above-the-fold.temp.css']
}
}
}
grunt-contrib-cssmin will allow multiple Targets to be defined in a single Task. For example:
Gruntfile.js
module.exports = function (grunt) {
grunt.initConfig({
// ...
cssmin: { // <-- cssmin Task
options: {
mergeIntoShorthands: false,
roundingPrecision: -1
},
targetA: { // <-- First target
files: {
'data/style.min.css': ['a.css', 'b.css', 'c.css', 'd.css', 'e.css', 'f.css', 'g.css']
}
},
targetB: { // <-- Second target
files: {
'data/above-the-fold.min.css': ['data/above-the-fold.temp.css']
}
}
}
// ...
});
// ...
};
Each Target name should be unique within the cssmin Task. For example: targetA and targetB
As you've included the penthouse Task in your post, I guess that you need to run that after generating the style.min.css file, and before generating the above-the-fold.min.css. To do this you can register your Tasks as follows:
grunt.registerTask('default', ['cssmin:targetA', 'penthouse', 'cssmin:targetB',]);
Note: The use of the semi-colon notation, namely cssmin:targetA and cssmin:targetB. This simply ensures that targetA of the cssmin Task is run before the penthouse Task. Subsequently, (when the penthouse Task completes), targetB of the cssmin Task is run.

Grunt executes multiple times, creates infinite loop

We are working as on a project with a couple of other devs on GIT, using the same repo, it works fine with everyone else. However, when I run grunt it executes multiple times, seems to be running into an infinite loop, without me actually making any changes. It's only happening to me on a different computer
I am considering that maybe I need something else installed.
I deleted node, npm and reinstalled with homebrew which I'm also using for updates. Node v5.3.0, npm 3.3.12
Running Mavericks.
What am I missing?
Here's the loop:
Reloading watch config...
Running "watch" task
Waiting...
>> File "Gruntfile.js" changed.
>> File "js/all-js/bootstrap-hover-dropdown.min.js" changed.
>> File "js/all-js/site.js" changed.
Running "uglify:build" (uglify) task
>> 1 file created.
Done, without errors.
Completed in 3.740s at Tue Jan 05 2016 13:11:07 GMT-0500 (ECT) - Waiting...
[BS] File changed: js/site.min.js
Reloading watch config...
Running "watch" task
Waiting...
>> File "js/all-js/bootstrap.js" changed.
>> File "Gruntfile.js" changed.
Running "uglify:build" (uglify) task
>> 1 file created.
Done, without errors.
Completed in 1.869s at Tue Jan 05 2016 13:11:10 GMT-0500 (ECT) - Waiting...
[BS] File changed: js/site.min.js
>> File "js/all-js/bootstrap-hover-dropdown.min.js" changed.
Running "uglify:build" (uglify) task
>> 1 file created.
Done, without errors.
Completed in 1.885s at Tue Jan 05 2016 13:12:04 GMT-0500 (ECT) - Waiting...
[BS] File changed: js/site.min.js
Reloading watch config...
Running "watch" task
Waiting...
>> File "Gruntfile.js" changed.
Here's my Gruntfile.js:
module.exports = function(grunt) {
//Get all tasks from the package.json file
require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
/* Concurrent Task */
concurrent: {
watch: {
tasks: ['watch', 'compass:dist', 'browserSync'],
options: {
logConcurrentOutput: true
}
}
},
/* SASS task */
compass: {
dist: {
options: {
sassDir: ['SASS/'],
cssDir: ['css/'],
environment: 'development', /* development | production */
importPath: ['SASS/'],
outputStyle: 'compressed', /* expanded for development | compressed for production */
watch: true,
sourcemap: true
},
},
live: {
options: {
sassDir: ['SASS/'],
cssDir: ['css/'],
environment: 'production', /* development | production */
importPath: ['SASS/'],
outputStyle: 'compressed', /* expanded for development | compressed for production */
watch: false,
force: true,
},
},
},
/* Javascript Tasks */
uglify: {
// Uglify files
build: {
src: [
'js/all-js/bootstrap.js',
'js/all-js/site.js'
],
dest: 'js/site.min.js'
}
},
/* Run tasks when needed */
watch: {
js: {
files: ['js/all-js/*.js'],
tasks: ['uglify'],
options: { livereload: true }
},
gruntfile: {
files: ['Gruntfile.js'],
options: {reload: true}
}
},
/* Browser Reload with BrowserSync */
browserSync: {
bsFiles: {
src : [
'css/**/*.css',
'js/site.min.js',
'**/*.php'
]
},
}
});
// Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask('default', ['concurrent:watch']);
grunt.registerTask('live', ['compass:live']);
};
Here's my package.json file:
{
"name": "ourframework",
"version": "0.1.0",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-compass": "*",
"grunt-browser-sync": "*",
"grunt-contrib-watch": "*",
"grunt-concurrent": "*",
"grunt-contrib-uglify": "*",
"matchdep": "*"
}
}
Look at the timestamps in the grunt output, eg:
Completed in 3.740s at Tue Jan 05 2016 13:11:10
Completed in 1.885s at Tue Jan 05 2016 13:12:04
Notice these compilations are a minute apart - you are running the grunt watch task. This will watch a set of specified files and re-run tasks if there are any changes.
There is no 'loop' - it will simply re-compile every time something changes, which is often desirable.
You can see your default task is set to concurrent:watch
grunt.registerTask('default', ['concurrent:watch']);
So if you just type grunt, it will run that task.

Grunt: How do I run seperate processes for CSS (sass, concat, minify) and JS (concat, minify)

I'm looking at the grunt watch documentation but I can see how to run a separate process for my javascript files. Below is what I have for CSS:
GruntFile.js
module.exports = function(grunt) {
grunt.initConfig({
// running `grunt sass` will compile once
sass: {
dist: {
options: {
style: 'expanded'
},
files: {
'./public/css/sass_styles.css': './src/sass/sass_styles.scss' // 'destination': 'source'
}
}
},
// bring in additonal files that are not part of the sass styles set
concat: {
dist: {
src: [
'public/css/datepicker.css',
'public/css/jquery.tagsinput.css',
'public/css/sass_styles.css',
'application/themes/japantravel/style.css'
],
dest: 'public/css/all.css',
},
},
// running `grunt cssmin` will minify code to *.min.css file(s)
cssmin: {
minify: {
expand: true,
cwd: "public/css/",
src: ["all.css", "!*.min.css"],
dest: "public/css/",
ext: ".min.css"
}
},
// running `grunt watch` will watch for changes
watch: {
files: ["./src/sass/*.scss", "./src/sass/partials/*.scss"],
tasks: ["sass", "concat", "cssmin"]
}
});
// load tasks
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks("grunt-contrib-cssmin");
grunt.loadNpmTasks("grunt-contrib-watch");
};
As you can see I have tasks for CSS ["sass", "concat", "cssmin"], but I want to do separate tasks for separate files (js) - concat and minify - and listen for changes (watch). Can someone point me in the correct direction, I'm not really sure what I should be searching for. Is this something that watch can handle, or is there another plugin? I'm a little new to grunt so still trying to figure out how to use it. Thanks
You can use 'grunt-concurrent' for that, you can define multiple tasks with it. In combination with watch sets you will have the proper solution. https://github.com/sindresorhus/grunt-concurrent
# to install:
npm install grunt-concurrent --save-dev
And this will be your adjusted function then.
Remember, you still have to set some uglify and jshint properties! But I believe that's not the issue here.
module.exports = function(grunt) {
grunt.initConfig({
/* .. */
// running `grunt watch` will watch for changes
watch: {
// Use 'sets' like this, just make up a name for it:
watchCss: {
files: ["./src/sass/*.scss", "./src/sass/partials/*.scss"], // Directory to look for changes
tasks: ["concurrent:taskCss"] // Tasks you want to run when CSS changes
},
watchJs: {
files: ["./src/js/**/*.js"], // Directory to look for changes
tasks: ["concurrent:taskJs"] // Tasks you want to run when JS changes
}
},
concurrent: {
taskCss: ["sass", "concat", "cssmin"], // define the CSS tasks here
taskJs: ["jshint", "concat", "uglify"] // define the JS tasks here
},
});
// load tasks
grunt.loadNpmTasks("grunt-contrib-sass");
grunt.loadNpmTasks("grunt-contrib-concat");
grunt.loadNpmTasks("grunt-contrib-cssmin");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.loadNpmTasks('grunt-contrib-jshint'); // Added
grunt.loadNpmTasks('grunt-contrib-uglify'); // Added
grunt.loadNpmTasks("grunt-concurrent"); // Added
// register tasks (note: you can execute sets from concurrent)
grunt.registerTask('default', ["concurrent:taskCss", "concurrent:taskJs"]);
grunt.registerTask('css', ["concurrent:taskCss"]);
grunt.registerTask('js', ["concurrent:taskJs"]);
};
To watch for changes:
grunt watch
# if a css file is changed, only the css tasks are performed
You can also execute a task from the prompt directly, for example:
grunt js
# This will only execute the registered task 'js'
# In this case that task points to 'concurrent:taskJs' wich will run jshint, concat and uglify
To install uglify and jshint:
https://github.com/gruntjs/grunt-contrib-uglify
https://github.com/gruntjs/grunt-contrib-jshint
npm install grunt-contrib-uglify --save-dev
npm install grunt-contrib-jshint --save-dev

Is it possible to use CommonJS modules with karma/mocha

Is this possible with CommonJS?
Basically I'm trying to take the API testing from http://thewayofcode.wordpress.com/2013/04/21/how-to-build-and-test-rest-api-with-nodejs-express-mocha/
and use Karma to run the tests.
I'm attempted to use RequireJS with karma, based off http://karma-runner.github.io/0.10/plus/requirejs.html
My package.json is correctly setup and 'npm install' gets everything I need,
but when I do 'karma start test/karma.conf.js' , no tests run
DEBUG [karma]: All browsers are ready, executing
DEBUG [web-server]: serving: /home/npoklitar/project/node_modules/karma/static/context.html
DEBUG [web-server]: serving: /home/npoklitar/project/node_modules/karma-requirejs/lib/require.js
DEBUG [web-server]: serving: /home/npoklitar/project/node_modules/karma-requirejs/lib/adapter.js
DEBUG [web-server]: serving: /home/npoklitar/project/node_modules/mocha/mocha.js
DEBUG [web-server]: serving: /home/npoklitar/project/node_modules/karma-mocha/lib/adapter.js
DEBUG [web-server]: serving: /home/npoklitar/project/test/routerSpec.js
DEBUG [web-server]: serving: /home/npoklitar/project/test/test-main.js
ERROR: 'There is no timestamp for /base/supertest.js!'
Chrome 30.0.1599 (Linux): Executed 0 of 0 SUCCESS (0 secs / 0 secs)
ERROR: 'There is no timestamp for /base/should.js!'
Chrome 30.0.1599 (Linux): Executed 0 of 0 SUCCESS (0 secs / 0 secs)
ERROR: 'There is no timestamp for /base/assert.js!'
Chrome 30.0.1599 (Linux): Executed 0 of 0 SUCCESS (0 secs / 0 secs)
Chrome 30.0.1599 (Linux): Executed 0 of 0 ERROR (0.355 secs / 0 secs)
DEBUG [launcher]: Disconnecting all browsers
DEBUG [launcher]: Killing Chrome
test/rounterSpec.js
require(['supertest','should','assert'], function(supertest,should,assert){
describe('Routing:', function() {
var url = 'http://localhost:16000';
describe('API', function() {
it('should return the success string and request headers', function(done){
supertest(url)
.get('/api')
.expect(200)
.end(function(err, res) {
if (err) {
throw err;
}
var text = res.text;
var splitted = text.split('!');
splitted[0].should.include('request successfully proxied to API');
done();
});
});
});
});
});
test/karma.conf.js
module.exports = function (karma) {
karma.set({
// base path, that will be used to resolve files and exclude
basePath: '../',
frameworks: ['mocha','requirejs'],
// list of files / patterns to load in the browser
files: [
// {pattern: 'node_modules/chai/chai.js', include: true},
// {pattern: '*.js', include: false},
'test/*.js',
'test/test-main.js'
],
// list of files to exclude
exclude: [
'karma.conf.js'
],
// use dots reporter, as travis terminal does not support escaping sequences
// possible values: 'dots', 'progress', 'junit', 'teamcity'
// CLI --reporters progress
reporters: ['progress', 'junit', 'coverage'],
junitReporter: {
// will be resolved to basePath (in the same way as files/exclude patterns)
outputFile: 'junit-report/test-results.xml'
},
preprocessors: {
'src/*.js': 'coverage'
},
//Code Coverage options. report type available:
//- html (default)
//- lcov (lcov and html)
//- lcovonly
//- text (standard output)
//- text-summary (standard output)
//- cobertura (xml format supported by Jenkins)
coverageReporter: {
// cf. http://gotwarlost.github.com/istanbul/public/apidocs/
type: 'lcov',
dir: 'coverage/'
},
// web server port
port: 9876,
// cli runner port
runnerPort: 9100,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
logLevel: LOG_DEBUG,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
// CLI --browsers Chrome,Firefox,Safari
browsers: ['Chrome'],
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 6000,
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: true,
plugins: [
'karma-mocha',
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-junit-reporter',
'karma-coverage',
'karma-requirejs'
]
});
}
test/test-main.js
var tests = [];
for (var file in window.__karma__.files) {
if (/Spec\.js$/.test(file)) {
tests.push(file);
}
}
requirejs.config({
// Karma serves files from '/base'
baseUrl: '/base',
/*
paths: {
'jquery': '../lib/jquery',
'underscore': '../lib/underscore',
},
shim: {
'underscore': {
exports: '_'
}
},
*/
// nodeRequire: require, //doesnt work with or without this commented
// ask Require.js to load these files (all our tests)
deps: tests,
// start test run, once Require.js is done
callback: window.__karma__.start
});
I've created a plugin for Karma here: https://www.npmjs.com/package/karma-common-js
It let's you write tests as if you're using Browserify, but the plugin doesn't use Browserify. Not using Browserify has a few advantages:
There's no bundle created, so it's very fast for watching file changes
Line numbers and file names are preserved in stack traces without needing source maps
Works with karma-coverage
Lets you pass a second argument to require to pass in mocks
All (I hope) of Browserifys core features work. Such as transforms, respecting the browser field in package.json, requiring builtin modules uses the same shims as Browserify, etc.
There is now a CommonJS plugin for Karma: https://github.com/karma-runner/karma-commonjs
After trying a bunch of different plugins, I ended up using the karma-browserifast plugin that actually works quite well - especially if you run it in debug mode.

Ember.js - Handlebars not recognized if required via Grunt (Node.js)

is anybody else using Grunt as build tool for the Ember web application and is experiencing the same behaviour as I do? At this time, I'm using the framework in version RC3 and I can use my build tool without hassle and import all necessary libraries, uglify and compress them and everything works like a charm.
Anyhow, at least since Ember RC5 I'm not able to use Grunt for building my application anymore as Ember would not recognize Handlebars anymore!. It's always complaining that Ember Handlebars requires Handlebars version 1.0.0-rc.4. Include a SCRIPT tag in the HTML HEAD linking to the Handlebars file before you link to Ember. and right afterwards it says Cannot read property 'COMPILER_REVISION' of undefined which leads me to the assumption that Ember is not recognizing the included Handlebars library.
I haven't changed anything in my app.js (the order of the libraries/frameworks is untouched) except the references to the js files (using Ember RC5/6 instead of RC3 and Handlebars RC4 instead of RC3). But it seems that something breaks the initialization of Ember.Handlebars since then...
Do I get something wrong here? Is there a solution out there so that I can continue using Grunt as build tool?
EDIT
Here's my Gruntfile.js:
/*jshint camelcase: false */
/*global module:false */
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
meta: {
dev: {
buildPath: '.'
},
prod: {
buildPath: '.'
}
},
/*
Task for uglifyng the application javascript file in production environment
*/
uglify: {
options: {
banner: '/*! <%= pkg.name %> - v<%= pkg.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %> */'
},
prod: {
files: [
{
src: '<%= meta.prod.buildPath %>/js/application.js',
dest: '<%= meta.prod.buildPath %>/js/application.min.js'
}
]
}
},
/*
Task for creating css files out of the scss files
*/
compass: {
prod: {
options: {
environment: 'production',
noLineComments: true,
outputStyle: 'expanded',
cssDir: '<%= meta.prod.buildPath %>/css',
fontsDir: '<%= meta.prod.buildPath %>/fonts',
imagesDir: '<%= meta.prod.buildPath %>/images',
javascriptsDir: '<%= meta.prod.buildPath %>/js'
}
},
dev: {
options: {
environment: 'development',
noLineComments: false,
outputStyle: 'expanded',
cssDir: '<%= meta.dev.buildPath %>/css',
fontsDir: '<%= meta.dev.buildPath %>/fonts',
imagesDir: '<%= meta.dev.buildPath %>/images',
javascriptsDir: '<%= meta.dev.buildPath %>/js'
}
}
},
/*
Task to minify all css files in production mode.
All css files will end with '.min.css' instead of
just '.css'.
*/
cssmin: {
minify: {
expand: true,
cwd: '<%= meta.prod.buildPath %>/css/',
src: ['*.css', '!*.min.css'],
dest: '<%= meta.prod.buildPath %>/css/',
ext: '.min.css'
}
},
/*
Clean up the production build path
*/
clean: {
cssd: ['<%= meta.prod.buildPath %>/css/**/*']
},
/*
A simple ordered concatenation strategy.
This will start at app/app.js and begin
adding dependencies in the correct order
writing their string contents into 'application.js'
Additionally it will wrap them in evals
with # sourceURL statements so errors, log
statements and debugging will reference
the source files by line number.
This option is set to false for production.
*/
neuter: {
prod: {
options: {
includeSourceURL: false
},
files: [
{
src: 'app/app.js',
dest: '<%= meta.prod.buildPath %>/js/application.js'
}
]
},
dev: {
options: {
includeSourceURL: true
},
files: [
{
src: 'app/app.js',
dest: '<%= meta.dev.buildPath %>/js/application.js'
}
]
}
},
/*
Watch files for changes.
Changes in dependencies/ember.js or application javascript
will trigger the neuter task.
Changes to any templates will trigger the ember_templates
task (which writes a new compiled file into dependencies/)
and then neuter all the files again.
*/
watch: {
application_code: {
files: ['js/dependencies/ember.js', 'app/**/*.js'],
tasks: ['neuter:dev']
},
compass: {
files: [
'styles/**/*.scss'
],
tasks: ['compass:dev']
}
},
/*
Runs all .html files found in the test/ directory through PhantomJS.
Prints the report in your terminal.
*/
qunit: {
all: ['test/**/*.html']
},
/*
Reads the projects .jshintrc file and applies coding
standards. Doesn't lint the dependencies or test
support files.
*/
jshint: {
all: ['Gruntfile.js', 'app/**/*.js', 'test/**/*.js', '!js/dependencies/*.*', '!test/support/*.*'],
options: {
jshintrc: '.jshintrc'
}
},
/*
Generate the YUI Doc documentation.
*/
yuidoc: {
name: '<%= pkg.name %>',
description: '<%= pkg.description %>',
version: '<%= pkg.version %>',
options: {
paths: '<%= meta.dev.buildPath %>/app/',
outdir: '<%= meta.dev.buildPath %>/yuidocs/'
}
},
/*
Find all the <whatever>_test.js files in the test folder.
These will get loaded via script tags when the task is run.
This gets run as part of the larger 'test' task registered
below.
*/
build_test_runner_file: {
all: ['test/**/*_test.js']
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-neuter');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-yuidoc');
/*
A task to build the test runner html file that get place in
/test so it will be picked up by the qunit task. Will
place a single <script> tag into the body for every file passed to
its coniguration above in the grunt.initConfig above.
*/
grunt.registerMultiTask('build_test_runner_file', 'Creates a test runner file.', function () {
var tmpl = grunt.file.read('test/support/runner.html.tmpl');
var renderingContext = {
data: {
files: this.filesSrc.map(function (fileSrc) {
return fileSrc.replace('test/', '');
})
}
};
grunt.file.write('test/runner.html', grunt.template.process(tmpl, renderingContext));
});
/*
A task to run the application's unit tests via the command line.
It will
- convert all the handlebars templates into compile functions
- combine these files + application files in order
- lint the result
- build an html file with a script tag for each test file
- headlessy load this page and print the test runner results
*/
grunt.registerTask('test', ['neuter', 'jshint', 'build_test_runner_file', 'qunit']);
/*
Configures all tasks which will be executed with production setup
*/
grunt.registerTask('prod_tasks', ['clean', 'compass:prod', 'cssmin', 'neuter:prod', 'uglify:prod']);
/*
Setup for the production build. Sets the production build path.
*/
grunt.registerTask('prod', 'Production Build', function () {
grunt.task.run('prod_tasks');
});
/*
Configures all tasks which will be executed with development setup
*/
grunt.registerTask('dev_tasks', ['compass:dev', 'neuter:dev', 'watch']);
/*
Setup for the development build. Sets the development build path.
*/
grunt.registerTask('dev', 'Development Build', function () {
grunt.task.run('dev_tasks');
});
// Default task
grunt.registerTask('default', 'dev');
/*
Configures all tasks which will be executed with doc setup
*/
grunt.registerTask('doc_tasks', ['yuidoc']);
/*
Setup for the YUI doc generation.
*/
grunt.registerTask('doc', 'Generate YuiDoc Documentation for the App', function () {
grunt.task.run('doc_tasks');
});
};
EDIT 2
I took the ember-1.0.0-rc.6.js and handlebars-1.0.0-rc.4.js files from the starter kit at the Ember.js website and tried to run the Grunt tasks on it. Here's what Chrome is telling me:
EDIT 3
Just in case if anybody cares, here's the link to the raised issue over at the Ember.js Github page: https://github.com/emberjs/ember.js/issues/2894
EDIT 4
Finally, the issue was identified to be a Handlebars inconsistency when dealing with global exports, like #Tao reported in his answer. Here's the link to the Issue on GitHub if you want to follow: https://github.com/wycats/handlebars.js/issues/539
It looks like this issue is being addressed in the next version of Handlebars: https://github.com/wycats/handlebars.js/issues/539 Stay tuned.
You have a mismatch in the version used to compile the Handlebars templates and the version included via the script tag.
If you are using grunt-contrib-handlebars, it uses the npm module handlebars to compile the the templates. The handlebars module/project is independent of Ember and has its own revisions that may or not be compatible with Ember.
To maintain compatibility with Handlebars Ember needs specific versions of handlebars which it is warning you about.
The tricky part here is you need to ensure that grunt-contrib-handlebars is forced to use that specific version of handlebars.
Solution 1: Use shrinkwrap to change grunt-contrib-handlebars's handlebars dependency version.
Solution 2: This is what I am currently using. I have switched to Emblem. The emblem grunt task asks for your handlebars file explicitly so you don't have to drop down to node sub dependency management. And your build includes the same file into your script tags, thus avoiding duplication/mismatch for future revisions.
Edit: After Gruntfile edit
Looking at the Gruntfile I don't see anything amiss. Looks like a standard build process, js -> neuter -> (if prod) -> uglify etc.
I think you need to try refreshing both emberjs and handlebars js files. Try using the files from the starter kit itself, those definitely work together.
And verify this for your index.html by looking at the unminified source in Chrome/Inspector. Handlebars has the revision numbers below the banner something like Handlebars.VERSION and Handlebars.COMPILER_REVISION. Match those with what you see in the ember.js file, somewhere below #submodule ember-handlebars-compiler in the Ember.assert.

Resources