Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

require.js require a module with index.js

So I'm trying to set up Typescript and Chutzpah for testing purposes. Typescript is set up to output in this format:

define(['require', 'exports', './someModule'], function(require, exports, someModule) {
    //examplecode
});

Which works fine, the problem occurs when someModule is actually a directory with an index.js.

/app
  app.js
  /someModule
    index.js

require.js is unable to resolve someModule in this way and the test fails.

Is there any way to tell require.js that this is a module?

like image 769
Devan Buggay Avatar asked Jan 23 '17 22:01

Devan Buggay


2 Answers

RequireJS won't automatically check for the presence of index.js and load that as your module. You need to tell RequireJS that when you want to load someModule, it should load someModule/index. I'd set a map in my call to require.config:

require.config({
  [ ... ]
  map: {
    '*': {
        someModule: 'someModule/index',
    }
  },
});

You have to adjust the name you give there so that it is a path relative to your baseUrl. It's not clear from the information you give in your question what it should be.

(For the record, there's also a packages setting that you could probably tweak to do what you want but putting something packages says "this is a package", which is not what you appear to have here. So I would not use it for what you are trying to do.)

like image 52
Louis Avatar answered Sep 23 '22 03:09

Louis


I didn't like the configuration in map either. The most simple way I accomplished this was writing a plugin for require.

Let's name the plugin mod, where it is to be used as mod!module/someModule, you can also call it index as in index!module/someModule, whatever suits you best.

define(function(require, exports, module) {
   // loading module/someModule/index.js with `mod!`      
   var someModule = require('mod!module/someModule');

   // whatever this is about ..
   module.exports = { .. };
});

So lets assume you have paths set in require's configuration with some sort of project structure:

- app
  - modules
    - someModule/index.js        // the index we want to load
    - someModule/..
    - someModule/..
    - etc
  - plugins
    - mod.js                     // plugin to load a module with index.js

Requires config:

require.config({
   paths: {
      'module': 'app/modules',

      // the plugin we're going to use so 
      // require knows what mod! stands for
      'mod': 'app/plugins/mod.js'
   }
});

To read all the aspects of how to write a plugin, read the docs at requirejs.org. The simplest version would be to just rewrite the name of the requested "module" you are attempting to access and pass it back to load.

app/plugins/mod.js

(function() {
    define(function () {
        function parse(name, req) {
            return req.toUrl(name + '/index.js');
        }

        return {
            normalize: function(name, normalize) {
                return normalize(name);
            },
            load:function (name, req, load) {
                req([parse(name, req)], function(o) {
                    load(o);
                });
            }
        };
    });
})();

This is not production code, it's just a simple way to demonstrate that requires config wasn't meant to solve problems like this.

like image 45
dbf Avatar answered Sep 26 '22 03:09

dbf