Env Dependency Policy

The env dependency policy standardizes your component dependencies. That includes the dependencies used for your component development, component previewing, and for the execution of components in production.

See the section below to learn about alternative dependency configurations:

workspace.jsonc

The workspace dependency policy, configured in the workspace.jsonc file, is the default policy for all components in a workspace. It is applied on all components that use the relevant dependency, and is overridden by more specific policies.

The workspace policy is mostly automated. Dependency versions are resolved to the ones installed in the node_modules directory.

To install new dependencies see Dependency installation
To change the semver range of an existing dependency, see Dependency policies

Modifying the env dependency policy

Modify your env dependencies by updating your env's env.jsonc file. For example, the following sets classnames version ^2.0.0, as a runtime (regular) dependency of your env's components:

// @filename: env.jsonc
{
  "policy": {
    "runtime": [
      {
        "name": "classnames",
        "version": "^2.0.0"
      }
    ]
  }
}
CopiedCopy

Update your workspace node_modules directory by running the following:

$bit
Copiedcopy
See command synopsis

Verify the dependency update was successful by inspecting your components' dependencies. For example:

$bit
Copiedcopy

The output lists "classnames" with the proper dependency type and version, assuming this component is detected using classnames:

┌──────────────────┬────────────────────────────────────────────────────┐ │ id │ my-org.my-scope/pages/welcome │ ├──────────────────┼────────────────────────────────────────────────────┤ │ env │ my-org.my-scope/envs/my-react-env │ ├──────────────────┼────────────────────────────────────────────────────┤ │ dependencies │ classnames@^2.0.0--------------------- (package) │ └──────────────────┴────────────────────────────────────────────────────┘

By default, the dependency policy only affects components that use the dependencies listed in that policy. To forcefully add a dependency, see the Add dependencies forcefully section.

Add dependencies forcefully

By default, env dependencies only affect components detected using the dependencies listed in the policy. For example, if the pages/welcome component does not include any import ... from "classnames" statement , classnames will not be added to its dependency graph. The force property allows you to override this default behavior, and add a dependency to components that are not detected as using that dependency.

// @filename: env.jsonc
{
  "policy": {
    "runtime": [
      {
        "name": "classnames",
        "version": "^2.0.0",
        "force": true
      }
    ]
  }
}
CopiedCopy

Remove dependencies forcefully

Use the "-" notation in combination with the "force" property, to remove dependencies from components.

For example, the following components uses the themes/my-theme component in its compositions file:

// @filename: welcome.composition.tsx

import { MyTheme } from '@my-org.design/themes/my-theme';
import { Welcome } from './welcome';

export const DarkWelcome = () => (
  <MyTheme dark>
    <Welcome />
  </MyTheme>
);
CopiedCopy

Bit automatically detects this dependency and resolves it as a dev dependency, since it is only used by a dev file.

To forcefully remove this dependency as a dev dependency and configure it, instead, as a peer dependency, use the following config:

// @filename: env.jsonc
{
  "policy": {
    "dev": [
      {
        "name": "@my-org.design/themes/my-theme",
        "version": "-",
        "force": true
      }
    ],
    "peers": [
      {
        "name": "@my-org.design/themes/my-theme",
        "version": "0.0.2",
        "supportedRange": "0.0.2"
      }
    ]
  }
}
CopiedCopy

Peers

Peer dependencies are dependencies that are expected to be included in a component's host application. Since peer dependencies play a special "public role" in an app, such as the medium of communication between modules or the app's global state, they are required to exist in just a single instance, a single version.

When previewing components (docs and compositions) your env serves as your components' host application. That makes every peer dependency of your component, a regular ("runtime") dependency of your env.

For example, the following configures react as a peer dependency:

// @filename: env.jsonc
{
  "policy": {
    "peers": [
      {
        "name": "react",
        /* the version to be used by the env */
        "version": "^17.0.0",
        /* the versions of react your components are compatible with */
        "supportedRange": "^16.8.0 || ^17.0.0"
      }
    ]
  }
}
CopiedCopy

Run the following to inspect your env's dependencies:

$bit
Copiedcopy

The output lists react as a regular dependency, with version ^18.0.0:

┌──────────────────┬───────────────────────────────────────┐ │ id │ my-org.my-scope/envs/my-react-env │ ├──────────────────┼───────────────────────────────────────┤ │ env │ teambit.envs/env │ ├──────────────────┼───────────────────────────────────────┤ │ dependencies │ react@^18.0.0------------ (package) │ └──────────────────┴───────────────────────────────────────┘

Run the following to inspect one of your components' dependencies:

$bit
Copiedcopy

The output lists react as a peer dependency, with a wide range of possible versions:

┌────────────────────┬──────────────────────────────────────────────┐ │ id │ my-org.my-scope/pages/welcome │ ├────────────────────┼──────────────────────────────────────────────┤ │ env │ my-org.my-scope/envs/my-react-env │ ├────────────────────┼──────────────────────────────────────────────┤ │ peer dependencies │ react@^17.0.0 || ^18.0.0-------- (package) │ └────────────────────┴──────────────────────────────────────────────┘

Dev

Dev dependencies are dependencies that are used by components solely for development. Since they're not used during runtime, they are excluded from the components' production code.

Dev dependencies such as type declaration packages (under the @types organization) aren't detected by Bit as there are no corresponding require/import statements in the component files. To forcefully add them to the components' graph, set their "force" property to true.

//  @filename: env.jsonc
{
  "policy": {
    "dev": [
      {
        "name": "@types/react",
        "version": "^18.0.0",
        "hidden": true,
        "force": true
      }
    ]
  }
}
CopiedCopy
Hiding dev dependencies

It is recommended to set the dev dependencies' "hidden" property to true to hide them from Bit's dependency inspection tools. Components are developed using their env, which makes this list of standardized dev dependencies, superfluous information for maintainers of these components (as opposed to maintainers of the env).

Configure files as dev files

Bit infers the type of a dependency as dev dependency when it is consumed only via the component's dev files.

Configure a file as a dev file by adding its glob pattern to the "patterns" property. This can be done by extending an existing array of glob patterns or by adding a new array.

// @filename: env.jsonc
{
  "patterns": {
    "compositions": ["**/*.composition.*", "**/*.preview.*"],
    "docs": ["**/*.docs.*"],
    "tests": ["**/*.spec.*", "**/*.test.*"],
    /* a custom array of dev file glob pattern */
    "my-dev-files": ["**/*.dev.*"]
  }
}
CopiedCopy

Extending an array will not only set the file as dev file but also as a file that is loaded by that specific dev service.

In the following example lodash is considered as a dev dependency as it is only consumed via this custom dev file:

// @filename: welcome.dev.ts

import _ from 'lodash';

export const isString = _.isString('hello');
CopiedCopy

Run the following to inspect your component's dependencies:

The output should include welcome.dev.ts as a dev file, and its dependency, lodash, as a dev dependency:

┌───────────────────┬─────────────────────────────────────────────────────────────┐ │ id │ my-scope/pages/welcome │ ├───────────────────┼─────────────────────────────────────────────────────────────┤ │ env │ my-org.my-scope/envs/my-react-env │ ├───────────────────┼─────────────────────────────────────────────────────────────┤ │ dev files │ welcome.dev.ts (@my-org/my-scope.envs.my-react-env) │ ├───────────────────┼─────────────────────────────────────────────────────────────┤ │ dev dependencies │ @my-org/my-scope.envs.my-react-env (component) │ │ │ lodash@^2.3.2----- (package) │ └───────────────────┴─────────────────────────────────────────────────────────────┘

Runtime

Runtime dependencies (regular/production dependencies) are dependencies that are part of the components' production code. Unlike peer dependencies, runtime dependencies are used by the components and not by their env.

// @filename: env.jsonc
{
  "policy": {
    "runtime": [
      {
        "name": "classnames",
        "version": "^2.0.0"
      }
    ]
  }
}
CopiedCopy

By default, dependency policies only affect components that are detected using the dependencies listed in the policy. To learn more, see Add dependencies forcefully.

The env dependency policy is great for standardizing your components' dependencies. To set a specific dependency configuration on a component or a group of components, instead of a single standardized version for all your env's components, use the dependency configuration.

For example:

$bit
Copiedcopy
See command synopsis