Loading local project static assets from CDN with RequireJS - node.js

I have a single page application with node serving up the backbone app along with all the marketing material. I would like to serve all assets (JS, html, images) from our Rackspace Cloudfiles CDN to reduce load times as gzip files will be delivered as well as reduce the load on my node server.
What is the best way to automate this?
I need would need to:
sync files after build to the CDN
reference the CDN for all static assets in production mode
I found solutions with both Grunt and Node Modules which are used in my project.
Grunt CDN
Grunt Cloud Files
Node Asset Rack
If I go with Grunt - which is my first choice,
How do I set the express application I am running on to serve from the CDN in production?
Is it better to use the asset manager for node since its serving all my assets anyway?

How do I set the express application I am running on to serve from the CDN in production?
When you render your view you could pass it a flag to tell where to pick the assets from.
I've got an example here if you are interested. In my case I've got a flag on whether I am connected to the network or not (e.g. during a flight) to decide where to pick my JS files from:
<% if(isConnected) { %>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular-resource.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular-cookies.min.js"></script>
<% } else { %>
<script src="/js/jquery.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
<script src="/js/angular.min.js"></script>
<script src="/js/angular-resource.min.js"></script>
<script src="/js/angular-cookies.min.js"></script>
<% } %>
https://github.com/hectorcorrea/hectorcorrea.com/blob/master/views/index.ejs#L136
In my example, the value is hard coded, but you could easily pass Express dev/prod value to the view to get the same thing done automatically.

Related

Intercept local requests to a remote server with Node.js

Using NodeJS, is it possible to listen to calls from localhost:3000 to my.site.com/resources/* and serve those files locally instead ?
Context: my Angular app relies on resources from a CDN. Sometimes when the CDN is down, I want to serve these files locally.
You can use javascript to check if angular object is correctly loaded , if not you generate a new tag a local link instead of CDN
<script src="//cdn_link/angular.min.js"></script>
<script>
(typeof angular != 'undefined') || document.write('<script src="local_link/angular.min.js")<\/script>')
</script>
For angular2 you can check for ng object instead of angular

How to set up React and Redux project without npm (Node.js)?

I have seen lot of videos and posts configuring project with npm (Node.js). I already have .Net server where I want to use React.JS and Redux.
I could set it up for React by adding following JS file downloaded.
<script src="~/Scripts/src/react.min.js"></script>
<script src="~/Scripts/src/react-dom.min.js"></script>
<script src="~/Scripts/src/browser.min.js"></script>
But how to include Redux in my application to use React with Redux?

How to use npm-installed bootstrap in express?

I 'm a beginner of Node.js development,
Now I try to use bootstrap framework in my first Express web app.
I use
npm install bootstrap
to download the files,and it seems that npm puts them in my node_modules folder.
My question is how can I refer to the bootstrap files in my views in express?
I know a typical way is copying the bootstrap file into the public folder. So my html files can find them. But I don't think this is a good idea.
Thank you.
You need to use in your server.js:
app.use(express.static(__dirname + '/node_modules/bootstrap/dist'));
to define a static resourse and then use:
<script language="javascript" src="js/bootstrap.min.js"></script>
<link rel="stylesheet" href="css/bootstrap.min.css"/>
I found a similar question. In which the solution is explained better by #augusto-goncalves. His solution works for me. It is similar to the solution of #victor-behar but more elaborated and clears confusion.
You have to reference it in the <script> and <link> tags in the header or at the bottom of your main script.
If you're using express, you're probably using templating. To use it in your header part or in your main template (depending on how you've managed your views) like :
<script language="javascript" src="node_modules/bootstrap/.../bootstrap.min.js"></script>
and
<link rel="stylesheet" href="node_modules/bootstrap/.../bootstrap.min.css"/>
This works only if you didn't moved your files with a gulp or a grunt task
There's also a way to transpile scss in express using node sass middleware, for example https://github.com/sass/node-sass-middleware.
That way you can override bootstrap scss. You can do the same for JS with webpack: transpile client-side js and then include the bundle.js in your frontend.

Node.js Express - Specifying path to root of app

I am trying to access a folder in my app that contains a few .js controller modules.
in the head of one of my .html files I have this script declared:
the problem is when the app is running, the application seems to know what the current path is, so the path to my script is not relative to the actual file system, it is relative to the current path of the app, which I might say is very strange.
So, the quick fix would be to easily specify the root of my application, since fancy_scripts is just one folder down from the root.
the following doesn't work, because of the problem I mentioned above
<head>
<script type="text/javascript" src="../fancy_scripts/userHomeController.js"></script>
</head>
but there has to be a way to specify the global root of the app with something like a double slash "//"
<head>
<script type="text/javascript" src="//fancy_scripts/userHomeController.js"></script>
</head>
(the above doesn't work either, // is the root in MS Windows (I think), but not an Express app) this is a straightforward problem, with I hope a straightforward solution. There might be a better way to do things however.
I have these 3 lines of code already:
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(__dirname + '/fancy_scripts'));
app.use('/fancy_scripts', express.static(__dirname + '/fancy_scripts'));
When using express, the path will be routed through one of your declared handlers or via the static module if you've set that up. Normally Express is configured to use static and to map it to your applications public folder. When using the express-generator that folder is located at <approot>/public/. So in order to access something like this:
<head>
<script type="text/javascript" src="/fancy_scripts/userHomeController.js"></script>
</head>
You'll need to put userHomeController in <approot>/public/fancy_scripts/userHomeController.js

RequireJS, Shim doesn't work correct when CDN failover occurs

I have the website, which is use intranet (small share) as well as on the internet (larger share). Intranet environment, doesn't have internet access. I was planning to load JavaScript from CDN for internet users, while using a local version for intranet user. I am using RequireJS library to dynamically load the scripts, and use failover, when it can't retrieve from the CDN.
I am using the following requireJS configuration to load jQuery library from CDN or use the local one.
Problem occurs, when RequireJS fails to load from CDN, it loads the bootstrap library prior of loading of local version of jquery. This cause two error, 'Bootstrap requires jQuery' from bootstrap and timeout error from requireJS.
My question, how to I avoid this? I want bootstrap to wait till any (CDN or local) version of jQuery is loaded. I have use Shim to define bootstrap dependency on jQuery library. But, it didn't work as anticipated. Is this known bug in requireJS?
Here, my configuration code
require.config({
paths: {
jquery: ['https://code.jquery.com/jquery-1.10.2'
, '/Scripts/_Ref/jquery-1.10.2'],
async: '/Scripts/_Ref/async',
propertyParser: '/Scripts/_Ref/propertyParser',
goog: '/Scripts/_Ref/goog',
bootstrap: '/Scripts/_Ref/bootstrap'
},
shim: {
'bootstrap': {
deps: ['jquery']
}
}
});
require.onError = function (err) {
console.log('RSC JS Error: ' + err.requireType);
if (err.requireType === 'timeout') {
var errorMessage = 'Following modules timeout: ' + err.requireModules;
console.log(errorMessage);
MyNamespace.ShowErrorMessage(errorMessage);
}
};
To demonstrate the problem, I have create a sample website, where I have block the internet and stimulate failover to occur.
Here, is the video link http://www.screencast.com/t/gcQ2I9aUdBY where I have shown problem in action
It sounds like CDN javascripts and RequireJS shims don't play well together. From the RequireJS documentation:
Do not mix CDN loading with shim config in a build. Example scenario:
you load jQuery from the CDN but use the shim config to load something
like the stock version of Backbone that depends on jQuery. When you do
the build, be sure to inline jQuery in the built file and do not load
it from the CDN. Otherwise, Backbone will be inlined in the built file
and it will execute before the CDN-loaded jQuery will load. This is
because the shim config just delays loading of the files until
dependencies are loaded, but does not do any auto-wrapping of define.
After a build, the dependencies are already inlined, the shim config
cannot delay execution of the non-define()'d code until later.
define()'d modules do work with CDN loaded code after a build because
they properly wrap their source in define factory function that will
not execute until dependencies are loaded. So the lesson: shim config
is a stop-gap measure for non-modular code, legacy code. define()'d
modules are better.
For explanations that are easier to understand, see this StackOverflow question.
We seem to have some luck not loading Bootstrap with RequireJS; instead, we're using script tags in <head>:
<script type="text/javascript" sync src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
// Load jQuery if CDN fails
window.jQuery || document.write('<script src="scripts/libs/jquery.min.js">\x3C/script>')
</script>
<script type="text/javascript" sync src="//maxcdn.bootstrapcdn.com/bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script type="text/javascript">
// Load bootstrap if CDN fails
window.jQuery.fn.dropdown || document.write('<script src="scripts/libs/bootstrap.min.js">\x3C/script>')
</script>
<script type="text/javascript">
var require = {
baseUrl: "scripts/",
deps: ['main']
};
</script>
<script type="text/javascript" src="scripts/libs/require/require.js"></script>
jQuery and Bootstrap are loaded from CDN's with local fallback per Hanselman.

Resources