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

1.4k Views Asked by At

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

2

There are 2 best solutions below

0
Nuclear Wessel On BEST ANSWER

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;
0
cscott530 On

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.