Setting up an NPM-based development environment
The simple setup demonstrated in the previous recipe is enough for implementing most recipes in this book. However, when you work on a more complex data visualization project that requires the use of a number of JavaScript libraries, the simple solution we discussed before might become a bit clumsy and unwieldy. In this section, we will demonstrate an improved setup using Node Packaged Modules (NPM), a de facto JavaScript library repository management system. If you are as impatient as me and want to get to the meaty part of the book, the recipes, you can safely skip this section and come back when you need to set up a more production-ready environment for your project.
Getting ready
Before we start, please make sure that you have NPM properly installed. NPM comes as part of the Node.js installation. You can download Node.js from https://nodejs.org/
. Select the correct Node.js binary build for your OS. Once installed, the following npm
command will become available in your terminal console:
> npm -v 2.15.8
The preceding command prints out the version number of your NPM client to indicate that the installation is successful.
How to do it...
With the NPM installed, we can now create a package descriptor file to automate some of the manual setup steps:
- First, under your project folder, create a file named
package.json
that contains the following code:Â Â Â { Â Â Â ""name": "d3-project-template", Â Â Â ""version": "0.1.0", Â Â Â "description": "Ready to go d3 data visualization project template", Â Â Â "keywords": [ Â Â Â "data visualization", Â Â Â "d3" Â Â Â ], Â Â Â "homepage": "<project home page>", Â Â Â "author": { Â Â Â "name": "<your name>", Â Â Â "url": "<your url>" Â Â Â }, Â Â Â "repository": { Â Â Â "type": "git", Â Â Â "url": "<source repo url>" Â Â Â }, Â Â Â "dependencies": { Â Â Â "d3":"4.x" Â Â Â }, Â Â Â "devDependencies": { Â Â Â "uglify-js": "2.x" Â Â Â } Â Â Â }
- Once the
package.json
file is defined, you can simply run the following:Â Â Â > npm install
How it works...
Most of the fields in the package.json
file are for informational purpose only, such as its name, description, home page, author, and the repository. The name and the version fields will be used if you decide to publish your library into an NPM repository in the future. What we really care about, at this point, are the dependencies
and devDependencies
fields:
- The
dependencies
field describes the runtime library dependencies that your project has, that is, the libraries your project will need to run properly in a browser. - In this simple example, we only have one dependency on D3.
d3
is the name of the D3 library that is published in the NPM repository. The version number4.x
signifies that this project is compatible with any of the version 4 releases, and NPM should retrieve the latest stable version 4 build to satisfy this dependency.
Note
D3 is a self-sufficient library with zero external runtime dependency. However, this does not mean that it cannot work with other popular JavaScript libraries. I regularly use D3 with other libraries to make my job easier, for example, JQuery, Zepto.js, Underscore.js, and ReactJs to name a few.
- The
devDependencies
field describes development time (compile time) of library dependencies. What this means is that libraries specified under this category are only required in order to build this project, and not required to run your JavaScript project.
Note
Detailed NPM package JSON file documentation can be found at https://docs.npmjs.com/files/package.json .
Executing the npm install
command will automatically trigger NPM to download all dependencies that your project requires, including your dependencies' dependencies recursively. All dependency libraries will be downloaded into the node_modules
folder under your project's root folder. When this is done, you can just simply create your HTML file as shown in the previous recipe, and load your D3 JavaScript library directly from node_modules/d3/build/d3.js
.
The source code for this recipe with an automated build script can be found at https://github.com/NickQiZhu/d3-cookbook-v2/tree/master/src/chapter1/npm-dev-env .
Relying on NPM is a simple and yet more effective way to save yourself from all the trouble of downloading JavaScript libraries manually and the constant need for keeping them up to date. However, an astute reader may have already noticed that with this power we can easily push our environment setup to the next level. What if you are building a large visualization project where thousands of lines of JavaScript code will be created? Then obviously, our simple setup described here will no longer be sufficient. However, modular JavaScript development by itself can fill an entire book; therefore, we will not try to cover this topic since our focus is on data visualization and D3. In later chapters, when unit test-related recipes is discussed, we will expand the coverage on this topic to show how our setup can be enhanced to run automated build and unit tests.
Tip
D3 v4.x is very modular; so if you only need a part of the D3 library for your project, you can also selectively include D3 submodule as your dependency. For example, if you only need d3-selection
module in your project, then you can use the following dependency declaration in your package.json
file:
"dependencies": {
   "d3-selection":"1.x"
}
There's more...
Although in previous sections it was mentioned that you can just open the HTML page that you have created using your browser to view your visualization result directly, this approach does have its limitations. This simple approach stops working once we  need to load data from a separate data file (this is what we will do in later chapters, and it is also the most likely case in your daily working environment) due to the browser's built-in security policy. To get around this security constraint, it is highly recommended that you set up a local HTTP server so your HTML page and the data file can be accessed from this server instead of being loaded from a local file system directly.
Setting up a local HTTP server
There are probably more than a dozen different ways to set up an HTTP server on your computer based on the operating system you use and the software package you decide to use to act as an HTTP server. Here, I will attempt to cover some of the most popular setups.
Python Simple HTTP server
This is my favorite for development and fast prototyping. If you have Python installed on your OS, which is usually the case with any Unix/Linux/Mac OS distribution, then you can simply type the following command in your terminal with Python 2:
> python -m SimpleHTTPServer 8888
Alternatively, type the following command with Python 3 distribution:
> python -m http.server 8888
This little python program will launch an HTTP server and start serving any file right from the folder where this program is launched. This is by far the easiest way to get an HTTP server running on any OS.
Note
If you don't have python installed on your computer yet, you can get it from https://www.python.org/getit/ . It works on all modern OS, including Windows, Linux, and Mac.
Node.js HTTP server
If you have Node.js installed, perhaps as part of the development environment setup exercise we did in the previous section, then you can simply install the http-server
module. Similar to the Python Simple HTTP Server, this module will allow you to launch a lightweight HTTP server from any folder and start serving pages right away.
First, you need to install the http-server
module using the following command:
> npm install http-server -g
The -g
option in this command will install http-server
module globally, so it will become available in your command-line terminal automatically. Once this is done, you can launch the server from any folder you are in by simply issuing the following command:
> http-server -p 8888
This command will launch a Node.js-powered HTTP server on the default port 8080
, or if you want, you can use the -p
option to provide a custom port number for it.
Note
If you are running the npm install
command on Linux, Unix, or Mac OS, you may need to run the command in the sudo
mode or as root in order to use the -g
global installation option.