Search code examples
javascriptrequirejsboweramd

requirejs + bower, paths and dependencies within bower components


I have done a lot of research but can't find the answer I am looking for, so here goes.

I have a bower component which has its own dependencies:

/vendor/bower_components/my_module/my_module.js /vendor/bower_components/my_module/dependency_1.js /vendor/bower_components/my_module/dependency_2.js

Inside of my_module.js, it loads its dependencies using relative paths:

define(["./dependency_1", "./dependency_2"], function (dep1, dep2) { ... });

But when my requirejs config.paths is set up:

paths: {
    my_module: "/vendor/bower_components/my_module/my_module"
}

... now the relative paths are relative to the base requirejs path and not the full path for my_module. I understand why this is happening (because the module id is no longer the full path, but rather the shortened name), I just don't know how to solve it. I am pretty sure packages is the right direction, I'm just not having any luck. How should I go about this? my_module is a third party module btw and would rather not edit it. Thanks.

UPDATE - Example uses of code within my application:

Scenario 1 (without config.paths):

define(["/vendor/bower_components/my_module/my_module"], function(myModule) {
    // This works.  No issues here.
    // The reason this works is because the module ID for myModule is:
    // "/vendor/bower_components/my_module/my_module"
    // Therefore, the relative paths "./dependency_1" and "./dependency_2"
    // are resolved against that module ID.
});

Scenario 2 - now my_module is defined in config.paths (see above):

define(["my_module"], function(myModule) {
    // Error, cannot load files dependency_1.js or dependency_2.js
    // This is because relative paths are resolved against a module's ID.
    // Now the module ID is "my_module", not "/vendor/bower_components/my_module/my_module"
    // As such, the paths for ./dependency_1 and ./dependency_2 are resolved against "/"
});

Unfortunately (or not?) this happens by design: http://requirejs.org/docs/api.html#modulenotes-relative-names. We should be able to use packages to resolve this. I'm just wondering if anybody has any knowledge of how to do this.


Solution

  • This is what I get so far with your question. You can do what you want (or not?) with these configurations:

    require.config({
        packages: [
            {
                name: "myModule"
                location: '/vendor/bower_components/my_module/',
                main: "my_module"
            }
            // [name option] can be anything you want
            // [main option] pointing to your main js file of the package
            // if you rename your mymodule.js to main.js you no longer need to config the [main option]
        ]
    });
    

    and in your my_module.js

    define(["./dependency_1", "./dependency_2"], function (dep1, dep2) {
      // ...
    });
    

    And you can call your my_module.js like this.

    define(["myModule"], function(myModule) {
        // ...
    });
    

    For further info you can check out this link Common-config#packages