Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RequireJS: Why do relative paths work for define(), but not require()?

Tags:

requirejs

Let's say you have the following directory structure, and the following files:

root
|-- require-jquery.js
+-- folder
     |-- index.html
     |-- main.js
     +-- AnotherModule.js

In RequireJS, when you reference a module starting with a ".", RequireJS looks in the same folder that your current module is in, even if that's a subdirectory. However, if you change baseUrl just before calling define(), RequireJS will map dependencies to the new baseUrl.

You can fix this by setting baseUrl in index.html and changing data-main to a path relative to baseUrl:

folder/index.html:

<script>
    var require = {
        baseUrl : "../"
    };
</script>
<script data-main="folder/main" src="../require-jquery.js"></script>

folder/main.js:

define(
        [ "jquery", './AnotherModule' ],
        function($, AnotherModule) {});

This only works for define(), though:

folder/main.js:

require(
        [ "jquery", './AnotherModule' ],
        function($, AnotherModule) {});

if I try it with require(), RequireJS will look for AnotherModule.js in root, not folder. Why is this, and in particular, why the design difference between define() and require()?

like image 435
Chris Avatar asked Apr 18 '13 15:04

Chris


People also ask

What is define () in JS?

Advertisements. The define() function can be used to load the modules (module can be an object, function, class or a code which is executed after loading a module). You can load different versions of the same module in the same page.

Why do we need RequireJS?

RequireJS is a JavaScript library and file loader which manages the dependencies between JavaScript files and in modular programming. It also helps to improve the speed and quality of the code.

Is RequireJS asynchronous?

RequireJS, like LABjs, allows for asynchronous JavaScript loading and dependency management; but, RequireJS uses a much more modular approach to dependency definitions. This is just an initial exploration of RequireJS. RequireJS seems to be quite robust and includes optimization and "build" tools for deployment.

What is RequireJS Shim?

As per RequireJS API documentation, shim lets you. Configure the dependencies, exports, and custom initialization for older, traditional "browser globals" scripts that do not use define() to declare the dependencies and set a module value.


1 Answers

This is because define specifies a module name and require does not.

Define can be called like this:

define('folder/main',
        [ "jquery", './AnotherModule' ],
        function($, AnotherModule) {});

The first parameter is the module name - an explicit path to the module. Define() always implicitly specifies a path, and in general using an explicit path is not recommended. Require does not take a name parameter.

When you include a relative dependency in define() (like './AnotherModule'), it's found relative to the module name. In this case, ./AnotherModule would resolve to folder/AnotherModule.

In a call to require(), there is no module name. Relative dependencies are resolved to the root.

like image 90
Chris Avatar answered Sep 24 '22 17:09

Chris