Skip to content

justinsisley/mostly

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mostly

mostly

They mostly come at night; mostly.
Express + React + Babel + Webpack + Prettier + ESLint + Jest + Puppeteer

GitHub release CircleCI license


mostly is a full-stack web application starter kit built on Node.js. It uses Express for the server and React for the user interface.

Its purpose is to serve as a lightweight, easy-to-comprehend starting point, with a focus on providing a great developer experience while helping you get high quality and maintainable apps deployed rapidly.

Nothing is hidden, nothing is magical, and all of the "plumbing" is accessible and relatively simple.


Table of Contents

Features

  • Uses a minimal set of UI development tools (via React and CSS modules)
  • Uses a familiar Node.js HTTP server library (via Express)
  • Lets you use the latest and greatest ECMAScript everywhere (via Babel)
  • Provides a fast development workflow (via hot-reloading on the client and server)
  • Helps you write unit, functional, and end-to-end tests with ease (via Jest and Puppeteer)
  • Keeps your code clean and consistent (via Prettier and ESLint)
  • Gives you simple dev, test, build, and deploy scripts (via NPM and bash)
  • Runs on Node.js v6+ (via Babel runtime)

Documentation

Install

Clone the repository:

git clone --depth=1 https://github.com/justinsisley/mostly.git your-project-name

Initialize your own repository:

$ cd your-project-name
$ rm -rf .git && git init

Install dependencies:

$ npm install

Configuration

Configurations for Babel, ESLint, lint-staged, and prettier are contained within the package.json file.

Configurations for Webpack can be found in the scripts/config directory.

Configuration for CircleCI is contained in the .circleci/config.yml file.

Develop

Run the application in development mode:

npm run dev

Note: The dev server runs on port 3320 by default. Feel free to change it in scripts/config/webpack.dev.js.

Test

Run unit and functional tests:

npm test

Note: Both test suites will run concurrently. End-to-end tests will not be run.

Unit Tests

Run unit tests:

npm run test:unit

Note: Jest will run any file that matches the following pattern: src/**/__tests__/unit.js

Functional Tests (API endpoint tests)

Run functional tests:

npm run test:func

Note: Jest will run any file that matches the following pattern: src/**/__tests__/func.js

End-to-end Tests (user interface tests)

Run end-to-end tests:

npm run test:e2e

Note: Jest/Puppeteer will run any file that matches the following pattern: src/**/__tests__/e2e.js

Test Modes and Options

Run a test suite in watch mode:

npm run test:unit -- --watch
# or
npm run test:func -- --watch

Note: This option is simply passing the watch option directly to Jest. End-to-end tests do not support the watch option.

Run the unit test suite and generate a coverage report:

npm run test:unit -- --coverage

Note: Like watch, this option is passing the coverage option directly to Jest. Functional and end-to-end tests do not support the coverage option.

Build

Create a static build:

npm run build

Note: This script will use Babel and Webpack to compile code within the src directory into a dist directory.

Production

Run the application in production mode:

npm start

Note: This script requires you to first create a build by running npm run build.

The production application will run on port 3325 by default. If you'd like to run it on another port, use the PORT environment variable. For example:

PORT=8080 npm start

Deployment

Deploy to now.sh:

npm run deploy

Note: now.sh is one of the quickest and easiest ways to get your app deployed. It also offers a free plan. Nevertheless, like every other part of this starter kit, I encourage you to modify deploy.sh to suit your needs.

Pre-commit Hook

This starter kit is pre-configured with a git pre-commit hook, which will automatically clean up your staged code using Prettier and ESLint, then execute your unit and functional tests. This is done using lint-staged and husky.

You can modify the pre-commit workflow using the lint-staged property in package.json and the scripts/precommit.sh file.

Continuous Delivery

CircleCI was chosen as the continuous integration provider because it's one of the more popular CI's in use across GitHub and it offers a free plan.

No matter which CI you decide to use in the long run, the configuration is code-based, which should make it relatively easy to migrate if and when you decide to use another provider.

For information about setting up your repository in CircleCI, sign up for a free account, then check out the documentation.

Once you've set up your repository in CircleCI, you'll need to get a token from now.sh in order to automate your deployment. Once you've got your token, add it to your CircleCI project as an environment variable named NOW_TOKEN.

Now, when you push new commits, CircleCI will run the lint, test:unit, test:func, and test:e2e scripts, then deploy your app to now.sh with zero downtime using the deploy script.

It'll be up to you to configure a custom domain, promote from staging to production, etc., but this configuration gets you most of the way there; mostly.

FAQ

What's with the name?

This project is the successor of another project, clear. I considered making this the v2 of clear but decided that because mostly handles client-side web application development as well as server development, it would not be in line with clear's raison d'être.

It's still "clear", in this context meaning "straightforward", but there's some additional complexity, therefore it's mostly clear.

I told you at the start of this that there's no magic, so try not to be too disappointed.

I don't get the tagline.

That's not a question, but ok. It's a line from the movie Aliens and was made humorous by South Park.

Why are you promoting now.sh and CircleCI? Are you getting paid?

No. I have no affiliation with either of those companies. In fact, at the time of first publishing this project, they're both new to me.

Bottom line: they're both free to use until you need to scale, and they're both very easy to work with. That puts them in perfect alignment with the purpose of this project.

Why are you using Puppeteer instead of Nightwatch.js, TestCafe, Cypress, etc.?

I've used several other end-to-end testing frameworks, and I've used them on one-person "teams", in small and medium-sized startups, and in large engineering organizations. In my experience, I've seen several themes repeat themselves:

  • Adding another test framework and/or assertion library does not lend itself to increased velocity or a better developer experience.
  • Choosing a single assertion library for all types of tests, if possible, leads to higher-quality testing, as teams build cohesive expertise over time.
  • If tests aren't easy to write, they tend to be avoided*.
  • If tests are brittle, they tend to be avoided*.

*Avoided, in this context, means not written, not maintained, not trusted, not run regularly, or any combination thereof.

Due to these experiences and observations, I've become a fan of Jest, as it contains the test runner, the assertion library, and the code coverage utility all in one easy-to-use package.

I've also become a fan of Puppeteer, especially when combined with jest-puppeteer, as it allows me to easily automate Chrome while writing the exact same style of assertions I use for my unit and functional tests.

Is Puppeteer perfect? Of course not. For one, it's built on Chrome/Chromium, so you're not getting multi-browser testing like some other libraries. Nevertheless, the API is straightforward and easy-to-use, and when combined with jest-puppeteer, it creates a good enough developer experience that I end up writing a more complete end-to-end test suite, which ultimately boils down to a more trustworthy codebase and a more reliable product being delivered to the end user.

What if there's a better, simpler library out there? Are you willing to switch to it?

Absolutely. It's quite likely that there are better libraries than what this project is using, and if that's the case, please open an issue, or better yet, a PR.

If your suggestion truly improves and/or simplifies this project, there's a strong guarantee it will make the cut.

Where's the Redux version?

There's a redux branch, but in addition to redux, it uses react-redux, redux-thunk, and redux-actions, so it's a bit more opinionated in library choice, architecture, and configuration.

It's also configured to use Redux DevTools, which can be quite useful during development and debugging.

Why isn't there a CLI? Everything should have a CLI.

For this project, I just don't think it's necessary. The install steps are relatively simple, and three shell commands get you the most up-to-date starter kit checked out in a brand new repository.

Credits

Icon made by Eucalyp from www.flaticon.com is licensed by CC 3.0 BY