There's a standard template for creating React apps: the create-react-app application template. This includes some standard dependencies and boilerplate code that all React applications need. However, it also contains some extra items such as favicon.ico, a sample logo, and CSS files. While these are undoubtedly useful, having them here at the very start of a project is at odds with one of the test-driven developer's core principles: You Ain't Gonna Need It (YAGNI).
This principle says that you should hold off adding anything to your project until you're really sure that it's necessary. Perhaps that's when your team adds a user story for it into the iteration, or maybe it's when a customer asks for it. Until then, YAGNI.
It's a theme that runs throughout this book and we'll start right now by choosing to avoid create-react-app. You can always start every JavaScript project from scratch, and there's a certain joy to be found in going over the basics each time.
We’ll be making extensive use of the npm command-line tool and the Node.js execution environment. Each time you run your tests, which will be very frequently, you'll be required to run an npm command.
Toward the end of the chapter, we'll also use npm to package our application.
You can find out if you already have it installed on your machine by opening a Terminal window (or Command Prompt if you’re on Windows) and typing the following:
npm -v
If the command isn’t found, head on over to the Node.js website for details on how to install. The URL is included at the end of this chapter.
The npm program knows how to update itself, so if it's installed, I recommend you ensure you’re on the latest version. You can do this on the command line by typing this:
npm install npm@latest -g
I'm using version 6.9.0 to write this book. If you have any issues with the code samples contained here, differing NPM versions could be one of the causes, so please bear that in mind as you continue.
Yet another resource negotiator (YARN) is an alternative to NPM, and I won’t hold it against you if you choose to use it. There are only a handful of npm commands in this book—I assume that if you’re sticking with YARN, then you’ll already know how to convert npm commands to yarn commands.
The Git tag for this section is starting-point. It doesn't contain any code; just a README.md file. If you want to follow along using the book's Git repository then you should ensure you've branched from this tag. Detailed instructions from doing that are in the Getting started before Chapter 1 section of the Preface.
Now that NPM is installed, we can create our project:
- If you're following along with the book's Git repository, open a Terminal window and navigate to the repository directory that you cloned in the Getting started before Chapter 1 section of the Preface. Otherwise, simply navigate to your local projects directory.
- Create a new directory using mkdir appointments and then change to it using cd appointments.
- Enter the npm init command, which begins the process of initializing a new NPM project and generating a package.json file for you.
- The first questions ask you to provide a package name, version, description, and an entrypoint. Since we're building an appointments system, you can call it appointments. Accept the default version (by just hitting Enter), and enter a description of Appointments system. You can accept the default entrypoint too.
- Next, you'll be asked for a test command, for which you should type in jest. This will enable you to run tests by using the npm test shortcut command.
Don't worry if you miss this; you can set it afterward by adding "test": "jest" to the scripts section of the generated package.json.
- You'll be asked to specify a repository, which you could just set as example.com for now. If you don’t fill these fields in, npm will print warnings every time you run a command.
- You can accept the defaults for everything else.
You may wonder why we filled out the repository field. TDD loves fast feedback cycles. Prioritize cleaning your screen and command outputs of as much noise as possible. Any time you see something that is destroying clarity, either fix it right then and there, or put it as an action at the top of your to-do list.
In this particular case, you could also add "private": true to your package.json, instead of setting the repository field.
- Hit Enter on the remaining questions to finish the initialization process.
- Install Jest using npm install --save-dev jest.
You will see the bottom line of your Terminal fill up with a fast-changing stream of package information as NPM installs dependent packages (a paltry 553 packages at the time of writing). You may see some warnings depending on the platform you are installing on, but these can be ignored. Once complete, you should see this:
npm notice created a lockfile as package-lock.json. You should commit this file.
+ [email protected]
+ added 553 packages from 373 contributors and audited 849842 packages in 16.304s
+ found 0 vulnerabilities
Let's install React. That's actually two packages:
npm install --save react react-dom
React makes heavy use of JavaScript XML (JSX), which we need Babel to transpile for us. Babel also transpiles our modern ES6 and ES7 constructs for us.
The following information is accurate for Babel 7. If you're using a later version, you may need to adjust the installation instructions accordingly.
Thankfully, Jest already includes Babel, so we just need to install presets and plugins:
npm install --save-dev @babel/preset-env @babel/preset-react
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtime
A Babel preset is a set of plugins. Each plugin enables a specific feature of the ECMAScript standards, or a preprocessor such as JSX.
The env preset brings in essentially everything possible. It should really be configured with target execution environments. See the Further reading section at the end of this chapter for more information.
We need to enable the packages we've just installed. Create a new file, .babelrc, and add the following:
{
"presets": ["@babel/env", "@babel/react"],
"plugins": ["@babel/transform-runtime"]
}
With that, you're all set to write some tests. You may wish to check in at this point.