-
Notifications
You must be signed in to change notification settings - Fork 9
Component Based Development
A lot of the major JS frameworks are headed towards component based architecture. Angular 2 is all about components. The benefits include reusability, composability, reduced complexity, encapsulation, easier to test, easier to modify without mangling the whole app, and so on.
- See Angular's new component function
- See Guide to refactor apps to component style (Long read but good principles)
The metaphor used to explain Atomic Design is a good way to think of component based development. Atomic design puts an emphasis on composability of components.
- Are concerned with how things look.
- May contain both presentational and container components inside, and usually have some DOM markup and styles of their own.
- Have no dependencies on the rest of the app, such as services or parental controllers.
- Don’t specify how the data is loaded or mutated.
- Receive data and callbacks exclusively via scope.
- Rarely have their own state (when they do, it’s UI state rather than data).
- Example: Think of simple HTML DOM elements like an anchor tag. It knows nothing about the app and relies on the app setting the
href,title, etc.
- Are concerned with how things work.
- May contain both presentational and container components inside but usually don’t have any DOM markup of their own except for some wrapping divs, and never have any styles.
- Provide the data and behavior to presentational or other container components.
- Provide app events or actions as callbacks to dumb components.
- Are often stateful, as they tend to serve as data sources.
- Need access to external app-level state.
Whenever possible, build reusable dumb components, not only because of the re-usability, for by removing application awareness and state, the complexity of the component is reduced. When a component knows nothing about the app, there are fewer parts of the code which may break when making app-level changes.
If you are creating smart components often, think about whether the state should be managed at a higher level instead of within the component itself; many things which may initially seem like they should be aware of app-level state can be a dumb component included within a higher-level smart component.
Further reads (still good even thought these are React based):
- This article has good principles for decomposing an app into components and identifying what type of component it should be.
- React Dumb component
- React Smart component
- Container and Presentation components
Routes are smart components that configure UI-Router. This means the index.js file for a route will be short and sweet:
// src/desktop/routes/home/index.js
module.exports = ngModule => {
// Include the component for the route
ngModule.component('home', require('./home.component.js'));
// Configure UI-Router
ngModule.config($stateProvider => {
$stateProvider.state('home', {
url: '/',
template: '<home></home>'
});
});
};This structure can be generated automatically by running $ plop route.
Since each route is a smart component, it should focus on getting data for services but not presentation. It should create a simple layout with child components and pass scope data to them. Its CSS file should be very short.
These files and folders will exist when you clone starter-kit.
src/
common/
components/
filters/
services/
styles/
index.js (creates a common module)
desktop/
components/
containers/
routes/
desktop.config.js
desktop.css
desktop.html
desktop.init.js
index.js (bootstraps the desktop app)
responsive/
(similar to desktop)
This is an opinionated setup that is optimized for our team's style of development. Here are some of the benefits:
- Easy to automate workflows with da-plop
- Easy to define guidelines (harder to mess up!)
- Allows for automatic module importing
- In General
- Components that we could potentially pull out into
da-bitsor other shared code - Dumb components: just inputs and outputs
- Reusable components that aren't tied to specific data queries, etc.
- Components that we could potentially pull out into
-
common/components- For loading purposes: don't include anything you don't intend to use on both platforms
-
desktop/componentsandresponsive/components- Components that are reusable on that platform, but not the other
- Example: You reuse a chart component on several desktop views, but don't use the chart on mobile
- Smart components: they depend on data or services from other places