Note that there are some explanatory texts on larger screens.

plurals
  1. POEmber.js - Handlebars not recognized if required via Grunt (Node.js)
    text
    copied!<p>is anybody else using <code>Grunt</code> as build tool for the <code>Ember</code> web application and is experiencing the same behaviour as I do? At this time, I'm using the framework in version <code>RC3</code> and I can use my build tool without hassle and import all necessary libraries, uglify and compress them and everything works like a charm.</p> <p>Anyhow, at least since <code>Ember RC5</code> I'm not able to use <code>Grunt</code> for building my application anymore as <strong>Ember would not recognize Handlebars anymore!</strong>. It's always complaining that <code>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.</code> and right afterwards it says <code>Cannot read property 'COMPILER_REVISION' of undefined</code> which leads me to the assumption that <code>Ember</code> is <em>not recognizing</em> the included <code>Handlebars</code> library.</p> <p>I haven't changed anything in my <code>app.js</code> (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 <code>Ember.Handlebars</code> since then...</p> <p>Do I get something wrong here? Is there a solution out there so that I can continue using <code>Grunt</code> as build tool?</p> <hr> <h2>EDIT</h2> <p>Here's my <code>Gruntfile.js</code>:</p> <pre><code>/*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: '/*! &lt;%= pkg.name %&gt; - v&lt;%= pkg.version %&gt; - ' + '&lt;%= grunt.template.today("yyyy-mm-dd") %&gt; */' }, prod: { files: [ { src: '&lt;%= meta.prod.buildPath %&gt;/js/application.js', dest: '&lt;%= meta.prod.buildPath %&gt;/js/application.min.js' } ] } }, /* Task for creating css files out of the scss files */ compass: { prod: { options: { environment: 'production', noLineComments: true, outputStyle: 'expanded', cssDir: '&lt;%= meta.prod.buildPath %&gt;/css', fontsDir: '&lt;%= meta.prod.buildPath %&gt;/fonts', imagesDir: '&lt;%= meta.prod.buildPath %&gt;/images', javascriptsDir: '&lt;%= meta.prod.buildPath %&gt;/js' } }, dev: { options: { environment: 'development', noLineComments: false, outputStyle: 'expanded', cssDir: '&lt;%= meta.dev.buildPath %&gt;/css', fontsDir: '&lt;%= meta.dev.buildPath %&gt;/fonts', imagesDir: '&lt;%= meta.dev.buildPath %&gt;/images', javascriptsDir: '&lt;%= meta.dev.buildPath %&gt;/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: '&lt;%= meta.prod.buildPath %&gt;/css/', src: ['*.css', '!*.min.css'], dest: '&lt;%= meta.prod.buildPath %&gt;/css/', ext: '.min.css' } }, /* Clean up the production build path */ clean: { cssd: ['&lt;%= meta.prod.buildPath %&gt;/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: '&lt;%= meta.prod.buildPath %&gt;/js/application.js' } ] }, dev: { options: { includeSourceURL: true }, files: [ { src: 'app/app.js', dest: '&lt;%= meta.dev.buildPath %&gt;/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: '&lt;%= pkg.name %&gt;', description: '&lt;%= pkg.description %&gt;', version: '&lt;%= pkg.version %&gt;', options: { paths: '&lt;%= meta.dev.buildPath %&gt;/app/', outdir: '&lt;%= meta.dev.buildPath %&gt;/yuidocs/' } }, /* Find all the &lt;whatever&gt;_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 &lt;script&gt; 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'); }); }; </code></pre> <hr> <h2>EDIT 2</h2> <p>I took the <code>ember-1.0.0-rc.6.js</code> and <code>handlebars-1.0.0-rc.4.js</code> 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: <img src="https://i.stack.imgur.com/rwoGA.jpg" alt="Ember RC6 Problems with Handlebars on Grunt Buildstep"></p> <hr> <h2>EDIT 3</h2> <p>Just in case if anybody cares, here's the link to the raised issue over at the Ember.js <strong>Github</strong> page: <a href="https://github.com/emberjs/ember.js/issues/2894" rel="nofollow noreferrer">https://github.com/emberjs/ember.js/issues/2894</a></p> <hr> <h2>EDIT 4</h2> <p>Finally, the issue was identified to be a <code>Handlebars</code> 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: <a href="https://github.com/wycats/handlebars.js/issues/539" rel="nofollow noreferrer">https://github.com/wycats/handlebars.js/issues/539</a></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload