env.jsonc

The env.jsonc file configures the dependencies and file types for components maintained by the env. It allows you to simplify and standardize the component configuration for components of the same type.

File types

Component files can be defined as dev files (as opposed to "runtime" or "production"), and can be configured to be loaded by a specific dev service.

For example:

{
  "patterns": {
    /**
     * a glob pattern for files to be loaded and previewed
     * */
    "compositions": ["**/*.composition.*", "**/*.preview.*"],
    /**
     * a glob pattern for files to be loaded and displayed as docs
     * */
    "docs": ["**/*.docs.*"],
    /**
     * a glob pattern for files to be loaded and executed as tests
     * (by whichever test runner is configured for the env)
     * */
    "tests": ["**/*.spec.*", "**/*.test.*"],
    /**
     * a glob pattern for files to be loaded by no specific dev service
     * but to be considered as dev files (replace "my-dev-files" with whatever name you want)
     * */
    "my-dev-files": ["**/*.dev.*"]
  }
}
CopiedCopy

Note that every file handled by a dev service is considered as a dev file.

Dependency configuration

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

Configure the dependencies for components maintained by the env in the "policy" entry. 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

Regular or "runtime" dependencies should rarely be configured using the env.jsonc. In most cases, simply installing a specific package version is enough (Bit will resolve to the version installed in the workspace).

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.

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

Peer dependencies

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" or consuming 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 dependencies

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).

Infer dev dependencies by file types

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

See the file types section above to learn how to configure files as dev files.

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

// @filename: welcome.test.ts

import _ from 'lodash';

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

Run the following to inspect your component's dependencies:

$bit
Copiedcopy

The output should include welcome.test.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) │ └───────────────────┴─────────────────────────────────────────────────────────────┘

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