Skip to content
This repository has been archived by the owner on Jan 25, 2023. It is now read-only.

npm ci support #172

Closed
ekoeryanto opened this issue May 13, 2018 · 5 comments
Closed

npm ci support #172

ekoeryanto opened this issue May 13, 2018 · 5 comments

Comments

@ekoeryanto
Copy link
Contributor

No description provided.

@brycekahle
Copy link
Contributor

Thanks for opening an issue.

We looked into npm ci and it would actually be a negative thing for most folks on Netlify. The purpose of the command is intended for CI that is used for testing, rather than deployment, which is what our builds are for. The command re-installs all dependencies, which we've gone to a lot of effort to avoid for performance reasons.

@mbrevda
Copy link

mbrevda commented Jul 15, 2019

Hi - I was wondering if you can elaborate a bit?

According to the docs, npm ci is

meant to be used in automated environments such as test platforms, continuous integration, and deployment

So it would seem this can be used for CD as well. Being that npm doesn't need to rebuild the depends graph (as it reads the lockfile) that should speed up the install time. Have your experiences been different? Additionally, npm ci guarantees a deterministic, repeatable build - every time, something which cannot be said for npm i.

Further reading:
https://docs.npmjs.com/cli/ci.html
https://stackoverflow.com/questions/52499617/what-is-the-difference-between-npm-install-and-npm-ci

@frangio
Copy link

frangio commented Jul 17, 2019

I agree that re-installing all dependencies is undesirable in Netlify, but the benefit of npm ci is as @mbrevda mentioned deterministic builds based on the lockfile. I would consider using npm ci instead of npm install when the node_modules directory is not found in the cache, and if there is a lockfile to begin with.

@markkasaboski
Copy link

markkasaboski commented Apr 15, 2022

The only way npm install makes sense to use within an automated build is if we (the developers of the application) edit our package.json files removing all ^, ~, >, >=, <, <= ... that prefix the versions and get them all to match exactly the version that we want. https://docs.npmjs.com/cli/v8/configuring-npm/package-json#dependencies

Currently, Netlify runs npm install very early in the build. This will result in the build process blindly updating any dependencies that are not strictly locked right down to the patch level. We, the application developers, cannot see what has happened. This is dangerous because we, the application developers, will have (hopefully) tested our application against a specific set of dependencies, but now Netlify's build process has altered them, possibly introducing some instability.

To be able to use npm install or npm ci should be a nothing more than a simple configuration change within the Netlify UI. This would not break everyone else's builds. It's just an environment (site) level switch that we should have the option to turn on. Or a Team level setting that applies to all environments (sites).

Until then (should it ever happen) this hack will suffice:

Go into your Build & Deploy Environment Variables and set NPM_FLAGS with the value --dry-run. This will effectively disable Netlify's invocation of npm install as it will not result in installed node modules. This also means that you are no longer taking advantage of Netlify's build cache for node modules, but whatevs. ¯_(ツ)_/¯ I'm happy to deal with a longer build time vs having builds that are not deterministic. Further to that, I'm not sure I have a whole lot of confidence in Netlify's ability to maintain those correctly. Anyway, after that, configure the command you want to use in the command input within the Build & Deploy Build settings or set it up in your netlify.toml.

A better approach for everyone would be this:

Get your app setup within a CI/CD pipeline. Github Actions is great and someone has already created a Netlify Deploy action (https://github.com/marketplace/actions/netlify-deploy).

  1. Create a build job where you build your application (using npm ci obvi) with your dev dependencies and run your tests. Tests and all of your other quality gates pass? Great! Onto the Deploy job.
  2. We don't need the artifacts from the previous job, so don't pass those to this job. From there setup the netlify-deploy action mentioned above, point it at your build directory, make sure to configure the build command to be NODE_ENV=production npm ci (see: https://github.com/marketplace/actions/netlify-deploy#inputs) and that should pretty much take care of it.

Using Github Actions, you'll have better control over your builds.

Oh, you're also gonna want to make sure the deploy step only happens on a specific branch, i.e.: main. Not "master"! You should have already changed that to "main" by now! SHAAAAAME! 🔔

@ghost
Copy link

ghost commented Jan 24, 2023

I agree with the comments here. Not sure how npm ci "isn't intended for CD" but it's undoubtedly more consistent than npm install, which should always be the number one concern for any automation. Also from all of my tests, it's significantly faster than npm install and utilizes caches just fine in GitHub Actions.

Edit: Also, @markkasaboski, I think your step 2 should use NODE_ENV=development instead because devDependencies are needed for builds. The only time NODE_ENV=production should be used is when you're installing Node onto the actual production environment, but here you are using it to build artifacts which are then sent to the production environment (Netlify's CDN).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants