requirejs - why loading module in define() works, but in require() doesn't

StackOverflow https://stackoverflow.com/questions/23523143

  •  17-07-2023
  •  | 
  •  

Question

Code blow doesn't work, and the error msg is:

Uncaught Error: Module name "text!templates/bookTemplate.html_unnormalized2" has not been loaded yet for context: _. Use require([])

define(['backbone', 'underscore', 'jquery'], function (Backbone, _, $) {
    var bt = require('text!templates/bookTemplate.html');
    var BookView = Backbone.View.extend({
        initialize: function () {
            this.render();
        },
        render: function () {
            var template = _.template(bt, {
                name: 'secret book'
            });
            this.$el.html(template);
        }
    });
    return BookView;
});

then I move the "text!templates/bookTemplate.html" to define(), it works! below is working code:

   define(['backbone', 'underscore', 'jquery', 
'text!templates/bookTemplate.html'], function (Backbone, _, $, bt) {
        // var bt = require('text!templates/bookTemplate.html');
        var BookView = Backbone.View.extend({
            initialize: function () {
                this.render();
            },
            render: function () {
                var template = _.template(bt, {
                    name: 'secret book'
                });
                console.info('template', template);
                this.$el.html(template);
            }
        });
        return BookView;
    }); // it is working

As my understanding, require() and define() is the same in loading a module. Is this correct? Can you help me explain why it works in define and doesn't in require()?

Était-ce utile?

La solution

You are calling require with a string literal. When you call require like this, it acts in a pseudo-synchronous fashion. It acts like a synchronous call because it will return immediately the module. It is pseudo-synchronous because the module must be loaded before you call the pseudo-synchronous form of require.

So you could do this:

define(['backbone', 'underscore', 'jquery', 'text!templates/bookTemplate.html'], 
  function (Backbone, _, $) {
    var bt = require('text!templates/bookTemplate.html');

and it would work because the module would be loaded before require executes. Or you could use the method you've shown in your 2nd code snippet:

define(['backbone', 'underscore', 'jquery', 
    'text!templates/bookTemplate.html'], function (Backbone, _, $, bt) {

Or you could use use the CommonJS wrapping:

define(function(require, exports, module) {
    var Backbone = require('backbone');
    var _ = require('underscore');
    var jquery = require('jquery');
    var bt = require('text!templates/bookTemplate.html');

This wrapping works because RequireJS will transform it at run time into:

define(["require", "exports", "module", "backbone", "underscore", "jquery",
        "text!templates/bookTemplate.html"], function(require, exports, module) {
    var Backbone = require('backbone');
    var _ = require('underscore');
    var jquery = require('jquery');
    var bt = require('text!templates/bookTemplate.html');

before executing the module.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top