SlexAxton / require-handlebars-plugin

A plugin for handlebars in require.js (both in dev and build)
804 stars 202 forks source link

Strange error on r.js build via grunt-contrib-requirejs #135

Open Saturate opened 11 years ago

Saturate commented 11 years ago

I get this error that breaks my build, I'm not 100% sure what the issue is:

C:\Git\SomePath\Layouts\UI\node_modules\grunt-contrib-compass\node_modules\tmp\lib\tmp.js:261
  throw err;
        ^
Error: Mismatched anonymous define() module: function ( hbs, Handlebars ){
var t = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
  helpers = helpers || Handlebars.helpers;

  return "<h4>\r\n      <span class=\"label label-info\">Frist udl├©ber: </span>\r\n</h4>";});
Handlebars.registerPartial('aura_components_countdown_countdown', t);
return t;
}
http://requirejs.org/docs/errors.html#mismatch
    at makeError (C:\Git\SomePath\Layouts\UI\node_modules\grunt-bower-hooks\node_modules\requirejs\bin\r.js:397:17)
    at intakeDefines (C:\Git\SomePath\Layouts\UI\node_modules\grunt-bower-hooks\node_modules\requirejs\bin\r.js:1454:36)
    at null._onTimeout (C:\Git\SomePath\Layouts\UI\node_modules\grunt-bower-hooks\node_modules\requirejs\bin\r.js:1638:25)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)

But the paths are pretty strange. I am only running grunt requirejs.

Haraldson commented 10 years ago

I’m getting the same error, also with grunt requirejs. Were you able to fix it, @Saturate?

Is it because of some weird circular dependency? hbs.js is chock full of require this and that calls.

Saturate commented 10 years ago

I'm uncertain on how I fixed this. If you post your config, I might be able to see what I have changed.

Haraldson commented 10 years ago

@Saturate Is this enough? https://gist.github.com/Haraldson/7562873 :)

Saturate commented 10 years ago

You do not need to shim it. Also make sure you are using the correct files, like this:

// Templates 
handlebars:             'bower_components/require-handlebars-plugin/Handlebars',
hbs:                    'bower_components/require-handlebars-plugin/hbs',
i18nprecompile:         'bower_components/require-handlebars-plugin/hbs/i18nprecompile',
json2:                  'bower_components/require-handlebars-plugin/hbs/json2'

That might fix it, I'm not sure that this was my error, but try it out :)

Haraldson commented 10 years ago

Well, my app is crashing if I remove the shim. handlebars.js, hbs.js and json2 (i18nprecompile is disabled) are loaded via the baseUrl, as they’re all located in the lib folder. I’m not using Bower. Tried replacing my version of the files with the current ones in this repo, that also results in a crash... :-/

kashifshamaz21 commented 10 years ago

@SlexAxton Any idea why this issue might be occurring? Even i'm facing the same issue when trying to optimize using r.js (version 2.1.9). I'm using the latest version of this plugin(0.7.0). @Haraldson Which versions of r.js and this plugin did you use?

kashifshamaz21 commented 10 years ago

I actually got this issue resolved with the following require config: "paths": { "hbs/handlebars": "thirdparty/hbs-deps/handlebars", "hbs/underscore": "thirdparty/hbs-deps/underscore", "hbs/i18nprecompile": "thirdparty/hbs-deps/i18nprecompile", "hbs/json2": "thirdparty/hbs-deps/json2", "hbs": "thirdparty/hbs" } And no shim for hbs/handlebars plugin because it has already been wrapped in an AMD define() call. I'm using the latest(0.7.0) version of the plugin.

@Haraldson are you using some other 'Handlebars' plugin as well along with the one in hbs/ directory?

Haraldson commented 10 years ago

@kashifshamaz21 I haven’t been fiddling around with this for a long while, but I’ll have a look at your solution once I’ve got the time. I’m currently shimming Handlebars and hbs like this, not entirely sure why anymore, though;

'Handlebars': {
    exports: 'Handlebars'
},

'hbs': {
    deps: ['Handlebars', 'handlebars.compare', 'handlebars.math', 'json2'], // 'i18nprecompile'
    exports: 'Handlebars'
}
kashifshamaz21 commented 10 years ago

@Haraldson If you are using the latest version of the plugin, i don't think you would need any shim config at all because hbs and its dependencies are already turned into amd modules by the author. Try removing the shim and setting the path config for all the files and see if it helps. cheers.

Haraldson commented 10 years ago

Is anyone using grunt-contrib-requirejs for this? An example config would be super helpful. Both Gruntfile.js and all the relevant stuff from the mainConfigFile (I’m importing my config from my app’s entry-point file, main.js), what to include and so on.

Haraldson commented 10 years ago

I’ve finally had the time to look more at this. My page isn’t rendering anymore, but I’m now able to run r.js without it throwing any errors back in my face.

My current configuration looks like this (the relevant parts):

requirejs.config(
{
    baseUrl: '/assets/js/lib/',
    paths: {
        // Templates
        handlebars: 'hbs/handlebars',
        hbs: 'hbs',
        i18nprecompile: 'hbs/i18nprecompile',
        json2: 'hbs/json2'
    }
}

hbs.js is located in the lib folder, and it’s modified like this: define(['handlebars', 'hbs/underscore', 'i18nprecompile', 'json2'] ... as I’m using Lodash otherwise.

I’m currently not shimming any of the template related stuff.

So all that remains is to combine r.js compatibility with the most important aspect of any web app; actually rendering it out in the browser. Any ideas?

kashifshamaz21 commented 10 years ago

@Haraldson The config you are using seems to be fine, are you seeing any build/runtime issues. When you include any handlebars templates in your js files(hbs!template/xyz), and run r.js optimizer on the js files, the templates will get compiled and inlined into the output js file.

Haraldson commented 10 years ago

@kashifshamaz21 No build issues, but plenty of runtime issues with the minified file – it complains about libraries being undefined. First it complained that define() was undefined. Then I added require.js to my Gruntfile’s requirejs.options.include array. Then it complained that Backbone was undefined. And so on. I thought r.js would be able to read all these dependencies from my requirejs.config and merge them into the minified file?

I also was unable to set it up in such a way that I could continue developing and rendering the page unoptimized, as well as running the optimizer. Necessary changes done to the scripts would mess it up for the browser rendering, rolling the changes back would cause the optimizer to choke again.

This is turning into such a time consuming problem...

kashifshamaz21 commented 10 years ago

@Haraldson can you put a link to the require config and the project's entry point(main.js).. r.js optimizer traverses the dependency tree, starting from the main.js, and going recursively from there on. So, if your main.js, or any of its dependency js files, include backbone in their dependency array, optimizer will compile it into the final built output file..

Maybe if you can put the config and main.js and other files, can give more clear information

Haraldson commented 10 years ago

@kashifshamaz21 I am now able to both run the unoptimized project in my browser and run the optimizer using the same main.js file.

But. If I point my data-main to the optimized file, nothing happens. No error messages, nothing. Blank screen. Any pointers to what could be wrong? As this is a new question on my part, I don’t know what files you would be interested in having a look at, if any.

I appreciate your help, by the way. Big thanks!

kashifshamaz21 commented 10 years ago

@Haraldson Good to know that the unoptimized build is up and running. Regarding the issue with the optimized build, a few questions:

  1. Does running the optimizer on the main.js throw up any error?
  2. The output file after the optimzation, does it have all the js modules compiled into it? or has it ended up into an empty file?
  3. Maybe if you can create a jsfiddle for your project and post it here, i can have a look.
Haraldson commented 10 years ago

@kashifshamaz21 There are no errors, and the file is built, though without the contents of main.js, which mainly consists of requirejs.config, but ends with the following:

define(['app', 'domReady!'], function(App)
{
    App.start();
});

This is why nothing happens. I’ve tried several patterns for kickstarting my app, but had no luck so far.

The project is way too huge for a fiddle, I’m afraid.@

Edit: I got it resolved now, in both cases. Now just struggling with timing issues with the optimized code. :)

mchepurnoy commented 10 years ago

@Haraldson How do you resolve this?

mchepurnoy commented 10 years ago

@Haraldson You said: "Edit: I got it resolved now, in both cases.". But how?)

Haraldson commented 10 years ago

@mchepurnoy: The way I solved it – and I don’t know if this is a really ugly hack or just business as usual in the Requirejs universe – is as following:

main.js

requirejs.config(
{
    paths: {
        // The app
        app: '../app/app',
        init: '../app/init',
        // ...
    }
});

require(['init']);

init.js

require(['app', 'domReady!'], function(App)
{
    App.start();
});

My problem was that the code that was supposed to start my app never ran when optimized. I solved this by making the initiation requirable, and it is now being run both when optimized and unoptimized.

mchepurnoy commented 10 years ago

@Haraldson Thanks. Got it.