I have the following simple structure:
index.html
...
<script src="static/js/lib/require.js" data-main="static/js/main"></script>
</head>
...
static/js/main.js
requirejs.config({
baseUrl: 'static/js',
paths: {
m: 'modules'
}
});
require(['m/test01'], function(test01) {
console.log(test01.print());
});
static/js/modules/test01.js
define(['m/test02'], function(test02){
return {
print: function() {
return 'test01 and '+ test02;
}
};
});
static/js/modules/test02.js
define(function() {
return 'test02';
});
Now when I open index.html directly (file:///index.html) all goes well. The script loading works and "test01 and test02" is logged in the console.
However, if I'm opening via xampp (localhost/requiretest/index.html) the loading of test01.js goes well, but for test02.js I get this error in the console (Firefox):
NetworkError: 404 Not Found - localhost/01-test-grunt/static/js/test02.js
(removed "http://" before localhost for stackoverflow)
As you can see the 'modules/' part is missing in the URL.
Anyone got any idea what might be going on?
NOTE: It does work when I change baseUrl to 'static/js/modules', but I can't do this because of my grunt buildprocess. Anyway, I assume other paths won't be loaded either, so is this a bug or am I doing something wrong?
Related
Am getting the above error in console on loading my application. My controller looks as below.Am new to angular so any help would be appreciated
Am trying to export the datatable into excel here. I think the issue is here angular.module('myApp','datatables', 'datatables.buttons'])
What is the correct way to include them in the module?
ViewCtrl.js
angular.module('myApp',['datatables', 'datatables.buttons'])
.controller('ViewCtrl', function($scope, DTOptionsBuilder, DTColumnDefBuilder) {
$scope.dtOptions = DTOptionsBuilder.newOptions()
.withPaginationType('full_numbers')
.withDisplayLength(2)
.withDOM('pitrfl')
.withButtons([{
extend: 'excelHtml5',
}
]);
vm.dtColumnDefs = [
DTColumnDefBuilder.newColumnDef(0),
DTColumnDefBuilder.newColumnDef(1).notVisible(),
DTColumnDefBuilder.newColumnDef(2).notSortable()
];
});
Verify the console loads. If the console.log does not show and you still get the inject error, then your problem is likely the datatables and datatables.buttons. Verify that these files are added to your index.html file prior to this file.
angular.module('myApp', ['datatables', 'datatables.buttons'])
.controller('ViewCtrl', function ($scope) {
console.log("Code of awesomeness");
});
If you find that you do see the console.log("Code of awesomeness"); Then your $inject issue is DTOptionsBuilder, DTColumnDefBuilder. Verify spelling.
I'm pretty new to require.js and having problems loading i18next.js.
main.js
require(["lib/jquery", "lib/i18next", "config.i18next", "constants"],
function(util) {
console.log("loaded javascript files");
});
and config.i18next.js
var option = {resGetPath: '../translations/__lng__.json' };
i18n.init(option, function(t) {
console.log("Language initialization successfull");
});
I always get the error
Uncaught ReferenceError: i18n is not defined config.i18next.js:2
I know who to use i18next, and everything works fine when loading the javascript files traditionally.
EDIT:
Meanwhile I got it working with shim like this:
requirejs.config({
shim: {
'lib/i18next' : ['lib/jquery'],
}
});
require(["lib/i18next"], function(i18n) {
var options = {
resGetPath: 'translations/__lng__.json',
preload: ['de', 'en']
};
i18n.init(options, function(t) {
});
});
and I can translate in other files with $.t("key"); , but when now I can't change the language programatically with i18n.setLng() because the variable can't be found ReferenceError: Can't find variable: i18n.
--- i18next comes now with amd build ---
this should solve all issues using i18next with amd. you can grab it at http://i18next.com
I am using requirejs for a multipage application. I am having a weird issue with the order of execution of the main files. Here is my setup.
In all of my html pages ( This main has all the common js files that are required by all my pages)
then on each page (say page1.html):
<script data-main="main" src="require.js" />
<script>
require(['require','main'],function(require) {
require(['main-library']);
});
</script>
My main.js looks like:
require.config({
paths:{
'lib':'../lib',
'jquery': '../lib/jquery/jquery-1.7.1.min',
'jquery.iframe-transport' : '../lib/jquery.iframe-transport.min.js'
},
deps:['jquery','jquery-ui'],
shim: {
<other shim files>
},
});
require([<list of all other dependencies>], function() {
});
And the main-library.js looks like:
define('main-library',
['main',
'jquery.iframe-transport',
<other dependencies>
],
function() {
}
);
My expectation:
Was that the "main-library" will not start to load until the "main" and all the dependencies specified in the main are not loaded. I expect this since I require "main-library" in a nested require call on each page. see above.
The issue:
When my page1.html loads, it looks like the main-library.js starts loading even before the main.js has finished loading and main-library fails to get the require.config and hence the paths for the dependencies are not seen by it.
What am I doing wrong ?
Answering my own question. It was infact another require down in that page1.html that was loading the "main-library" again. So I had something like:
<script data-main="main" src="require.js" />
<script>
require(['require','main'],function(require) {
require(['main-library']);
});
</script>
...
... Other html ...
...
<script>
require(['main-library'],function(require) {
//do something.
});
</script>
This second require on main-library was the one that was failing to find the paths. Wrapping it with a require on main worked.
codes in file main.js is like this:
phantom.injectJs("libs/require-1.0.7.js");
require.config(
{
baseUrl: ""
}
);
require([], function(){});
when i run "phantomjs main.js" in the commandline, requirejs doesn't work well in the main.js. I know how to use requirejs in the page running in the browser(including phantomjs' way: page.open(url, callback)), but not like above. I tries using requirejs like the main.js, it is a popular problem, i think. Thank you!
I just struggled for some time. My solution is not clean, but it works, and I'm happy with that due to the unfinished api documentation from phantomjs.
Wordy explanation
You need three files. One is your amd phantomjs test file which I'll call "amd.js". The second is your html page to load which I'll name "amd.html". Finally the browser test which I called "amdTestModule.js".
In amd.html, declare your script tag per normal:
<script data-main="amdTestModule.js" src="require.js"></script>
In your phantomjs test file, this is where it gets hacky. Create your page, and load in the 'fs' module. This allows you to open a relative file path.
var page = require('webpage').create();
var fs = require('fs');
page.open('file://' + fs.absolute('tests/amd.html'));
Now since requirejs loads files asynchronously, we can't just pass in a callback into page.open and expect things to go smoothly. We need some way to either
1) Test our module in the browser and communicate the result back to our phantomjs context. Or
2) Tell our phantomjs context that upon loading all the resources, to run a test.
#1 was simpler for my case. I accomplished this via:
page.onConsoleMessage = function(msg) {
msg = msg.split('=');
if (msg[1] === 'success') {
console.log('amd test successful');
} else {
console.log('amd test failed');
}
phantom.exit();
};
**See full code below for my console.log message.
Now phantomjs apparently has an event api built in but it is undocumented. I was also successfully able to get request/response messages from their page.onResourceReceived and page.onResourceRequested - meaning you can debug when all your required modules are loaded. To communicate my test result however, I just used console.log.
Now what happens if the console.log message is never ran? The only way I could think of resolving this was to use setTimeout
setTimeout(function() {
console.log('amd test failed - timeout');
phantom.exit();
}, 500);
That should do it!
Full Code
directory structure
/projectRoot
/tests
- amd.js
- amdTestModule.js
- amd.html
- require.js (which I symlinked)
- <dependencies> (also symlinked)
amd.js
'use strict';
var page = require('webpage').create();
var fs = require('fs');
/*
page.onResourceRequested = function(req) {
console.log('\n');
console.log('REQUEST');
console.log(JSON.stringify(req, null, 4));
console.log('\n');
};
page.onResourceReceived = function(response) {
console.log('\n');
console.log('RESPONSE');
console.log('Response (#' + response.id + ', stage "' + response.stage + '"): ' + JSON.stringify(response, null, 4));
console.log('\n');
};
*/
page.onConsoleMessage = function(msg) {
msg = msg.split('=');
if (msg[1] === 'success') {
console.log('amd test successful');
} else {
console.log('amd test failed');
}
phantom.exit();
};
page.open('file://' + fs.absolute('tests/amd.html'));
setTimeout(function() {
console.log('amd test failed - timeout');
phantom.exit();
}, 500);
amd.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<script data-main='amdTestModule.js' src='require.js'></script>
</body>
</html>
amdTestModule.js
require([<dependencies>], function(<dependencies>) {
...
console.log(
(<test>) ? "test=success" : "test=failed"
);
});
console
$ phantomjs tests/amd.js
amd test successful
you are misunderstanding webpage.injectJs()
it's for injecting scripts into the page you are loading, not into the phantomjs runtime environment.
So using .injectJs() is making requirejs load up into your page, not into phantomjs.exe.
That said, phantomjs's runtime environment has an aproximation of commonjs. RequireJs will not run on there by default. If you felt especially (VERY) motivated, you could attempt porting the require-shim made for nodejs, but it doesn't work out of the box, and would require an incredibly deep understanding of the runtimes. for more details: http://requirejs.org/docs/node.html
a better idea:
probably you should make sure you have commonjs versions of your javascript you wish to run. i personally write my code in typescript so i can build for either commonjs or amd. i use commonjs for phantomjs code, and amd for nodejs and browser.
Can I have the following config in route/index.js ?
exports.PageA = function(req, res) {
...
...
if(req.method == 'GET') {
if (condition1) {
//PageA has 2 .js files
res.render('PageA', { title: 'A', layout: false});
}
else {
//PageB has 2 + 2 .js files
res.render('PageB', { title: 'B', layout: false});
}
}
else {
res.render('PageC', { title: 'B', layout:'some_other_layout' });
}
};
Case: mywebsite.com/PageA renders correctly when condition1 passes (with all scripts loaded and executed correctly)
Issue : But when condition1 fails, I get PageB rendered, javascripts in PageB.ejs are rendered but not executed, say, on $document.Ready().
Strangely if I 'Refresh' the already rendered PageB in browser, javascripts are then executed correctly.
As a piece of info: I use defer="defer" tag in all "< script >..."
What am I missing here?
Your problem is entirely on the client side. Attribute "defer" supported only in Internet Explorer and Firefox at this moment. I think your problem is that the scripts are loaded in the wrong sequence. Check your browser console for errors. When you re-load a page, the scripts are loaded from the browser cache. It's faster. Therefore, the error may not appear in this situation.