Using a Static Dependency Policy in a Legacy Env

ed
eden-e11 months ago

The env.jsonc file was recently introduced along with other major upgrades to the envs API. The file, which is located at the root of the env directory, lists the dependency policy for components using that env.

The env.jsonc file offers 2 main improvements, compared to the previous getDependencies and overrideDependencies APIs:

  1. Since it is a static JSON file, and not a function, Bit can read its dependency configuration without running the env. This means Bit does not need to perform the installation process in order for it to get the list of dependencies set by the env (no need to install the dependencies required for the env to function, or to compile it). This, in turn, boosts the installation process as a single installation is needed instead of two, or more.
  2. The env.jsonc file can be used as dependency policy or as a dependency configuration. This means you you can use it to define how dependencies should be resolved, if they are consumed by the component, or alternatively, to define the dependencies a component should have, even if they not detected in that component.

Use the right env.jsonc file for your env

The following lists the different env.jsonc files you can use, depending on the type of env you are using. Copy the content of the relevant file to a new env.jsonc file, that should be created at the root of your env directory.

Note that once you include the env.jsonc file in your env directory, you completely override the getDependencies and overrideDependencies APIs.

Move dependency configuration to env.jsonc

The following example is of a legacy React env that uses the overrideDependencies API to extend the default legacy React env dependencies with react-router-dom:

/* @filename: my-legacy-env/my-legacy-env.main.runtime.ts */

import { MainRuntime } from '@teambit/cli';
import { ReactAspect, ReactMain } from '@teambit/react';
import { EnvsAspect, EnvsMain } from '@teambit/envs';
import { MyLegacyEnvAspect } from './my-legacy-env.aspect';

export class MyLegacyEnvMain {
  static dependencies = [ReactAspect, EnvsAspect];
  static runtime = MainRuntime;
  static async provider([react, envs]: [ReactMain, EnvsMain]) {
    const MyLegacyEnvEnv = react.compose([
      react.overrideDependencies({
        peerDependencies: {
          'react-router-dom': '6.11.2',
        },
      }),
    ]);
    envs.registerEnv(MyLegacyEnvEnv);
    return new MyLegacyEnvMain();
  }
}

MyLegacyEnvAspect.addRuntime(MyLegacyEnvMain);
CopiedCopy

To achieve a similar result with the new env.jsonc file, you can add the file to your env directory, and add the following content to it:

/* @filename: my-legacy-env/env.jsonc */

{
  "policy": {
    "peers": [
      {
        "name": "react-router-dom",
        /* the version to be installed and used by the env */
        "version": "6.11.2",
        /* the range of versions this env's components are compatible with */
        "supportedRange": "^6.11.2"
      }
    ]
  }
 // other policies...
}
CopiedCopy

The above configuration only affects components that are detected as using the react-router-dom dependency (i.e, it is only a policy). To add this dependency to all components, regardless of whether they use it or not, you can add the following configuration to the env.jsonc file:

/* @filename: my-legacy-env/env.jsonc */

{
  "policy": {
    "peers": [
      {
        "name": "react-router-dom",
        /* the version to be installed and used by the env */
        "version": "6.11.2",
        /* the range of versions this env's components are compatible with */
        "supportedRange": "^6.11.2",
        /* add this dependency to components, even if they don't directly import it */
        "force": true
      }
    ]
  }
   // other policies...
}
CopiedCopy

Run bit install to install the dependencies set by the env. Verify your components use the proper dependencies by running bit show COMPONENT_NAME.