mdBootStrap and NodeJS Directory Structure Inquiry - node.js

I've read over the documentation and I cannot seem to find a clear answer as to the proper directory structure for a node application (insert downvotes here).
When I create an application directory off the root. All js, css, and img directories will be based of this application directory. My confusion comes in where when I install mdBootStrap using npm it creates the node_modules and mdbootstrap directory as expected, but then down these chains of directories it creates it's own js and css directory as well.
So back in the main application directory, in the HTML files, when I reference bootstrap and jquery files for example, am I forced to reference all the way down the node_modules directory, or has the mdBootStrap actually become my new application directory.

If you are using express you can expose your node_modules dependancy folder through your routing by adding a static route.
var application = express();
application.use('/mdbootstrap', express.static(__dirname + '/node_modules/mdbootstrap'));
Other options are using gulp build tasks to include the node_module dependancies in your output build.

Related

How to correctly setup folders / files in nodejs?

I am currently starting out in node.js and I am a bit confused with the folder/file setups. Let´s say I have a main folder where all my different projects are located, and those are folders too. Now where do I need to keep my node-modules folder? Also how about the package.json file, do I need that inside each project folder?
use npm init first
it will make a package.json file.
Install the dependencies which be stored in Node_modules folder
Now make a folder named Public
with subfolders assets, css, js, index.html -- the FrontEnd part

Copying node_modules or bower_components to static/public directory in web app

I am using a Node.js Express web server - I see some people using Grunt or Gulp scripts to copy the bower_components directory into the /public directory so those assets can be requested. Is there a better way to point to bower_components or node_modules than just copying files during a build?
You can always point to your bower components directly from HTML:
<script src="bower_components/jquery/dist/jquery.min.js"></script>
The reason people advise not to do this is because you might not want to copy your whole bower directory to the production environment. But you you can always preen the bower directory and have it only include the files you need before uploading to the production server, which means you can retain the paths in HTML as above.
Or you can copy the files you need to a place in your static directory, which is the more common approach, and with gulp/grunt it isn't all that cumbersome.
There are various tools available for all these tasks, there is a good list in Bower website's tools page, which will also give you an idea of the approaches people employ for this specific problem (and have therefore built tools for).
http://bower.io/docs/tools/
Yes you can also serve other folders like 'bower_componenets' in your Expressjs dir using:
app.use('/bower_components', express.static(path.join(__dirname, 'bower_components')));
You can use multiple static assets directory.
So you can define something like this:
app.use('/public', express.static(path.join(__dirname, 'public')));
app.use('/bower_components', express.static(path.join(__dirname, 'bower_components')));
Now express will first search for your requested asset in public dir if not found it will search in bower_components dir before sending 404 not found error.

Purpose of installing Twitter Bootstrap through npm?

Question 1:
What exactly is the purpose of installing Twitter Bootstrap through npm? I thought npm was meant for server side modules. Is it faster to serve the bootstrap files yourself than using a CDN?
Question 2:
If I were to npm install Bootstrap, how would I point to the bootstrap.js and bootstrap.css files?
If you NPM those modules you can serve them using static redirect.
First install the packages:
npm install jquery
npm install bootstrap
Then on the server.js:
var express = require('express');
var app = express();
// prepare server
app.use('/api', api); // redirect API calls
app.use('/', express.static(__dirname + '/www')); // redirect root
app.use('/js', express.static(__dirname + '/node_modules/bootstrap/dist/js')); // redirect bootstrap JS
app.use('/js', express.static(__dirname + '/node_modules/jquery/dist')); // redirect JS jQuery
app.use('/css', express.static(__dirname + '/node_modules/bootstrap/dist/css')); // redirect CSS bootstrap
Then, finally, at the .html:
<link rel="stylesheet" href="/css/bootstrap.min.css">
<script src="/js/jquery.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
I would not serve pages directly from the folder where your server.js file is (which is usually the same as node_modules) as proposed by timetowonder, that way people can access your server.js file.
Of course you can simply download and copy & paste on your folder, but with NPM you can simply update when needed... easier, I think.
The point of using CDN is that it is faster, first of all, because it is a distributed network, but secondly, because the static files are being cached by the browsers and chances are high that, for example, the CDN's jquery library that your site uses had already been downloaded by the user's browser, and therefore the file had been cached, and therefore no unnecessary download is taking place. That being said, it is still a good idea to provide a fallback.
Now, the point of bootstrap's npm package
is that it provides bootstrap's javascript file as a module. As has been mentioned above, this makes it possible to require it using browserify, which is the most likely use case and, as I understand it, the main reason for bootstrap being published on npm.
How to use it
Imagine the following project structure:
project
|-- node_modules
|-- public
| |-- css
| |-- img
| |-- js
| |-- index.html
|-- package.json
In your index.html you can reference both css and js files like this:
<link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.min.css">
<script src="../node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
Which is the simplest way, and correct for the .css files. But it is much better to include the bootstrap.js file like this somewhere in your public/js/*.js files:
var bootstrap = require('bootstrap');
And you include this code only in those javascript files where you actually need bootstrap.js. Browserify takes care of including this file for you.
Now, the drawback is that you now have your front-end files as node_modules dependencies, and the node_modules folder is usually not checked in with git. I think this is the most controversial part, with many opinions and solutions.
UPDATE March 2017
Almost two years have passed since I wrote this answer and an update is in place.
Now the generally accepted way is to use a bundler like webpack (or another bundler of choice) to bundle all your assets in a build step.
Firstly, it allows you to use commonjs syntax just like browserify, so to include bootstrap js code in your project you do the same:
const bootstrap = require('bootstrap');
As for the css files, webpack has so called "loaders". They allow you write this in your js code:
require('bootstrap/dist/css/bootstrap.css');
and the css files will be "magically" included in your build.
They will be dynamically added as <style /> tags when your app runs, but you can configure webpack to export them as a separate css file. You can read more about that in webpack's documentation.
In conclusion.
You should "bundle" your app code with a bundler
You shouldn't commit neither node_modules nor the dynamically built files to git. You can add a build script to npm which should be used to deploy files on server. Anyway, this can be done in different ways depending on your preferred build process.
Answer 1:
Downloading bootstrap through npm (or bower) permits you to gain some latency time. Instead of getting a remote resource, you get a local one, it's quicker, except if you use a cdn (check below answer)
"npm" was originally to get Node Module, but with the essort of the Javascript language (and the advent of browserify), it has a bit grown up. In fact, you can even download AngularJS on npm, that is not a server side framework. Browserify permits you to use AMD/RequireJS/CommonJS on client side so node modules can be used on client side.
Answer 2:
If you npm install bootstrap (if you dont use a particular grunt or gulp file to move to a dist folder), your bootstrap will be located in "./node_modules/bootstrap/bootstrap.min.css" if I m not wrong.
Use npm/bower to install bootstrap if you want to recompile it/change less files/test. With grunt it would be easier to do this, as shown on http://getbootstrap.com/getting-started/#grunt.
If you only want to add precompiled libraries feel free to manually include files to project.
No, you have to do this by yourself or use separate grunt tool. For example 'grunt-contrib-concat' How to concatenate and minify multiple CSS and JavaScript files with Grunt.js (0.3.x)

sails.js v0.10 create new project --linker not working Gruntfile.js not used

With the default version of sails on npm (v.9?) --linker works ok i.e. creates /linker folder. I can copy js, css files to assets/linker/ and they appear in layout.ejs automatically.
I now have sails v0.10 installed both locally and globally. Using Node V0.10.25.
I created a new sails project using:
sails new project_name --linker
but no /linker folder is created.
I had to create /.tmp as it did not exist
I had to create /.tmp/public/linker/ to put /js & /styles
and add them manually into layout.ejs
I renamed Gruntfile.js and my program still works thus Gruntfile does nothing in the program.
Sails v0.10 no longer uses the linker folder--it was just causing confusion. If you have the linker option enabled, then any assets under your assets folder will be copied over to your .tmp/public folder by Grunt when Sails is lifted. The public folder will be created by Grunt as necessary. The grunt-sync task will then keep the folders synced as long as the program is running.
Sails projects are not dependent on Grunt, so renaming the Gruntfile (or removing it completely) won't stop the program from working, but that doesn't mean it's not doing anything when it's there! To see what Grunt is up to, you can lift Sails with sails lift --verbose.
As an add-on to sgress454's answer, the reason a .tmp folder is created is so that files like the ejs and less files can be compiled into formats that your browser will understand. It's similar to the way that when you compile Java, it converts to Java bytecode (just an analogy, definitely not the same process).There doesn't necessarily have to be any .tmp folder when you're not running the server though; this is something Grunt creates and is what the browser reads from. Hope this clarifies things a bit more.

Does express.js create folder to mirror javascript files?

I've just checked out a nodejs-expressjs-boilerplate project. After I ran it I've discovered there are a lot of directories mirrored from root 'web/' to newly-created 'public/' directory.
I'm writing here because it looks this question is not covered well in the documentation (Or I'm bad at googling expressjs docs, sorry).
is that true that 'public/' directory in the project root contains copies of files inside 'web/...' directory?
When these copies are created?
Are javascript files from 'public/' executed or from 'web/'?
Do you experience the same behaviour? Is that expressjs feature or project-specific?
Why 'public/' directory is not in '.gitignore'?
Is that true that 'public/' directory in the project root contains copies of files inside 'web/...' directory
When these copies are created?
The Gruntile specifies that, yes. At build time files are compiled/copied.
This task is performed when you execute npm start, as you could see from package.json it calls grunt which executes its default task.
Are javascript files from 'public/' executed or from 'web/'?
In web you have .coffee files, those cannot be run in the browser, that is why there's the need for a dir that holds the compiled .js files.
Do you experience the same behaviour? Is that expressjs feature or project-specific?
This tasks are performed by Grunt, express could be used without these features, also without the Jade templates for instance. It depends on what you need.
Why 'public/' directory is not in '.gitignore'?
I honestly don't know, ask the author :D

Resources