Skip to content

v1 Dependencies

Jonathan Sharpe edited this page Aug 24, 2024 · 1 revision

In short:

  • Because the development dependencies are stripped out, anything you need Express to access at runtime must be a production dependency; and
  • To keep the build size small (Heroku has a slug size limit of 500Mb, the Cloud Foundry manifest sets a 256Mb quota), anything that's not needed by Express at runtime should be a development dependency.

Build process

  • The Heroku deployment effectively goes through the following build process:

    1. npm install - install all dependencies, development and production
    2. npm run build - build the output in dist/
    3. npm prune --production - strip out the development dependencies

    At runtime, it just has to npm start.

  • With Cloud Foundry we build the dist/ output locally or in a CI machine, then the buildpack only ever installs the production dependencies.

The development dependencies aren't available at runtime on either platform.

New dependencies

If you are adding a dependency, then:

  • If it's something that the server needs at runtime (i.e. imported and used in server/), install it as a production dependency (npm install <thing>); or
  • If it's something that's part of the build process (Babel, Webpack), verification (ESLint, Jest, Cypress, etc.) or used in the React app (i.e. imported and used in client/), install it as a development dependency (npm install --save-dev <thing>).

Audit

When you install or update your dependencies, you may see a message like this:

63 moderate severity vulnerabilities

To address issues that do not require attention, run:
  npm audit fix

To address all issues possible (including breaking changes), run:
  npm audit fix --force

Some issues need review, and may require choosing
a different dependency.

Run `npm audit` for details.

Many of the dependencies are only used during development, and not exposed to any end-user inputs, so aren't such a big deal (see e.g. facebook/create-react-app#11174 for more discussion). To focus on the ones that are used at runtime (assuming you've categorised any new dependencies appropriately, see v1 Dependencies#new-dependencies), which is where the greatest risk lies, omit the development dependencies from the audit report:

$ npm audit --omit=dev
found 0 vulnerabilities

NPM provides some commands you can use to manage the dependency tree (and automatically update the package.json "package file" and package-lock.json "lock file" if needed):

  • npm audit fix will update any packages in your dependency tree where: 1. there is a known vulnerability in a version you have installed; and 2. there is a fixed version that's semver-compatible with what's in your package file;

  • npm explain <package>/npm ls <package> tell you why the package is in your dependency tree (vulnerabilities won't always be in direct dependencies like react, sometimes they're in transitive dependencies):

     $ npm ls word-wrap
     [email protected] path/to/starter-kit
     └─┬ [email protected]
       └─┬ [email protected]
         └─┬ [email protected]
           └─┬ [email protected]
             └── [email protected]
  • npm outdated will show you a list of packages you have installed that have newer releases:

     $ npm outdated
     Package             Current   Wanted   Latest  Location                         Depended by
     cypress             12.14.0  12.16.0  12.16.0  node_modules/cypress             starter-kit
     eslint-plugin-jest   27.2.1   27.2.2   27.2.2  node_modules/eslint-plugin-jest  starter-kit
     react-router-dom     6.13.0   6.14.0   6.14.0  node_modules/react-router-dom    starter-kit
     webpack              5.87.0   5.88.0   5.88.0  node_modules/webpack             starter-kit
  • npm update will update all packages in your dependency tree to the latest semver-compatible releases;

    • npm update --save will also update the package file so that the minimum version is the latest semver-compatible one;
    • npm update <package>@<version> will update to the specified version (e.g. npm update react@latest would install the latest version) whether or not it's compatible with what's in the package file.

⚠️ Do not run npm audit fix --force. That will apply changes that are not compatible with the dependencies declared in the package file, which can break things outright or cause hard-to-debug errors. If you need to apply major-version updates, do them one at a time using npm update <package>@<version> and test each one.

If it's a package you've added (i.e. one that's not required by the base starter kit), a final option is to look for alternatives if it's not a well-maintained dependency (e.g. infrequent releases, lots of reported bugs that don't get fixed).

Clone this wiki locally