2

I am currently working in a Durandal project and researching the use of Knockout Components in my application. I'm building using Gulp and the gulp-durandal plugin and have it configured to use almond.

I'm running into an issue where I receive the following error when navigating to one of my pages which uses the newly registered components:

component: function () { return componentBindingValue; }" Message: Component 'myComponent': Uses require, but no AMD loader is present

In the hopes of providing as much information as possible, here is the gulpfile I am currently using as well.

var gulp = require('gulp');
var durandal = require('gulp-durandal');

gulp.task('durandal', function() {
    durandal({
        baseDir: 'app',
        main: 'main.js',
        output: 'main-built.js',
        almond: true,
        minify: true,
        rjsConfigAdapter: function (rjsConfig) {
            rjsConfig.paths = {
                'text': '../Scripts/text',
                'durandal': '../Scripts/durandal',
                'plugins': '../Scripts/durandal/plugins',
                'transitions': '../Scripts/durandal/transitions',
                'dataservice': 'domain/dataservice'
            };

            return rjsConfig;
        }
    }).pipe(gulp.dest('build'));
});
  • If you set almond: false does it work? – Frank Feb 05 '15 at 12:48
  • Sadly, no. If I change the script to "almond: false" then when trying to run main.js I get the error: 'Uncaught ReferenceError: define is not defined` – James Chadwick Feb 05 '15 at 15:30
  • well, it was worth a shot, looks like the error message your are getting is from this [code](https://github.com/knockout/knockout/blob/master/src/components/defaultLoader.js) . I would try using the debug version of knockout and put a breakpoint here, then follow the stack trace and see if reveals anything more. If you don't have your heart set on knockout components you can also try using the built in [widget support](http://durandaljs.com/documentation/Creating-A-Widget.html) in durandal, it is very similar to ko components – Frank Feb 05 '15 at 20:18
  • @James did you get any solution for this, because am also facing same issue – Sivanraj M Feb 10 '15 at 04:19
  • @SivanrajM No I have not. I see that you have also commented on the issue that I logged in Github. I noticed this issue in 3.2 as well and was building my app using Weyland at the time. Since Weyland has been discontinued decided to upgrade to Gulp. An educated guess would lead me to believe that Almond and Knockout aren't playing nice together. – James Chadwick Feb 10 '15 at 15:51

2 Answers2

2

The Durandal Gulp task is calling r.js with the wrap parameter configured to encapsulate your application code in an IFFE with the Almond source. Unfortunately, Almond's require, requirejs, and define implementations are getting bundled inside and not being added to the global window scope the way Knockout is expecting.

You can manipulate the wrap parameter in the rjsConfigAdapter to remove the IFFE wrappers, or just add require/define to the window object first thing in your application code to get around this.

Ex.

requirejs.config(config);
window.require = require;
window.requirejs = requirejs;
window.define = define;
-1

I ran into this as well, but I had a much simpler front-end stack, and I was only seeing it on one page, even though I was using the component several places through my site.

Turns out it can also be a race condition. I had to put my ko.applyBindings inside of document.ready callback, and everything worked.

cscott530
  • 1,658
  • 16
  • 25