The argument to put most dependencies under
dependencies instead of
devDependencies can actually go both ways. More commonly I see people start with putting everything in
dependencies but should lean towards
devDependencies, and figure out how to use it properly. See the two scenarios below. This conversation revolves around using webpack, but is applicable to most projects.
Scenario 1: If your project needs to run webpack in the production environment before serving
Packages required to build the webpack project are under dependencies, rather than
devDependencies. Node is historically used as a “server”, and still considered true. For webpack (and many react) projects, we are actually using webpack as a build tool, which translates to our project being considered a “source project” waiting to be built. We now also call our project a “build server”.
In this scenario, our project is no longer considered the “front end app”, but instead “the project that builds the front end app”. Assuming the statement above to be reasonable, dependencies are the requirements to build this project and
devDependencies will have things that are not related to building, such as unit testing.
Scenario 2: If our project does not need to run webpack in the production environment, and has a pre-built copy to serve (or require by other projects)
This scenario is if we do not need to run webpack in production and we only serve the pre-built files in a node server. This means our project will need to ship with our build folder. The webpack and app dependencies can be placed in
This scenario is also used if we are creating library packages, instead of servers. Others will install the project as a package, and require the pre-built files in their project. If one wishes to help develop our package, then they can clone and install it with
devDependencies to enable webpack building.
A caveat to this scenario is that for production, one must have already built using webpack in a development environment.
Webpack projects should be considered build-type projects first, and not production-type projects unless webpack is used in production. Packages needed during production go in
dependencies, and packages used just to develop the project go in
devDependencies. If our production environment needs to build (run webpack), then those dependencies must reside in dependencies.
Of course, one can always put everything in
dependencies, but if we are looking to publish our project for others to use or require, then this will consequently bloat their projects’
node_modules folder unnecessarily. Scenario 2 should be the way to go: exhaust
devDependencies unless it is required otherwise.
That’s it! That’s all you need to know!
Whichever scenario you find yourself in, I would love to know if there are any other pitfalls and caveats!
- We are generally in scenario 1 if webpack builds to a folder under .gitignore
- React’s usage of environment variables, such as the
NODE_ENVvariable in scenario 1 will generally be correct.
- In scenario 2, to rebuild using webpack we must
run npm installwith the environment variable
NODE_ENV=development(default) rather than
NODE_ENV=production. We must define separately the proper
NODE_ENV(and other variables) when running webpack depending on whether we are building for production or for development.
- Of course, if we just have the project as just a web server that dishes out the already-built webpack project (from elsewhere), then the webpack dependencies don’t belong in either
devDependencies(they belong nowhere since they’re already packed in the build! ?). If we develop our webpack/app within the same project as the server, however, then we are effectively in scenario 2 above and need the appropriate
- To keep things simple, most projects, typically small or starter web projects will fall under scenario 1, so they can build and serve at the same time during production. As the project scales, one may find themselves splitting up their server and the webpack app into separate commands or even projects, which will require them to be in scenario 2.
- If we use webpack to build an app to deploy somewhere, and no other person or project depends on it, then none of this matters.
When developing your project, one shouldn’t be calling
NODE_ENV=production npm install anyway.
A browser app built by webpack has no node dependencies. However, many projects not only serve but also build during production. It is true that this is an unconventional use of the word “build” for node developers (in scenario 1), as building typically refers to doing it before production instead of during. Instead of build and run in separate commands, it’s more like “build-to-run” in one.