3

Independent Components: The Web’s New Building Blocks

 3 years ago
source link: https://blog.bitsrc.io/independent-components-the-webs-new-building-blocks-59c893ef0f65
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

The road to full independence

An independent component goes through a series of steps, starting with a few source files and ending in a set of shareable git-like objects.

Keep in mind that much of the following steps are automated by Bit.

1*MiVQjyptOjcY5-dsb2fcAQ.png?q=20
independent-components-the-webs-new-building-blocks-59c893ef0f65
The path of an independent component, from multiple source files to a set of shareable git-like objects. Much of the steps are autogenerated by Bit.

1. Starting with a few files

$ cd <path/to/workspace-directory>
$ bit init --harmony
$ bit create <component-template>

Every independent component starts its journey as a regular component. That can be done by pre-configured templates or by creating your own files.

2. Mapping files to a single abstract unit, a component

$ bit add <path/to/component>

The component’s files are mapped to a single component ID. This is key to versioning and configuring multiple files as one discrete unit, a component.

Bit auto-generates the .bitmap file to track ‘components’ in a Bit workspace. The .bitmap file will later reference to specific component versions used by the workspace (the working directory).

/* THIS IS A BIT-AUTO-GENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. */{
"button": {
"scope": "",
"version": "",
"mainFile": "index.ts",
"rootDir": "components/ui/button"
},
"trim": {
"scope": "",
"version": "",
"mainFile": "index.ts",
"rootDir": "components/utils/trim"
},
}

3. Configuring a component with dependencies and a development environment setup

When authoring components in a monolithic project, the dependencies, development environment setup, and CI/CD, are all configured on the project as a whole. An independent component, on the other hand, has all configurations set on it as an independent project. These configurations will eventually be stored as part of the component’s metadata.

Once an independent component is cloned (‘imported’) into another Bit workspace, its runtime and development environment are generated using its metadata. This step is crucial for simple and easy component-driven collaboration.

Bit uses a combination of tools and methodologies to simplifiy the process of component configuration. It does so by:

1. Auto-generating the component’s dependency-graph

2. Using a central configuration file to set configurations on group of components in a cascading, CSS-like, way (instead of manully setting up the configurations of every individual component).

3. Encapsulating pre-configured development environments into a single indepndent component. These environment components, as well as other components used for development, are then registered as dependencies of the authored component.

4. Generating the component’s distributable code and artifacts

$ bit build <component-id>

In addition to a component’s source files and configurations, an independent component encapsulates in it its compiled code, generated node package, documentation, and other artifacts valuable for consumers and maintainers of that component.

The component build process happens in a separate directory, isolated from the components hosting project, its workspace, to ensure a component is truly independent.

A component tested inside its workspace may pass all tests but still fail once consumed in a different project. That may happen when packages and files are present in the hosting project, the Bit workspace, but are missing from the component’s configurations (and therefore will not get generated in the isolated direcoty).

5. Tagging a component with a release version

$ bit tag <component-id> <version> --message "message"

The tag command executes the component build. For the sake of clarity, the two steps were separated.

Once a component has gone through its build process it is ready to have its source code, configurations, and artifacts committed and tagged with a new release version. This process uses git under the hood but is not identical to the way git works.

Much like git, Bit handles component versioning using content-addressable storage that uses hashes and objects to manage the versioned component’s files and metadata. Bit’s storage for component’s release version is called “scope”. You’ll find it in the .bit or .git/bit directory at the root of your Bit workspace.

Run bit cat-scope to list all objects in your local scope.

1*-kdVjp_45BfRdyDD5HkTPA.png?q=20
independent-components-the-webs-new-building-blocks-59c893ef0f65

Learn more about Bit objects here:

Exporting and importing independent components

Exporting (pushing)

$ bit export
  • When exporting a component, its objects are pushed to a remote scope.
  • Objects relating to different components can be pushed to different remote scopes, each according to the scope configured specifically for it.

Importing (cloning)

$ bit import <component-id>
1*gEEubDCfj8i-6MHjlGb3UQ.png?q=20
independent-components-the-webs-new-building-blocks-59c893ef0f65

When importing a component into a Bit workspace the following steps take place:

  1. The component’s objects are downloaded to the workspace .bit/ .git/bit directory.
  2. The component’s source files are extracted from its object and placed at the workspace root, nested in a directory named by the component scope (workspace-dir-name/component-scope-name/component-name/... )
  3. The component's package.json file and dist directory are extracted from the component’s objects. They’re placed in the workspace node_modules directory. The component’s source files are symlinked to that directory, as well (workspace-dir-name/node_modules/@scope-owner-name/component-scope-and-name ).
  4. The component’s dependencies are installed.
  • The component’s configurations are downloaded and extracted, as well. To see your imported component configurations run: $ bit show <component-id>

For example:

1*vAqCx5OORnxLfQ2vDT6H3w.png?q=20
independent-components-the-webs-new-building-blocks-59c893ef0f65

Building the web with independent components

Microservices and Micro Frontends

1*C-505B4iv9pP_LSjJJYaSQ.jpeg?q=20
independent-components-the-webs-new-building-blocks-59c893ef0f65

Microservices and Micro Frontends, in all their shapes and forms, are all about end-to-end modularity. That is, maintaining separate services or features as decoupled codebases that are authored, maintained, and delivered independently. Both of these architectural styles aim to achieve more resilient software and more effective collaboration.

A key element of all Microarchitectures is structuring applications out of decoupled, small and simple codebases, that are easy to understand, develop and test. In addition to that, working on decoupled codebases opens up the way to more effective collaboration that is between autonomous teams working together in parallel.

Independent components can play various roles in backend and frontend applications. They can play the role of (in-memory) libraries or that of separately-run apps and services that communicate over the network (as mentioned earlier, an independent component has its own CI/CD setup).

Regardless of the way they’re used, independent components serve as the perfect building blocks of every Microarchitecture.

Monorepos

1*b1jdYtQEO2XaLjnBlrFR1Q.png?q=20
independent-components-the-webs-new-building-blocks-59c893ef0f65

A Monorepo is a single repository used for several projects. It is a way to centralize the development workflow, share code more easily, and simplify the dependency management of 3rd party libraries. A Monorepo DRYs up your organization’s code and enables cross-project and business-centric collaboration.

As mentioned earlier, Bit not only generates the dependency graph of each component but also that of the entire workspace. Changes made to a single component are propagated onwards to dependent components, triggering component builds and versioning.

When used with Bit.dev for component hosting and CI, each independent component becomes part of one virtual Monorepo where changes to one component not only propagate inside the limits of the same workspace but across all (and only) dependent components hosted on Bit.dev.

Independent components provide all the benefits of a traditional Monorepo, without well-known scalability challenges, like inefficient builds and version control.

Design systems and component libraries

0*TdQDCJ3ln9ofQCHA?q=20
independent-components-the-webs-new-building-blocks-59c893ef0f65

Component libraries are a great way to share code and keep a consistent design & behavior across decoupled projects.

A component library built as a single monolith is versioned as a single unit, built as a single product, and consumed as a single package. All that affects consuming projects in unwanted ways, such as an unnecessarily large bundle size (tree-shaking is not flawless), meaningless updates (updates that have nothing to do with the components a project actually uses), and more.

Independent components solve many well-known challenges produced by monoliths but offer much more than that. One such benefit is the ease with which better architectural styles can be implemented.

Better architectural styles are styles that are focused on composability. They allow for flexibility in the way components are used and enable the rapid composition of larger structures, all the way to full applications.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK