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)
Related
I always wondered how I can properly add the clientsided javascript in my express project. I use Typescript and I would also like to take advantage of the Typescript typings (for jquery for instance) when writing my clientside javascripts.
My project structure looks like this:
root
dist
src
helpers
models
registration
router.ts
form.pug
profile
router.ts
profile.pug
wwwroot
css
js
images
What I have done until today:
I created all clientsided javascript files in wwwroot/js (e.g. jquery.min.js, registration-form.js) and I loaded them into the header of the appropriate pages.
Disadvantages:
I had to write ES5 javascript which is compatible with the browsers we would like to support
I couldn't put the javascript files where they logically belong to (e. g. I'd rather put my registration-form.js into src/registration/ instead of the wwwroot)
No Typescript possible :(. No typescript typings, no transpiling to ES5 etc.
In some tutorials I saw they would simply run npm install --save jquery and import it in their clientsided files. So I feel like I must have missing some pretty important stuff, but I couldn't find any tutorials about it.
My question:
What is the "right way / best practice" to write clientsided javascript in Typescript / Express applications (which should also elliminate also the mentioned disadvantages)?
Using TypeScript on the client side is not much different from the server side.
Here is what you can do:
Create client folder for client-side typescript sources
Put tsconfig.json into client folder and configure it to produce "es5" code (target: es5)
Install jquery types (npm install --save-dev #types/jquery)
That's it, now you can write your client side code in TypeScript.
You can compile server-side code with tsc -p ./src (having server-side tsconfig.json under src) and compile client-side code with tsc -p ./client.
I made a simple example of such app, check it here. I put the simple script to build everything into package.json, so you can run npm run-script complie to get both server and client code complied into /dist folder. Then run it with npm start.
Further steps:
Automate your flow: you should be able to start your app locally and then just edit source TypeScript files and the app should be reloaded automatically. This can be done with webpack / gulp / grunt or custom shell script that can be triggered once any of your source file has been changed and saved.
If you find yourself writing good amount of client-side code, check also angular (https://angular.io/docs). It uses TypeScript as preferred language for client-side development and you'll be able to build much more powerful client-side app using it. You may choose another library as well (react, vue.js, etc), see the examples on the TypeScript site.
I tryed to use css frameworks lots of times. But i cant found any guide what to do. Just some post from other developers. Can you help me with the guide, how to import and use css framework in my expressjs project.
For instance, i started new project with express generator:
express --view=pug --css=sass
next, i installed materialize
npm install materialize-css
What i must to do next??? How to connect js and sass files with my project? How to compile all, if i tryed to do just a website? Where i can find good guides about such things, if i will have more questions?? Thanks!
npm was originally to get Node Module, but with the essort of the Javascript language (and the advent of browserify, webpack,etc), it has a bit grown up.
In fact, you can even download Bootstrap 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. Same goes for Webpack module bundler.
If you npm install bootstrap (if you don't use grunt or gulp file to move to a dist folder), your bootstrap will be located in some location like below.
"./node_modules/bootstrap/bootstrap.min.css"
You need to include this in your .html file.
For sass if you use grunt then you will be using this plugin grunt-sass to convert sass to css and add the destination file to the .html file. Similarly goes for gulp.
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.
is there a way I can use an npm package on the client side? For example, I want to use the dateformat(https://www.npmjs.com/package/dateformat) package in my client side javascript file
If you want to use npm on the client you may consider using browserify which is designed for that purpose. The node module system is not compatible with browsers so browserify transpiles the javascript into something that will work. Hence the name : browserify.
I found it wasn't enough to use Browserify. There were still issues with the client-side not finding the variables/functions from the library.
Here are the steps that worked for me:
Install Browserify:
npm install -g browserify
Install a library from npm (I'll use leader-line as an example):
npm i leader-line
You will now have all the npm files needed inside the node_modules directory:
Now we can run the usual Browserify command to bundle the JS file from the npm package:
browserify node_modules/leader-line/leader-line.min.js -o bundle.js
This will produce a bundle.js file outside of node_modules:
This is the file we can bring into the front-end, as we would with a usual JS library.
So, assuming I added my bundle.js file to a libs folder, and renamed bundle.js to leaderline.js, I can simply add the usual line in the header of my index.html file:
<script src="libs/leaderline.js" type="module"></script>
Notice the addition of type="module" to the script tag.
However, this is STILL not enough. The final step is to open the JS file for the library (in my case leaderline.js) and find the main function that needs to be exported (usually somewhere near the top):
var LeaderLine=function(){"use strict";var te,g,y,S,_,o,t,h,f,p,a,i,l,v="leader-line"
I need LeaderLine to be available inside my scripts. To make this possible, we simply remove var and add window. in front of the function name, like this:
window.LeaderLine=function(){"use strict";var te,g,y,S,_,o,t,h,f,p,a,i,l,v="leader-line"
Now I can use the library client-side without any problems:
HTML:
<div id="start">start</div>
<div id="end">end</div>
JS
new LeaderLine(
document.getElementById('start'),
document.getElementById('end')
);
Some will argue that exposing the function to the window is too "global" for best practices. But the other option is to use module bundlers, which handle the exposing of packages, and this is overkill for many applications, especially if you're trying to whip together a quick front-end to try something out.
I find it odd that so many now publish packages in npm, that are obviously intended for the front-end (e.g. obviously nobody would use leaderline.js in back-end node, yet this is where the package was published, with no available CDN).
Given how tortuous it is to expose front-end functionality from an npm package, one can argue that today's JS ecosystem is a mess.
Most of the packages on NPM are designed for server side and won't work on the client side because of security reasons. You could use NW.js, but the user would have to install your software on there computer.
"NW.js (previously known as node-webkit) lets you call all Node.js modules directly from DOM and enables a new way of writing applications with all Web technologies."
http://nwjs.io/
What is the correct way to include css and js files in express project ?
I am using ejs template engine. I have seen one example using connect-assetmanager but it was difficult to follow.
A small example project which includes css and js in index.ejs (not layout.ejs) would be very useful.
Static files can be served with express' static middleware. I usually make a directory for all static files to be served from the root.
If you've installed express globally with npm (npm install -g express) you can type the following at the command line.
express <project_name>
This will create a small example project for you. This example project has a folder named public, from which it serves static files. It further contains folders named javascripts and stylesheets.
The relevant piece of the example project for setting this up is the following line in the file app.js in the function passed to app.configure.
app.use(express.static(path.join(__dirname, 'public')));
Example is from express 3.0.0rc1
Express is built on Connect. The docs for it's static middleware might be helpful: Connect : Static