How Can I Place RequireJS Config in Separate File and Make the r.js Optimizer Work?
Asked Answered
C

1

8

Most examples for RequireJS setup, place the configuration object in the main.js entry point, something like this:

//main.js
require.config({
"paths": {
    //libs
    "lib1": "assets/js/lib/lib1",
    "lib2": "assets/js/lib/lib2",
    "lib3": "assets/js/lib/lib3",
    "lib4": "assets/js/lib/lib4"
    }
});
//start the app
define(["lib1"], function(lib1){/*start the app*/});

I prefer to place the configuration object in a separate file, because as it grows, it's difficult to maintain in the same file.

The following setup works when I run it in the browser, but for some reason I get an error when running the r.js optimizer:

//config.js
define({/*all configuration here*/});

//main.js
define(["config", "require"], function(config, require){
    requirejs.config(config); //set configuration
    require(["app"]); //launch app, where "app" path is defined in config.js
});

When I run r.js, I get the following error:

*Tracing dependencies for: main

Error: ENOENT, no such file or directory 'C:\Work\project\target\app.js*

So it seems that r.js doesn't get the configuration settings, because it's looking for app.js as a relative script, not as a module with a defined path.

Here is my build.js file (appDir, dir and mainConfigFile are relative to the build.js file):

({
    appDir: "../src",
    baseUrl: ".",
    dir: "../target",
    mainConfigFile: "../src/main.js",
    findNestedDependencies: true,
    modules: [
        {
            name: "main"
        }
    ]
})
Crissie answered 3/10, 2013 at 21:49 Comment(0)
O
7

This is how I am doing it. I like having the configuration file separate because I am reusing it in the tests.

Folder structure:

PROJECT
|
+- build (build output directory)
|
+- build-scripts (contains r.js, build.js)
|
+- WebContent
   |
   +- index.html (application main file)
   |
   +- scripts
      |
      +- require-cfg.js
      |
      +- main.js
      |
      +- ...

The configuration file (require-cfg.js - showing only the relevant stuff):

var require = {
    baseUrl: "scripts",
    paths: ...
    ...
};

The build file (build.js):

({
    appDir: "../WebContent/",
    baseUrl: "scripts/",
    mainConfigFile: "../WebContent/scripts/require-cfg.js",
    paths: {
        /* repeated from require-cfg.js */
    },
    dir: "../build",
    optimize: "uglify2",
    inlineText: true,
    removeCombined: true,

    name: "main"
})

Bootstraping code (index.html):

<script src="scripts/require-cfg.js"></script>
<script src="scripts/lib/require-2.0.2-jquery-1.10.2.js"></script>
<script src="scripts/main.js"></script>

I execute r.js with the build.js configuration inside the build-scripts folder. Optimized and combined output goes to the build folder. You can adapt the paths to suit your needs.

Olli answered 4/10, 2013 at 7:20 Comment(4)
Thanks, looks good. It's basically the same as I'm doing, but I am trying to keep 1 script tag in my index.html - namely, require.js. I see you are not using data-main, rather you are loading all the scripts separately. Is there a way to load require-config from the main.js using require? That way you could still keep it separate for the testsCrissie
I think using require to load require-cfg is a chicken-and-egg problem. I like loading require-cfg in a separate step, because it allows me to cusomize it (e.g. i18n) in place. And yes, 3 scripts are uglier than 1 script, but for me it is something I can live with.Olli
What's weird is that it works for me when I'm running locally in the browser. But when I run r.js, it doesn't. I can't seem to understand why. I can still load modules with require, without the paths defined, this is why I expect it to work.Crissie
The various approaches for using a shared require config are described at github.com/jrburke/requirejs/issues/354#issuecomment-6631063.Australia

© 2022 - 2024 — McMap. All rights reserved.