Skip to content

Commit

Permalink
In monorepo root, disallow dependencies in favor of devDependencies (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
VanTanev authored Nov 20, 2024
1 parent 4c32679 commit 1a5ea55
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 14 deletions.
5 changes: 5 additions & 0 deletions .changeset/wicked-points-own.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@manypkg/cli": minor
---

Change the `ROOT_HAS_DEV_DEPENDENCIES` rule to `ROOT_HAS_PROD_DEPENDENCIES`. Monorepo root should use `devDependencies` instead of `dependencies` for better support of production-only installs, useful in eg Docker builds.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,15 +294,15 @@ This is so that `peerDependencies` are available in the package during developme

The range for the dependency specified in `peerDependencies` is added to `devDependencies` unless the package is already a non-peer dependency elsewhere in the repo in which, that range is used instead.

## Root has devDependencies
## Root has prod dependencies

Key: `ROOT_HAS_DEV_DEPENDENCIES`
Key: `ROOT_HAS_PROD_DEPENDENCIES`

The root package should not have any `devDependencies`, instead all dependencies should be in `dependencies`
The root package should not have any production `dependencies`, instead all dependencies should be in `devDependencies`.

### Why it's a rule

The root `package.json` of a monorepo is not published so whether a dependency is in `devDependencies` or `dependencies` does not make a difference and having one place to put dependencies in the root means that people do not have to arbitrarily decide where a dependency should go every time they install one.
The root `package.json` of a monorepo is not published so whether a dependency is in `devDependencies` or `dependencies` does not make a difference and having one place to put dependencies in the root means that people do not have to arbitrarily decide where a dependency should go every time they install one. We prefer `devDependencies` because a monorepo root should contain only tooling dependencies.

### How it's fixed

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"jest-watch-typeahead/testname"
]
},
"dependencies": {
"devDependencies": {
"@babel/core": "^7.20.5",
"@babel/plugin-transform-runtime": "^7.19.6",
"@babel/preset-env": "^7.20.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,31 @@ import pc from "picocolors";
import { Package } from "@manypkg/get-packages";

type ErrorType = {
type: "ROOT_HAS_DEV_DEPENDENCIES";
type: "ROOT_HAS_PROD_DEPENDENCIES";
workspace: Package;
};

export default makeCheck<ErrorType>({
type: "root",
validate: (rootWorkspace) => {
if (rootWorkspace.packageJson.devDependencies) {
return [{ type: "ROOT_HAS_DEV_DEPENDENCIES", workspace: rootWorkspace }];
if (rootWorkspace.packageJson.dependencies) {
return [{ type: "ROOT_HAS_PROD_DEPENDENCIES", workspace: rootWorkspace }];
}
return [];
},
fix: (error) => {
error.workspace.packageJson.dependencies = sortObject({
error.workspace.packageJson.devDependencies = sortObject({
...error.workspace.packageJson.devDependencies,
...error.workspace.packageJson.dependencies,
});

delete error.workspace.packageJson.devDependencies;
delete error.workspace.packageJson.dependencies;
},
print: () => {
return `the root package.json contains ${pc.yellow(
"devDependencies"
)}, this is disallowed as ${pc.yellow("devDependencies")} vs ${pc.green(
"dependencies"
)}, this is disallowed as ${pc.yellow("dependencies")} vs ${pc.green(
"devDependencies"
)} in a private package does not affect anything and creates confusion.`;
},
});
4 changes: 2 additions & 2 deletions packages/cli/src/checks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import INTERNAL_MISMATCH from "./INTERNAL_MISMATCH";
import INVALID_DEV_AND_PEER_DEPENDENCY_RELATIONSHIP from "./INVALID_DEV_AND_PEER_DEPENDENCY_RELATIONSHIP";
import INVALID_PACKAGE_NAME from "./INVALID_PACKAGE_NAME";
import MULTIPLE_DEPENDENCY_TYPES from "./MULTIPLE_DEPENDENCY_TYPES";
import ROOT_HAS_DEV_DEPENDENCIES from "./ROOT_HAS_DEV_DEPENDENCIES";
import ROOT_HAS_PROD_DEPENDENCIES from "./ROOT_HAS_PROD_DEPENDENCIES";
import UNSORTED_DEPENDENCIES from "./UNSORTED_DEPENDENCIES";
import INCORRECT_REPOSITORY_FIELD from "./INCORRECT_REPOSITORY_FIELD";
import WORKSPACE_REQUIRED from "./WORKSPACE_REQUIRED";
Expand All @@ -14,7 +14,7 @@ export let checks = {
INVALID_DEV_AND_PEER_DEPENDENCY_RELATIONSHIP,
INVALID_PACKAGE_NAME,
MULTIPLE_DEPENDENCY_TYPES,
ROOT_HAS_DEV_DEPENDENCIES,
ROOT_HAS_PROD_DEPENDENCIES,
UNSORTED_DEPENDENCIES,
INCORRECT_REPOSITORY_FIELD,
WORKSPACE_REQUIRED,
Expand Down

0 comments on commit 1a5ea55

Please sign in to comment.