RequireJS not honoring relative paths when not loaded at "mysite.com/" - javascript

I'm having some trouble with requirejs and relative paths.
This is in my HTML file:
<script data-main="/app/main.js" src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.1/require.js"></script>
My config is set up as follows:
requirejs.config({
baseUrl: '/vendor',
paths: {
// APP FILES
'app-base' : '../app',
'app-config' : '../config',
models : '../models', // where the models and collections are
templates : '../templates',
views : '../views',
lib : '../lib',
tasks : '../tasks',
router : '../app/router',
// VENDOR FILES
marionette : 'backbone.marionette',
},
deps: ['router'],
shim: {...}
});
When my app loads from the url "localhost:3000/" or "localhost:3000/applications" all of these paths resolve correctly. But when it's loaded from something like "localhost:3000/applications/app1", the paths resolve incorrectly.
The paths looks like this, respectively.
Correct:
"/models/test-model.js"
Incorrect:
"/applications/models/test-model.js"
I'm loading my modules using CJS as follows:
define( function( require ) {
var TestModel = require('models/test-model.js');
});
When I change the above to this --> var TestModel = require('/models/test-model.js');, it works. But this defeats the purpose of using relative paths.
Would love it if someone could help me out. I'm super confused.

When requiring a module, be sure to leave off the .js extension unless you are specifying a complete path.

Related

RequireJS: data-main won't load the file

I am simply converting my small project into nodejs. But for some reason, the requireJS file - the one where you define the JS you will use in your project is not loading.
Here is my structure ...
the ng-app is where I make the front-end for the site. I use gulp to process them into html and js and placed to ng-dist
Here is what my server.js file
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/ng-dist'));
app.listen(3000);
When I go to my browser, it is rendered just as expected.
But it appears that my require.js file is not being read as stated in the data-main attribute.
Here is what require.js file looks like.
require.config {
baseUrl :'app/'
paths : {
angular : '//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min'
ngRoute : '//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-route.min'
ngAnimate : '//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-animate.min'
router : 'routes'
directives : 'directives/ref'
services : 'services/ref'
coreModule : 'config'
jQuery : '//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min'
uikit : '//cdnjs.cloudflare.com/ajax/libs/uikit/2.21.0/js/uikit'
}
shim: {
ngRoute:{
deps:['angular']
},
ngAnimate:{
deps:['ngRoute']
},
coreModule:{
deps:['ngAnimate']
},
uiKit:{
deps:['jQuery']
}
}
}
define ['coreModule'], ->
This is basically the same thing in my PHP project. I don't have an idea why require is not reading my require.js file and load my scripts.
data-main is a RequireJS module to load. In Your case RequireJS try to load /require.js.js. Remove the extension, and rename the file to app.js (require.js is ambiguous). Finally:
<script data-main="app"
src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.17/require.min.js">
</script>

How to get the r.js build script working

I've read through the documentation and the example app.build.js file but just can't get my js files to concatenate and minify into one single file. I think I'm just not understanding exactly what settings I need in the build script and was hoping for some help.
My app is set up like this:
src >
js >
build.js
r.js
config.js
app >
main.js
lib >
module1.js
module2.js
module3.js
vendor >
require.js
jquery.js
jquery.validation.js
build >
// Where concat and minified file would go
config.js looks like this:
requirejs.config({
"baseUrl" : "src/js/lib", // Used because when setting dependencies in modules, this is used
"paths" : {
"app" : "../app",
"jquery" : [
"https://code.jquery.com/jquery-1.11.1.min",
"../vendor/jquery"
],
"validate" : "../vendor/jquery.validate.min"
},
"shim" : {
// Allow plugins with dependencies to load asynchronously
validate : ["jquery"]
}
});
// Load the main app module to start the app
requirejs(["app/main"]);
main.js looks like this:
require(["module1", "module2", "module3"], function(Module1, Module2, Module3) {
return [
Module1.init(),
Module2.init(),
Module3.init(),
Module4.init()
];
});
And then the build.js is where I'm lost. I thought I should load a mainConfigFile because I'm using the shim, but I'm not sure. If I do load that config file, it uses the baseUrl from that config file. I'm not sure what name: is supposed to refer to exactly and whether I'm missing some necessary configuration options.
({
//baseUrl: ".",
paths: {
jquery: "empty:",
//main: "../app/main",
//app: "app"
},
name: "app/main",
out: "../build/main.js",
//mainConfigFile: "config"
})
If I run that build file as it is (with those lines commented out) I get:
Error: ENOENT, no such file or directory
'/Users/davidpaul/Sites/require/src/js/module1.js' In module tree:
app/main
I'm not really sure what's being referred to when it says 'module tree'. I keep making changes to paths in the build file but not making progress so hoping for someone to explain this a bit to me.
The builder parses all paths relative to the build file location (unless changed via the baseUrl property). If you look relative to src/js/build.js, your main.js is in ./app/ and module1/2/3.js are in ./lib/. All paths inside modules have to be specified relatively to the common root, so to make your example work it's enough to change the signature of main.js to:
require(["lib/module1", "lib/module2", "lib/module3"], function(M1, M2, M3) {
// (...)
})
Note that config.js doesn't take part in the build process, you may need to change it as well to make your application work both "raw" and optimized.

Require JS files from bower_components by saying "require('library')" possible?

I'm new to RequireJS and it seems it might not actually be possible but I'll still go ahead and ask away in case I'm missing something.
In the docs it says..
This setup assumes you keep all your JavaScript files in a "scripts" directory in your project.
project-directory/
project.html
scripts/
main.js
helper/
util.js
But what if I have to require files from my bower installed files in bower_components:
project-directory/
bower_components/
jquery-mousewheel
jquery.mousewheel.js
lodash
dist
lodash.js
As you see, not all libraries have the same directory hierarchy and naming convention.
So I was wondering is there a simple way to require these bower libraries without actually knowing where their main files are, maybe by simply saying
require('jquery-mousewheel');
require('loadash');
?
setup your requirejs config to use paths
requirejs.config({
// ... config ...
paths: {
jquery-mousewheel: 'bower_components/jquery-mousewheel/jquery.mousewheel',
loadash: 'bower_components/lodash/dist/lodash'
}
// ... config ...
});
documentation for reference
I think this is a better solution...
requirejs.config({
baseUrl: 'bower_components/',
paths: { // path to your app
app: '../'
}
});
requirejs( [
'imagesloaded/imagesloaded',
'app/my-component.js'
], function( imagesLoaded, myComp ) {
imagesLoaded( '#container', function() { ... });
});

Related paths for dependencies in RequireJS define

In a requirejs module, i want to load some related files as dependencies. That files are in the same folder as module with define(). The module and related files maybe move to another location.
How can i set define's dependencies by related paths?
movableModule.js now:
define('movableModule', [
"changable/path/to/my/modules/relatedFile1",
"changable/path/to/my/modules/relatedFile2"
], function(){
console.log("movableModule loaded");
});
movableModule.js i want to be like this:
define('movableModule', [
"./relatedFile1",
"./relatedFile2"
], function(){
console.log("movableModule loaded relatively!");
});
As i know calling require.config and using baseUrl will change all routes in all modules, yes? and if no, i don't know how to use it in this case.
You should configure RequireJS to define your different paths.
Then you could request those module, just by their name :
require.config({
baseUrl: "/",
paths: {
"relatedFile1": "changable/path/to/my/modules/relatedFile1"
}
});
Then you'll be able to do :
define('movableModule', [
"relatedFile1"
], function(){
console.log("movableModule loaded");
});
Also, as mentionned in comments, you can define a partial path, and use it later for your incoming modules :
require.config({
baseUrl: "/",
paths: {
"modulePath": "changable/path/to/my/modules/"
}
});
And require your modules like that :
define('movableModule', [
"modulePath/module1",
"modulePath/module2"
], function(){
console.log("movableModule loaded");
});
Comment from the developer.

RequireJS loading of modules to be fixed based on ROOT URL + baseUrl + module path

Hi i'm using requirejs to just organize my javascript codes into AMD modules, i'm building a non-single page website right now using codeigniter, what i do is i have a default layout html file which i always call to render the dynamic content of the body so my script which call the requirejs and has the data-main attribute is encoded on my layout html page.
<script data-main="<?=base_url('assets/js/main.js');?>" src="<?=base_url('assets/js/require.js');?>"></script>
and my main.js looks like this.
requirejs.config({
baseUrl: "assets/js",
paths: {
jquery: 'vendor/jquery',
bootstrap: 'vendor/bootstrap',
datatables: 'vendor/jquery.dataTables'
},
shim: {
jquery: { exports: '$' },
datatables: { deps: ['jquery'] }
}
});
requirejs(['bootstrap','datatables'], function(){
})
so when i type on my url "localhost/ci-project/" it will load the layout page together with the dynamic body. On this scenario it works fine. sicne requirejs will render the path correctly "localhost/ci-project/assets/js/vendor/[js file/module]"
but when i change the URL to say, 'localhost/ci-project/welcome/admin'. what requirejs do to load the modules is concatenate the baseUrl + module path, to the current URL which in this case is 'localhost/ci-project/welcome/admin' and ending result is like this:
'localhost/ci-project/welcome/admin/assets/js/vendor/[module]' which is wrong.
so how can i configure requirejs to always load the from the root url and then concatenate the baseUrl value together with the paths of each modules?
The way to solve this is to output the baseUrl from a server side variable.
In your PHP page:
<script>
var require = {
baseUrl: '<?= base_url(); ?>' // Or whatever outputs the full path to your site root
};
</script>
<script data-main="<?=base_url('assets/js/main.js');?>" src="<?=base_url('assets/js/require.js');?>"></script>
Creating a require object before RequireJS is loaded allows you to define config options that will be picked up automatically.
Calling require.config() again from inside main.js is fine, it will just add the additional config options, but be sure to remove baseUrl from there.
Simon's answer above helped when I had issues with navigating to routes with parameters - relative paths to base url go wrong. I am using asp .net mvc, but the solution is exactly the same:
(_Layout.cshtml)
<script>
var require = {
// by default, load any module IDs from
baseUrl: '#Url.Content("~/Scripts/lib")'
}
</script>
<script data-main="#Url.Content("~/Scripts/application/app.js")" src="#Url.Content("~/Scripts/lib/require.js")"></script>

Categories