I would like to rollout with Backbone.js + Require.js. I can load modules just fine. But when I try and load my .html files using the text! plugin (text.js), I get these errors:
Resource interpreted as Script but transferred with MIME type text/html: "https://host.net/templates/login.html". require.js:1843
Uncaught SyntaxError: Unexpected token < login.html:1
Uncaught TypeError: Cannot call method 'replace' of undefined underscore.js:1130
Here's the specs of what I'm working with:
Browser: Chrome
Server-Side: PHP w/ Slim
Machines: AWS micro-instance with bitnami AMI // These things ship with production defaults set, so it could be possible that an Apache config isn't right, or a php.ini isn't correct. I just don't know what.
Directory structure:
/
dev/ // Webroot: Behind basic_auth for dev reasons
web/
index.php // Starts up the Slim router and PHP backend
app/
app.html // The entry point for our SPA, data-main defined here
js/ // At root for module accessibility in case of reuse
apps/
app/
main.js // Here we do require.config and bootstrapping
app.js
router.js
text.js
modules/
models/
login.js
views/
login.js
lib/
backbone/
backbone.js
jquery/
jquery.js
require/
require.js
underscore/
underscore.js
templates/ // Also at root for access to reuseable markup, such as login.html
login.html
Here's some code I believe relevant:
/js/apps/app/main.js
requirejs.config({
baseUrl: '/js/apps/app',
shim: {
'backbone' : {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore' : {
exports: '_'
},
'jquery' : {
exports: '$'
},
'backbone.ajaxcommands' : {
deps : ['backbone', 'underscore', 'jquery'],
}
},
paths: {
jquery: 'lib/jquery/jquery-1.9.1.min',
underscore: 'lib/underscore/underscore',
backbone: 'lib/backbone/backbone-min'
},
config: {
text: {
useXhr: function (url, protocol, hostname, port)
{
protocol = 'https';
// return true;
}
}
}
});
require(['app'],function(App){
App.initialize();
App.start();
}
);
/js/apps/app/modules/views/login.js
define([
'backbone',
'underscore',
'modules/views/login',
'text!/templates/login.html'
], function(Backbone, _, Login, loginTemplate){
var LoginView = Backbone.View.extend({
el: $("#login-form"),
events: {
"click #login": "login"
},
template: _.template(loginTemplate),
initialize: function(){
var self = this;
this.username = $("#username");
this.password = $("#password");
this.username.change(function(e){
self.model.set({username: $(e.currentTarget).val()});
});
this.password.change(function(e){
self.model.set({password: $(e.currentTarget).val()});
});
},
login: function(){
var user= this.model.get('username');
var pword= this.model.get('password');
if(this.model.save() == false)
{
console.log("We got issues loggin' in");
}
else
{
console.log("We should have cookies now");
}
}
//render: function(){
// this.$el.append(this.template);
//}
});
return LoginView;
});
/templates/login.html
`<div>hi</div>`
Work to find solution: When I look at the Chrome debugger, under the 'network' tab, I see that indeed login.html was retrieved, but chrome thinks it's a JS file.
I stepped through the code using a breakpoint, and found that in Require.js 1843 the node object on that line has an attribute called 'outerHtml' equal to a '' tag with a bunch of attributes. So perhaps it is wrapping my html in a tag? When I look under the preview tab in the network tab of the debugger, I indeed see the markup. If login.html has valid js code, then I don't get the syntax error. I still get the underscore.js error because it's malformed html though.
I've tried these solutions: Chrome says "Resource interpreted as script but transferred with MIME type text/plain.", what gives?
Moving the js/template code under the project (made paths relative instead of absolute). Everything seemed to work, but text.js would append .js to the end of login.html, so I got a 404 not found. This is because of cross-domain access aparentally?
various config options with require.config, including setting the baseURL
tons of other tweaks that I have unfortunately forgotten. This has been really frustrating.
Thank you for your time.
Edit: I've put a stand-alone that exhibits the same behavior I'm seeing on my drive. The file structure should be:
/
index.html //This can actually be anywhere visible on the web
so-js/
...
so-templates/
...
notice that the so-js/ and so-templates are at the webroot, the index file can be where ever.