Skip to content

Building better components

Samuel Rapana Betio edited this page May 13, 2018 · 1 revision

This page is dedicated to small tips and tricks for building better components.

Naming conventions

Component names should be lower-cased, and hyphenated when multiple words are used. For example model-timestamps, instead of Model-Timetamps or model_timestamps.

Retina support

Any component that uses Canvas should utilize autoscale-canvas for retina support without the user doing this manually. However if the user is in charge of the canvas, and you are simply drawing to it, delegate this task to the user. An example of this is the canvas progress indicator component.

Modularity

When an aspect of a component may be useful to others, consider writing that as a component as well. If it requires reasonable effort to write the code in the first place, chances are someone else could use it too. For example both the popular "piecon" and "tinycon" favicon manipulation libraries have their own code for changing the favicon dynamically via canvas (and more specifically a data uri). I've re-written these libraries as piecon and noticon, both sharing favicon to perform the change.

Use only what's necessary

Using bloated libraries and frameworks for your application may be fine, that is completely up to you, if it improves your development process then by all means continue. This includes libraries such as "underscore", which is certainly not large, however forcing it upon someone who wants to use your component may be unnecessary unless you actually use a reasonable portion of underscore in that component. For example if you used underscore simply to produce a sum, then consider using (or writing) smaller components such as sum. In your application it may be incredibly redundant and frustrating to manage several dozen dependencies, in which case, use underscore.

The point is that this fragmentation does not have to exist, we do not have to write "jquery plugins", "ember plugins" and so on, we can write javascript components that everyone can share. If you wish to use jquery in your application, that is completely acceptable, but if we build a strong foundation of cross-browser components our eco-system will flourish like never before, with drastically reduced duplicate effort.

Better abstractions

Components should have very specific goals in mind, and attempt to provide the most flexible solution they can, after which higher-level and potentially more user-friendly abstractions may be built upon. This helps form a solid foundation, as higher-level abstractions may prove leaky, you'll always have a lower-level component to fall back on.

Avoid large options objects

If your component truly only takes a few options, and are unlikely to change after the fact, then an options object may be suitable. I strongly suggest considering a fluent API, even if you provide an options object. This makes code considerably cleaner, as the fluent API can back each key in the options object, which otherwise would promote extremely large plugins. Remember build up to a user-friendly api, do not start there.

Module patterns

Avoid "module" patterns, for example wrapper functions like (function(){ ... })();, these are unnecessary with components, the commonjs module adds a wrapper function for you, the scope is yours to play with.

CSS urls

CSS should be written with relative url()s. For example if you have a file named ./images/logos/large.png, and css within ./style.css, you would use url(images/logos/large.png). By not making assumptions of url prefixes, consumers of components such as component-build(1) can rewrite these as needed. Absolute urls will remain untouched.

CSS prefix

From 1.0.0 component use autoprefixer to add css prefix on the build process, so most of times you don't need to add css prefix by hand and cleaner css code would make it easier to maintain.

Versioning

Use the <major>.<minor>.<patch> convention with semver, for example "1.2.0", not "v1.2.0" etc. Bump <patch> when only fixes are applied, bump <minor> when fixes and/or features are added, and bump <major> for any combination of the former and changes that break compatibility with previous releases.

Preview

Having to try components to distinguish them can often be tedious. Create a Github-page with an example of your component in use.