Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Require.js nested requires

I'm trying to use requireJS but I want to build a hierarchy of dependencies: main requires obr.platcom and obr.platcom requires obr (for example).

I have this hierarchy of files:

- index.html
-> js
   - main.js
   -> lib
      - jquery.js
      - require.js
   -> obr [my own 'libraries']
      - obr.js
      - obr.platcom.js

index.html

<!DOCTYPE html>
<html lang="es">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta name="viewport" content="initial-scale=1.0, width=device-width" />
        <title>Platcom</title>
        <script type="text/javascript" src="js/lib/jquery.js"></script>
        <script data-main="js/main" src="js/lib/require.js"></script>
    </head>
    <body>
    </body>
</html>

main.js

$(document).ready(function() {
    require(["obr/obr.platcom"], function() {
        obr.hola();
        var myPlatcom = obr.platcom();
        myPlatcom.test();
    });
});

obr.js

var obr = {};
obr.hola = function() {
    alert('Hola OBR');
};

obr.platcom.js

require(["obr.js"],function() {
    obr.platcom = function(params) {
        var that = {};

        var test = function test() {
            alert('Hola Platcom!');
        }

        that.test = test;
        return that;
    }
});

If I require both obr and obr.platcom files in the main all works, but if I use this nested style I receive the next error:

Uncaught ReferenceError: obr is not defined       main.js:3

Do you know what I'm doing wrong? Thank you in advance.

like image 237
dgnin Avatar asked Feb 21 '23 09:02

dgnin


1 Answers

Alright, you've done several things wrong.

  1. You need to specify as an argument the dependency you're injecting. For example, require(["obr/obr.platcom"], function() { won't do much unless you specify how the required module can be called. You should need this:

    require(["obr/obr.platcom"], function( obr ) {
    

    This way, you know in which variable your required object is.

  2. The obr.js variables are in the global scope. You need to wrap them in a require or define function call. The following would work:

    define(function() {
        var obr = {};
        obr.hola = function() {};
        return obr;
    });
    

    You may have noticed some things that are wrong with your last file.

  3. If you want your module to be imported somewhere, you have to define it. So you have to use the define function, not the require one. And the define function must return an object. Here is a fixed obr.platcom.js file:

    // If you don't use "define" for the obr.js file too, this won't work
    define(['obr'], function( obr ) {
        obr.platcom = function() {};
    
        // Don't forget to return the obr object, or the require of
        // the main file won't return anything
        return obr;
    });
    

This way, things are done the correct way. Or at least, the way require.js wants you to do stuff.

I hope this reveals you how require.js can be effectively used to easily separate your code in modules :)

like image 73
Florian Margaine Avatar answered Feb 27 '23 08:02

Florian Margaine