Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RequireJS paths config

My development config (in "index.html" file) for RequireJS is:

<script src="require-2.1.5.min.js"></script>
<script>
    require.config({
        baseUrl: 'js',
        paths: {
            angular: 'libraries/angular-1.1.5.min',
            jquery: 'libraries/jquery-2.0.0.min',
            underscore: 'libraries/underscore-1.4.4.min',
            ...
            zeroclipboard: 'plugins/zeroclipboard-1.0.7.min',
            tablesorter: 'plugins/jquery.tablesorter-2.9.1.min',
            ...
        },
        shim: {
            'angular': {
                exports: 'angular'
            },
            'underscore': {
                exports: '_'
            }
        },
        packages: [
            {
                name: 'index',
                location: 'app/index',
                main: 'main'
            }
        ]
    });

    require(['index']);
</script>

But on production I have only 2 concatenated files for libraries and plugins:

js/libraries.js // all jQuery, AngularJS, RequireJS, Underscore and other libraries concatenated
js/plugins.js // all plugins (already an AMD modules, no need for "shim" config) concatenated

So, how do I write my config "paths" now? I don't have any 'libraries/angular-1.1.5.min.js' and other paths.

My solution is to write:

    paths: {
        angular: 'libraries',
        underscore: 'libraries'
    }

I associate AngularJS and Underscore to 'libraries.js' file and everything works perfect. (No need for jQuery and all plugins — they are already an AMD modules).

But is that a right way to write paths? My solution seems to me kinda dirty workaround, not the best practices solution.

My r.js build process:

({
baseUrl: 'scripts',
paths: {
    jquery: 'jquery-2.0.0.min',
    ...
    tablesorter: 'jquery.tablesorter-2.0.5.min',
    zeroclipboard: 'zeroclipboard-1.0.7.min'
},
name: 'foo/main',
exclude: [
    'angular',
    'jquery',
    ...
    'tablesorter',
    'zeroclipboard'
],
optimize: 'uglify',
out: 'production/js/foo.js'
})

UPD 1:

What I want:

www.mysite.com/about.html:

<script src="js/libraries.js"></script><-- jQuery (already AMD), AngularJS (not AMD), RequireJS, Underscore (not AMD) and other libraries already here, only 1 http request needed //-->
<script src="js/plugins.js"></script><-- all AMD //-->
<script>
    require.config({
        baseUrl: 'js',
        paths: {
            angular: WHAT I NEED TO WRITE HERE?,
            underscore: WHAT I NEED TO WRITE HERE?
        },
        shim: {
            'angular': {
                exports: 'angular'
            },
            'underscore': {
                exports: '_'
            }
        },
        packages: [
            {
                name: 'about',
                location: 'js',
                main: 'about'
            }
        ]
    });

    require(['about']); // will load "js/about.js"
</script>

UPD 2:

Ok, it is clear about "priority", so, I don't need for first and second «script» tags (but I need to separate "Require.js" from "libraries.js") — RequireJS will load them automatically. But what should be done with non-AMD libraries in "libraries.js" file?

AngularJS and UnderscoreJS are non-AMD modules, that is why I have to use "shim", right? But to make "shim" work, I need to use "paths" also, so "shim" can locate shimmed modules, right? But I still have only 1 file — "libraries.js" and I cannot write it in "path" option… Just really stuck…

like image 240
artuska Avatar asked May 29 '13 23:05

artuska


People also ask

What is RequireJS config?

Advertisements. RequireJS can be initialized by passing the main configuration in the HTML template through the data-main attribute. It is used by RequireJS to know which module to load in your application. For instance − <script data-main = "scripts/main" src = "scripts/require.js"></script>

Is RequireJS obsolete?

RequireJS has been a hugely influential and important tool in the JavaScript world. It's still used in many solid, well-written projects today.

What is the difference between RequireJS CommonJS and AMD loaders?

RequireJS is probably the most popular implementation of AMD. One major difference from CommonJS is that AMD specifies that modules are loaded asynchronously - that means modules are loaded in parallel, as opposed to blocking the execution by waiting for a load to finish.

What is Shim RequireJS?

shim: 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. Here is an example. It requires RequireJS 2.1. 0+, and assumes backbone. js, underscore.


2 Answers

In order to have common library code preloaded you should use the priority config option. you could put something like this in your foo/main.js file

require.config({
    priority: ["libraries", "plugins"]
});

And then your build file could look like this. The libraries and plugins file should contains a define statement that define all dependencies that are considered general / download once.

({
    baseUrl: 'scripts',
    paths: {
        jquery: 'jquery-2.0.0.min',
        ...
        tablesorter: 'jquery.tablesorter-2.0.5.min',
        zeroclipboard: 'zeroclipboard-1.0.7.min'
    },
    modules: [
        {
            name: 'foo/main'
            excludes: ...
        },
        {
            name: 'libraries'
        },
        {
            name: 'plugins'
        }
    ],
    optimize: 'uglify',
    out: 'production/js/foo.js'
})
like image 192
Willem D'Haeseleer Avatar answered Oct 16 '22 08:10

Willem D'Haeseleer


You should use same configuration for both environments. And this configuration that you have should be in the external file. When you optimize it using r.j, all modules already in that single file so RequireJS will just use them without loading. Seems like you need to tune your build process.

Checkout my recent blog post about it.

like image 22
Tomas Kirda Avatar answered Oct 16 '22 07:10

Tomas Kirda