Tracking Component's Dependencies
Bit manages a component’s package and file dependencies.
A component may use packages or import
files/components to work. Bit reads through all require
and import
statements for the components it tracks.
There are two dependencies a component may have, Package Dependencies and File Dependencies.
- Bit creates
package.json
for all package dependencies. - Bit should track all file dependencies. They can be a part of the same component or another one.
Note
If a project uses absolute imports or aliases, we need to configure it.
Package Dependencies
Components can import
external packages. Bit resolves those dependencies.
Here’s an example for a component with a package dependency:
.
├── node_modules
| └── left-pad
├── package.json
└── src
├── hello-world.js
└── index.js
index.js
export {default} from './hello-world';
hello-world.js
import leftPad from 'left-pad';
export default function hello(world) {
return leftPad(`hello ${world}`, 20, '-');
}
package.json
{
"dependencies": {
"left-pad": "^2.1.0"
}
}
In this example, the package left-pad
is in the project’s node_modules
directory. The package version range is in the project’s package.json
file. The file hello-world.js
requires the package left-pad
.
Let’s track the hello/world
component and follow Bit’s steps to resolve dependencies.
$ bit add src/hello-world.js src/index.js --id hello/world
tracking component hello/world:
added src/hello-world.js
added src/index.js
We get one component that depends on the package left-pad
. The version Bit sets for the dependency is the same version as defined in the project’s package.json
file. In this case, it’s ^2.1.0
.
If no package version found in the package.json
file, Bit resolves it from the node_modules
directory. Bit then sets the exact version - 2.1.0
(assuming that’s the actual version installed).
Verify Bit has resolved all dependencies using bit status.
$ bit status
new components
> component/hello-world... ok
Use bit show to check which version Bit has resolved for each package dependency.
$ bit show hello/world
┌───────────────────┬─────────────────────────────────────────────────────────────────────┐
│ ID │ hello/world │
├───────────────────┼─────────────────────────────────────────────────────────────────────┤
│ Language │ javascript │
├───────────────────┼─────────────────────────────────────────────────────────────────────┤
│ Main File │ src/hello-world/index.js │
├───────────────────┼─────────────────────────────────────────────────────────────────────┤
│ Packages │ left-pad@^2.1.0 │
├───────────────────┼─────────────────────────────────────────────────────────────────────┤
│ Files │ src/hello-world/hello-world.js, src/hello-world/index.js │
└───────────────────┴─────────────────────────────────────────────────────────────────────┘
Handling missing package dependencies
In some cases, Bit prompts the message ‘missing package dependencies’ when running bit status or bit tag.
$ bit status
new components
> hello/world... missing dependencies
missing packages dependencies: left-pad
Bit prompts the missing package dependencies
if it is unable to resolve all package dependencies. Bit is unable to isolate such components. To resolve this issue, we need to verify all required packages are in the repository’s package.json
file.
File Dependencies
A component can depend on other files. To isolate such components, we need to track these files as well. This is because the component must have these files around if we want to use it in another project.
Bit recognizes these files by reading the import
and require
statements. Once Bit has the list of files, it tries to figures out whether it tracks them. There are several cases for this situation:
- Bit already tracks a required file as part of the tracked component.
- A required file can be part of another component in your project. Bit creates a dependency relationship between the two components.
- If Bit does not track the file at all, it warns about
untracked file dependencies
on bit status or bit tag
Untracked file dependencies
If we encounter an untracked file dependencies
error, we need to resolve it to isolate the component. First, let’s view this example:
.
├── bit.json
├── package.json
└── src
├── hello-world
│ ├── hello-world.js
│ └── index.js
└── utils
└── noop.js
index.js
export {default} from './hello-world';
hello-world.js
import noop from '../utils/noop';
export default function hello(world) {
noop();
return `hello ${world}`;
}
noop.js
export default () => {};
Let’s track the hello/world
component:
$ bit add src/index.js src/hello-world --id hello/world
tracking component hello/world:
added src/hello-world.js
added src/index.js
When running bit status, an untracked file dependencies
warning appears.
$ bit status
new components
> hello/world... missing dependencies
untracked file dependencies: src/utils/noop.js
Bit has read the require
statement for src/utils/noop.js
. However, Bit does not track the file. So Bit is unable to isolate the hello/world
component. The error forbids it.
There are two ways to resolve this isolation issue.
Add an untracked file dependency to an existing component
We can add untracked file dependencies to an existing component.
Let’s continue the flow from the previous section and append src/utils/noop.js
to the component. Rerun bit add
. Track the selected file and set the --id
to the preexisting component.
$ bit add src/utils/noop.js --id hello/world
tracking component hello/world:
added src/hello-world.js
added src/index.js
added src/utils/noop.js
Rerun bit status and see that Bit can isolate the component.
$ bit status
new components
> component/hello-world... ok
Track an untracked file dependency as a new component
We can choose to create a new component from an untracked file dependency. To do this, we need to track the untracked files as a new component. This resolves the missing file dependency issue. Bit then creates a dependency relationship for components with file dependencies between them.
Let’s try resolving the prior untracked file dependency, but this time by adding a new component.
$ bit add src/utils/noop.js --namespace utils
tracking component utils/noop:
added src/utils/noop.js
The result is a new component, which is now a dependency of the hello/world
component.
› bit status
new components
> hello/world... ok
> utils/noop... ok
Custom Module Resolution
Some projects use a Custom Module Definition feature. We need to define them to Bit for it to resolve the dependencies.
Some examples for common frameworks that allow Custom Module Definition:
- Webpack resolve
- tsconfig resolving
- Vue absolute paths
- Babel module resolver
NODE_PATH
environment variable
When using Custom Module Definition, your code requires files using absolute paths. Bit assumes that requiring absolute paths means that you require a package and not a file. This is why Bit triggers a missing package dependency
warning.
Let’s use this example, and update it to use custom module resolution.
.
├── bit.json
├── package.json
└── src
├── hello-world
│ ├── hello-world.js
│ └── index.js
└── utils
└── noop.js
index.js
export {default} from './hello-world';
hello-world.js
import noop from '@/utils/noop';
export default function hello(world) {
noop();
return `hello ${world}`;
}
noop.js
export default () => {};
Now we track the component using this command:
$ bit add src/index.js src/hello-world --id hello/world
tracking component hello/world:
added src/hello-world.js
added src/index.js
The output of bit status
notifies on a missing package dependency for @/utils/noop
. This is not a package. To resolve this issue, we need to edit the project’s bit.json
and configure the following resovleModules
configuration:
"resolveModules": {
"aliases": {
"@": "src"
}
}
After defining the custom module resolution, Bit can find utils/noop
. Since we haven’t tracked src/utils/noop
yet, Bit marks it as an untracked file dependency. Resolving this issue is explained above.