Skip to content

Dev setup

Jonathan Sharpe edited this page Feb 26, 2023 · 30 revisions

Requirements

You need Node and NPM installed to use this starter kit. It's tested with the active and maintenance LTS versions of Node.

You can check your current versions of these tools with node --version and npm --version.

OS

The automated testing all takes place in Ubuntu 20.04, but other Linux versions should be fine and macOS (note M1 Macs require Node 16) and Windows should both work too.

Lockfile versions

The lockfile version is now pinned to v2 in the .npmrc, for compatibility with NPM from v6 to v9.

Note the different major NPM versions. NPM v7 introduced new (v2 and 3) formats for the package-lock.json. If you try to collaborate in a team where some people use NPM v6 and others use v7+, the lockfile will keep getting changed and cause large pull request diffs. Either:

  1. All use Node 14 with NPM 6;
  2. All use NPM 7+ (either all using Node 16 or upgrading NPM with npm install --global npm@<version>);
  3. Pin the lockfile-version in the .npmrc file; or
  4. [Not recommended] Add the package-lock.json to .gitignore (this could cause hard-to-debug issues where different machines have slightly different versions of your dependencies).

To help in maintaining consistency, you can narrow the requirements in the package.json engines field to e.g.:

  "engines": {
    "node": "^16.13.0",
    "npm": "^8.1.0"
  }

(This would require everyone to use the same version of Node, you can use e.g. https://semver.npmjs.com/ to test out different requirements and the versions they match.)

You should also edit any other files you're using that refer to the supported Node/NPM versions (e.g. README.md, .github/ISSUE_TEMPLATE/bug-report.md, .github/workflows/push.yml, ...).

Optional

The following global tools are recommended to simplify development:

  • NVM - lets you manage multiple versions of Node on one machine (the version this project currently uses is in .nvmrc).
  • direnv - lets you manage environment variables (and the active version of Node) based on the .envrc of the directory you're in.

Installation

  1. Click "Use this template" on the appropriate repository to create your own version

  2. Clone the new repository to your local machine.

  3. cd into the repository's directory on your local machine. You can run git status to check you're in the right place, it should say something like

    On branch master
    Your branch is up to date with 'origin/master'.
    
    nothing to commit, working tree clean
    
    • If you have direnv installed, you may see

      direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
      

      If you trust the repo, you can run direnv allow as suggested.

  4. Install the dependencies by running npm install; this will create a node_modules/ directory and fill it with the requirements specified in package.json and package-lock.json.

  5. [Optional] If you're using a version that needs a database, see Dev setup#Databases

  6. Run the app using either npm run dev (developer mode, with watching/reloading of your code as you make changes) or npm run serve (production mode, to check what will actually get deployed) - see Scripts for more details.

  7. While one of those two scripts is running, visit http://localhost:3000 to see the app:

    If you see any errors, or the site doesn't look like the image above, check out Home#Common errors.

Databases

If you're using either the CYF Postgres fork, you'll need to supply a database for the app to use on startup.

Postgres

By default the app tries to connect to postgres://localhost:5432/cyf, or this can be overridden with either:

  • the single DATABASE_URL environment variable (which e.g. Heroku sets automatically); or
  • any or all of the separate DB_HOST, DB_NAME, DB_PASS (or DB_PASSWORD), DB_PORT and DB_USER (or DB_USERNAME) environment variables.

These variables can be set in the .env file in the repository root, see Dotenv. You can see configuration and connection data (or edit it if needed) in server/db.js and server/utils/config.js.

To run Postgres locally see these CYF instructions, or if you're more confident:

  • Official installer: follow the instructions at https://www.postgresql.org/download/
  • Homebrew (macOS only): brew install postgresql then brew services start postgresql
  • Docker: docker run -d -e POSTGRES_PASSWORD=<password> -p 5432:5432 postgres (if you haven't installed Docker, see https://docs.docker.com/get-docker/)
    • Note that in this case you'll need to explicitly set -h localhost -U postgres and enter the password you set above when running e.g. createdb, and the connection URL will need to be postgres://postgres:<password>@localhost:5432/cyf (you could set this as the DATABASE_URL env var).
    • You can start and stop this container as needed using docker stop cyf-postgres/docker start cyf-postgres.

Once you have Postgres up and running, createdb cyf to create the database the app will use.

Ports

If you see EADDRINUSE when trying to run dev or serve, you may have other processes running on your machine that are using ports the starter kit expects. You can check which processes these are using the command:

lsof -i :<port>

If you see existing npm commands running, you may have terminals running in the background somewhere - find them and stop them! If you see some other program running, you may need to switch ports. You can do this as follows:

  • npm run dev:
    • Frontend (default: 3000): you need to change the line port: 3000, in client/webpack/dev.config.js
    • Backend (default: 3100): you need to change this in two places, the line "/api": "http://localhost:3100", in client/webpack/dev.config.js and the line "dev:server": "cross-env LOG_LEVEL=debug PORT=3100 nodemon --exitcrash --inspect --delay 500ms --watch server --exec babel-node server/server.js", in package.json.
  • npm run serve:
    • Backend (default: 3000): the easiest way to override this is when you actually run the server, so you can do e.g. PORT=3210 npm run serve. Alternatively you can change the line port: parseInt(process.env.PORT ?? "3000", 10), in server/utils/config.js.
Clone this wiki locally