Member preview

Overcoming Fear of package.json — Building Server-Side JavaScript Apps

Setting Up Development Environment

Setting up a Development Environment makes server-side applications distinct from their front-end counterpart. It’s easy to get lost especially if you’re working with libraries such as React for the first time.

We learned that in post-ES2015 era even JavaScript, a language that was primarily invented as a front-end development tool, is moving to the server-side. I’d say that this is the prevalent bias in the industry that started to become evident around 2016.

We must understand how server-side JavaScript works. I know this creates a bit of a hassle, but it’s sort of a necessary step. Because this is the future of JavaScript application development. Most likely that future is right now.

Build Environment

We can refer to development environment as “build” environment interchangeably. Because essentially a development environment is a system whose ultimate purpose is to provide the means for building your application.

Some programmers simply say things like “How did you build your application?” or “What are your favorite dependencies?” referring to your custom build.

You can use node, yarn and webpack packages to build your app. But we’ll take a look at how to use them a bit later in this tutorial.

Because with node and npm we are now working on server-side of things you will use these tools to install and uninstall various packages on demand. This conglomerate of various packages is what determines the essence of your build.

And this “how” is what many JavaScript developers who came from traditional pre-Millennial background are not familiar with. Thankfully after parsing through the previous tutorials on my Medium account we now understand the process at least at its basic. It’s not so hard after all is it?

The next natural step that completes setting up a development environment for working with React (or other server-side JavaScript libraries and/or frameworks) is setting up its configuration.

Build configuration drastically varies from one person to another. At one company things are configured are a certain way. Others prefer a different setup. These decisions can be often made mutually by an entire development team.

However, when working with React understanding package.json configuration file is a must at the very least. There is no way around it. So let’s take a look.

Configuring Your Build Environment With <package.json>

If you’ve been struggling with setting up React and gave up at configuration file this might be the place at which you and many JavaScript programmers turn to Vue.js framework. Because it is easier to set up. But don’t give up so easily!

Once you understand package.json, choose and set up the right packages for your application building React projects will become second nature. In the olden days we typed JavaScript in a text file and it just worked. But it is so much worth it walking the extra mile to figure this out now and ease into the world of React. This guide here will help you get started.

Again, I cannot possibly describe every nook and cranny of this process. In reality the only way to truly understand and get into server-side builds is to spend many hours actually working with the command line.

In fact, a lot of the time when being introduced to a build configuration on a project you’ve never worked on before, you may feel slightly disoriented. What are all those packages? What do they do? What concrete functionality or features they add to the application?

To determine a list of all packages you want to use in your project there is a package.json file. This file shows a list of nested dependencies. Why are they called this way? Well, every single library you add to your application (usually not written by you) will literally make your own application depend on it. That might sound worrying at first, just by reading that word.

And yes, in many cases it is. What if the version of the installed dependency changes? What if it breaks core functionality that your code already depends on? It will break your build. For this reason keeping an old version of a library is a common strategy among developers as tempting as it may be to always upgrade to latest. Which, in my personal opinion is what you should be doing. We’ll see how yarn solves this problem a bit later on in the book. But for now, let’s take a look at how to properly set up package.json file for your development environment.

Dependencies can be frightening. Because ultimately these packages often continue to change with each and every new release. And yes you can write your own code that accomplishes the same task and stop worrying! But reality is that most developers download about 80% of their base code from Node package repository.

With so many great and well-established libraries (axiom for working with relational database) already written all you have to do is include one and start using it. Of course all of this means that choosing the best packages is essential. And as you dive deeper into the world of professional web development you might just find out what they are.

Example of <package.json> Configuration File

In this section we’ll take a look at package.json file and break it down into understandable parts. It follows the JSON format notation, which means every key/value pair must be specified in quotation marks, and separated by a colon.

Below is an example of one possible build configuration.

The major differences between different package.json configuration files for different builds is in what’s specified under “scripts” and “dependencies” keys.

Each build is different. The example shown here is by no means the absolute way of setting up your project. It’s only somewhat of a bare minimum config. You may or may not need other dependencies. Treat it as a mere first time example.

Let’s take a look at one potential scenario.

Basic details are stored first: your project name, version number and description. You can also specify license of your module. Do not use spaces in “name”. You can use either dash or underscore to separate multiple words.

{
“name”
: module-name,
“version” : “1.0.0”,
“description” : “Amazing project.”,
“license” : “MIT”,

Next, branch out into a nested JSON to specify author of the project:

    “author” : {
“name”
: “Amazing Programmer”,
“email” : “wonderful@gmail.com”,
},

In package.json file “keywords” are used for helping people find your package. Unfortunately at the moment of this writing keywords are case-sensitive. For example React is not the same as react. Most packages are specified using lower-case characters.

    “keywords”: [
“react”
,
“redux”,
“example”
]
,

Main JavaScript file for this project. When calling require({ module-name }); in node, this is the actual file that will be included:

    “main” : “index.js”,

Homepage of your project:

    “homepage” : “http://module-name.js.org/",

Specify your repository type and URL address:

    “repository”: {
“type” : “git”,
“url” : “https://github.com/amazing-coder/module-name"
},

The “dependencies” key is perhaps the most important value in entire package.json file. It includes dependencies. Other packages your module relies on. Each dependency must also specify version number.

There are a few different version specifiers you can use:

Examples of using none, ~ (tilde) ^ and * (star) characters to request package version.

I’m not saying your project will need all of the dependencies listed in this example. But it’s not uncommon to have at least most of the babel packages installed. If your project depends on redux and router, then you might want to add them as well:

“dependencies”: {
“axios” : “0.16.1”,
“babel-core” : “6.24.1”,
“babel-loader” : “6.4.1”,
“babel-polyfill” : “6.23.0”,
“babel-preset-es2015” : “6.24.1”,
“babel-preset-react” : “6.24.1”,
“babel-preset-stage-3” : “6.24.1”,
“babel-runtime” : “6.23.0”,
“clean-webpack-plugin” : “0.1.15”,
“concurrently” : “3.4.0”,
“css-loader” : “0.28.0”,
“dotenv” : “4.0.0”,
“prop-types” : “15.5.8”,
“react” : “15.5.4”,
“react-dom” : “15.5.4”,
“react-redux” : “5.0.5”,
“react-router” : “3.0.1”,
“redux” : “3.6.0”,
“redux-thunk” : “2.2.0”,
“webpack” : “2.4.1”,
},

The more packages your module depends on the more potentially unstable it might be. Simply because there is no control over changes introduced by developers of those packages at a later time. For this reason ^ is the safest option for specifying version number, limiting it to minor version upgrades only.

You can “yarn” all dependencies together. Just run yarn install from the root directory of your project. Yarn will install all dependencies from this list automatically. So you never have to do it by hand for each one.

Next, we will explore the “scripts” key which includes instructions for which scripts to run in which situation. Not all of them are required or even needed. Each case is explained by a unique key. For example on start you can run node server.js. But there are a few other cases:

“scripts”: {
“start” : “node server.js”,
“test” : “”,
“dev” : “”,
“node-dev” : “”,
“node-prod” : “”,
“build-dev” : “webpack — config webpack.dev.config.js”,
“build-prod” : “webpack -p — config webpack.prod.config.js”,
“test-watch” : “yarn test — — watch”,
},

Finally, we will explore one key.

Babel has a special keyword reserved for itself. Here you can specify its presets.

“babel”: {
“presets”: [
“es2015”, “react”, “stage-3” ]
},
}

If you don’t need to use Babel in your project, you can skip this key altogether.

It looks like our configuration file is ready.

When you yarn all packages in package.json file are downloaded, installed and linked automatically. You never have to worry about installing each one by hand. Just make sure to include them here.

There are a few other keys in package.json file you can use, but at this time we will not go into those details. We’ve just created a basic configuration that should serve as a starting point for creating your build environment.

After all, it’s not so complicated. When I started programming in React, I was hesitant to even think about what these configuration files are used for. I took them for granted, called yarn command to bundle them all together, and it still worked. You can hide this way but not for long.

Many web developers do the same thing. If it works why understand it? But working on a real project you will eventually run out of excuses and will have to understand what each part does. Hopefully this chapter shed some light on package.json file and helped you become more comfortable with building server-side applications.

We created our package config. Now what? You can import and export packages into other projects. In the following section we will learn how to do it.

Importing And Exporting Local Packages

You can think of jQuery as a dependency in earlier JavaScript programs. Here, it’s the same thing. We’re just importing and exporting packages in a different way. Only we’re no longer using the <script> tag as before. To exactly the same effect. The JavaScript code is “included” much like it was with the script tag. It’s just the inclusion has been moved directly into your JavaScript application. Which is a really great idea.

And not only that, it is possible to import into your main program from multiple .js files. This not only makes your code look cleaner but forces you to think about building your application in a modular way (consisting of many separate modules.) This tactic is especially common of large projects usually where many people work on the same application. But from the point of keeping your project organized it is an excellent idea. Even if you’re working on your project alone.

There are thousands of libraries written by open source developers all over the world. So you don’t have to reinvent the wheel. Once installed they must be imported into your project.

You can pull any one of the existing packages as long as you have Node installed. It’s that simple. There is nothing to download manually. You just execute node/npm commands. Add its filename to the list of dependencies in package.json file and you’re ready to start. The yarn package can also help you tie all of your dependencies together without much grief.

Packages like yarn, however are used globally on the server. And local packages must be imported into your project using the import keyword. We’ve already installed yarn globally in one of the examples prior to this section. Let’s now take a look at how include/export keywords work.

We’ve already established that Instead of using the proverbial <script> tag local packages are added via your main JavaScript file using import directive. This is the new keyword in EcmaScript 6. It helps us organize our application in a modular way.

But the package containing the classes or functions that define functionality of that package must also export that class from your main script file. Let’s take a look at this pattern.

For example, I was working on a <GutterPane/> component in my React application. At first, I wrote it into my main application file as a JavaScript class. But, in obedience to global modular design in my application, I refactored GutterPane into a separate file called <gutterpane.js>.

The following example also provides a few other common cases of using import keyword in a basic React application.

index.js — main application file now imports my GutterPane component:

import React from “react”;
import { connect } from “react-redux”;
import { Link } from “react-router”;
import { push } from “react-router-redux”;
import GutterPane from “gutterpane”;
// You can now use the imported <GutterPane/> component
// in your React application

Here, gutterpane is a reference to gutterpane.js file. The <.js> extension is optional in import directive. And finally in my GutterPane file (gutterpane.js) I need to make sure to export the class. Skipping this step will not make this class available in my application. It’s just as important:

gutterpane.js file containing <GutterPane/> component definition:

export default class GutterPane extends React.Component()
{
render() {
return (
<div className = “GutterContainer”>
Sidebar gutter container
</div>
)
}
}

Here I am also using default keyword. It lets my app know that this is the only class being exported from this <.js> file.

You can create your own custom components or download and export packages created by the web development community. You don’t always have to write your own code. Chances are that somewhere out there a package already exists that accomplishes a particular task.

We now know how to install and include packages in our project. Well, that’s great. But let’s continue setting up our development environment. We’re just one step away from starting to write our first React application.

Finishing Setting Up Development Environment

There are plenty of ways in which a development environment can be configured. This is somewhat of a habit you develop over a long period of time working with different tools. For this reason there isn’t any one single solution.

In this section, one potential setup will be shown that worked for me while developing a web application for one of my employer’s clients: the “GoodYear” tire company. Our built consisted of node, babel, jsx, yarn and webpack. I know it’s a handful, and it probably makes no sense trying to grasp them all in one moment if you’ve never worked with them before. Understanding what each one does can only come from experience when you’re actually using them.

This section demonstrates several server-side commands you can use that will guide you toward getting one step closer to setting up a development environment. But it is still up to you to get familiar with alternative builds and commands in the Node toolset.

Just remember that there is no perfect formula. Some commands will overlap. For example, packages installed using yarn from package.json file may overlap packages installed manually by typing in commands into bash or command prompt. All this is part of a normal process. If you need to install a new version of a package, you can do it by hand. The same goes for uninstalling. What I am saying is that your build is a live ecosystem of packages and dependencies. Things change. They always do.

The following is a potential set of commands typed in progression for installing various packages. I don’t know if you will or will not need them in your project. This log demonstrates what you might find yourself typing into the console during your casual setup procedure:

npm install yarn — global
npm install webpack@2.1.0-beta.22 — save-dev
npm install extract-text-webpack-plugin
npm install clean-webpack-plugin
npm install dotenv
npm install babel-polyfill
npm install webpack-dev-server
npm install -jsx
npm install -S react-router
npm install -S history@1
npm install prop-types
npm install -g bundle-js
npm install
npm install yarn
yarn install
npm info webpack
webpack — config webpack.dev.config.js

Of course there isn’t a reasonable way to describe and explain every single package and configuration preference. Getting familiar with what packages you need for your project depends on making choices pertaining to your particular application needs.

Building server-side applications isn’t a trivial process. And it is tempting to just go back to writing front-end code and forget any of this happened. But this is exactly the difference between back-end and front-end programming.

Having said all this if you’re looking to grow your web development career, these types of things are an absolute must. In the industry, it is assumed that you have dedicated enough time on learning the command line tools and know installation process for some of the most common packages by heart.

Yarn

Yarn, yarn.lock and package.json are the files you will inevitably bump into while building your environment. Some packages automatically install yarn. In some cases, you have to install it manually. Let’s take a look at a real-world situation where we want to install TypeScript support together with a React app.

Assuming Node.js and npm are already present on your local machine here’s an example of what a React and TypeScript installation might look like:

Navigate to your project folder, for example:

On Windows:

C:\Program Files (x86)\Apache Software Foundation\Apache2.2\htdocs\

On Mac/Linux, it could be:

/Users/username/GitHub/

Or an equivalent folder currently linked up to your localhost environment via a web server like Apache, for example.

Create a new project folder. In this case I’ll use: “react.typescript”.

Navigate to this folder and execute the following command:

npm install create-react-app

This will add node_modules directory and all of its modules to our newly created “react.typescript” project folder.

Alternatively, you can do a global installation using -g flag:

npm install -g create-react-app

On Windows, this will install node_modules to a folder similar to:

C:\Users\Name\AppData\Roaming\npm\node_modules\create-react-app\…

Creating the app

We have just installed create-react-app package using Node package manager “npm”.

We now need to use react-scripts-ts to create an application capable of compiling TypeScript.

In the following example, replace “appname” with whatever you want to name your app:

create-react-app appname — scripts-version=react-scripts-ts
Installing packages. This might take a couple minutes.
Installing react, react-dom, and react-scripts

Yarn will be automatically deployed to “yarn up” dependencies from your “package.json” file.

yarn add v0.24.5
info No lockfile found.
[1/4] Resolving packages…
[2/4] Fetching packages…
warning fsevents@1.0.17: The platform “win32” is incompatible
with this module.
info “fsevents@1.0.17” is an optional dependency and failed
compatibility check. Excluding it from installation.
[3/4] Linking dependencies…
[4/4] ...
...followed by a long list of packages installed…

Wait for a minute or so, while watching an ASCII loading bar going through [4/4] processes outlined above, until this message with additional tips is received:

Success! Created appname at C:\Program Files (x86)\Apache Software Foundation\Apache2.2\htdocs\react.typescript\appname

Inside that directory, you can run several commands:

yarn start

Starts the development server.

yarn build

Bundles the app into static files for production.

yarn eject

Removes this tool and copies build dependencies, configuration files and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

cd appname
yarn start
Happy hacking!

Congratulations. You have just installed React with TypeScript support. Just one possible way to set up a development environment for a particular build flavor.

Again, you can install yarn manually via npm at any time. But in this example create-react-app has already taken care of that for us.

Babel

Few command line commands to add babel to your build:

npm install babel-core
npm install babel-loader
npm install babel-polyfill
npm install babel-preset-es2015
npm install babel-preset-react
npm install babel-preset-stage-3
npm install babel-runtime

After running these commands you can be sure that Babel is installed on your local machine. As you may know, Babel is what provides transpilation from EcmaScript 6 back to EcmaScript 5. Your project is bundled into a single file in ES5 that modern browser can compile, even though the application was built using latest specification.

Webpack and bundle.js

A whole book can be written about Webpack alone. But basically it is one of the common ways server-side the application can be built on the server. It can even transpile your ES6 code to ES5

You can use webpack to bundle your project into a bundle.js file. This single file will contain source code of your entire application, regardless how many separate <.js> modules were used to create it.

It is done this way because Babel will often produce EcmaScript 6 code not yet supported by all browsers. For example, as of this writing the ES6 import keyword wasn’t even supported in Chrome. Babel package “transpiles” that code back into ES5. Something that most browsers won’t choke on.

But that won’t always be this way. Eventually Chrome and other browsers will have native support for import keyword and the rest of standardized EcmaScript 6+ features. In the near future you may not even have to transpile your project anymore. Until then your project files (JavaScript modules) will need to be bundled into one long file containing your entire source code.

WebPack as many packages have configuration files. For WebPack it is usually webpack.config.js. You can create alternative builds.

webpack --config webpack.config.js

This command will build your entire application. The file bundle.js produced by this operation is then plugged into your front-end page.

var path = require(‘path’);
module.exports = {
entry: ‘./es6/main.js’,
output: {
path: dirname,
filename: ‘bundle.js’
},
module: {
loaders: [
{ test: path.join(dirname, ‘es6’),
loader: ‘babel-loader’ } ]
}
};

As you can see webpack defines babel loader in its configuration file webpack.config.js So when you actually build with webpack, it will use a babel loader to transpile ES6 code to ES5.

Creating a React Native App

Just to demonstrate an example of how easy it is to create new scaffolding for various applications with npm let’s create a React Native application.

Navigate to your server’s htdocs (or a folder mapped to your server root http://localhost/) and execute the following command to create a new directory AwesomeProject for your React Native project:

create-react-native-app AwesomeProject

After running this command you will need to wait for a couple of minutes according to output:

Installing packages. This might take a couple minutes.
Installing react-native-scripts…
yarn add v0.24.5
Info No lockfile found.
[1/4] Resolving packages…
[2/4] Fetching packages…
[3/4] Linking dependencies…
...followed by a long list of packages (probably hundreds)
...not shown here...
xtend@4.0.1
yallist@2.1.2
yesno@0.0.1
Done in 224.75s.
Installing dependencies using yarnpkg…
yarn install v0.24.5
[1/4] Resolving packages…
[2/4] Fetching packages…
[3/4] Linking dependencies…
[4/4] Building
success Saved lockfile.
Done in 264.47s.

Success! Created AwesomeProject at

C:\Program Files (x86)\Apache Software Foundation\Apache2.2\htdocs\AwesomeProject

Or if you’re on Linux, it could have been

/User/amazinguser/GitHub/AwesomeProject

This will be followed by just a few more convenience notes from for using yarn:

yarn start

Starts the development server so you can open your app in the Expo app on your phone.

yarn run ios

(Mac only, requires Xcode)

Starts the development server and loads your app in an iOS simulator.

yarn run android

(Requires Android build tools) Starts the development server and loads your app on a connected Android device or emulator.

yarn test

Starts the test runner.

yarn run eject

Removes this tool and copies build dependencies, configuration files and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

cd AwesomeProject
yarn start

Normally, you wouldn’t even need to install Apache server. Node alone can get your localhost folder link up with a project directory on your computer. But in this example, it’s installed via existing Apache folder structure. If you want to create your projects elsewhere, that’s fine too!

At this point, if you open your project folder in your browser you will see this:

Index of /AwesomeProject

And just like the command line suggested, Let’s cd to AwesomeProject and run yarn start.

The following log demonstrates what would happen:

cd AwesomeProject
yarn start
yarn start v0.24.5
$ react-native-scripts start
11:53:39 PM: Starting packager…
Packager started!

To view your app with live reloading, point the Expo app to this QR code.

You’ll find the QR scanner on the projects tab of the app.

Or enter this address in the Expo app’s search bar:

exp://192/168.0.2:19000

Your phone will need to be on the same local network as this computer.

For links to install the Expo app, please visit https://expo.io.

Logs from serving your app will appear here. Press Ctrl+C at any time to stop.

Congratulations! We’ve successfully prepared a clean React Native build.