James Chadwick
James Chadwick

Reputation: 143

Knockout Components "Uses require, but no AMD loader is present"

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'));
});

Upvotes: 2

Views: 1430

Answers (2)

cscott530
cscott530

Reputation: 1708

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.

Upvotes: -1

Nuclear Wessel
Nuclear Wessel

Reputation: 36

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;

Upvotes: 2

Related Questions