[node.js] 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?

This question is related to node.js twitter-bootstrap express npm cdn

The answer is


  1. 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.

  2. 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.

  1. You should "bundle" your app code with a bundler
  2. 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.

  1. 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.

  2. 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)


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.


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.


Examples related to node.js

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean`

Examples related to twitter-bootstrap

Bootstrap 4: responsive sidebar menu to top navbar CSS class for pointer cursor How to install popper.js with Bootstrap 4? Change arrow colors in Bootstraps carousel Search input with an icon Bootstrap 4 bootstrap 4 responsive utilities visible / hidden xs sm lg not working bootstrap.min.js:6 Uncaught Error: Bootstrap dropdown require Popper.js Bootstrap 4 - Inline List? Bootstrap 4, how to make a col have a height of 100%? Bootstrap 4: Multilevel Dropdown Inside Navigation

Examples related to express

UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block jwt check if token expired Avoid "current URL string parser is deprecated" warning by setting useNewUrlParser to true MongoNetworkError: failed to connect to server [localhost:27017] on first connect [MongoNetworkError: connect ECONNREFUSED 127.0.0.1:27017] npm notice created a lockfile as package-lock.json. You should commit this file Make Axios send cookies in its requests automatically What does body-parser do with express? SyntaxError: Unexpected token function - Async Await Nodejs Route.get() requires callback functions but got a "object Undefined" How to redirect to another page in node.js

Examples related to npm

What does 'x packages are looking for funding' mean when running `npm install`? error: This is probably not a problem with npm. There is likely additional logging output above Module not found: Error: Can't resolve 'core-js/es6' Browserslist: caniuse-lite is outdated. Please run next command `npm update caniuse-lite browserslist` ERROR in The Angular Compiler requires TypeScript >=3.1.1 and <3.2.0 but 3.2.1 was found instead DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean` What exactly is the 'react-scripts start' command? On npm install: Unhandled rejection Error: EACCES: permission denied Difference between npx and npm?

Examples related to cdn

Purpose of installing Twitter Bootstrap through npm? Cloudfront custom-origin distribution returns 502 "ERROR The request could not be satisfied." for some URLs Bootstrap 3 Glyphicons CDN Best way to use Google's hosted jQuery, but fall back to my hosted library on Google fail Downloading jQuery UI CSS from Google's CDN