Modular Front End Web Development

Using a modular approach in web development is nothing new or groundbreaking. It becomes an essential approach when dealing with large sites maintained over time. Here are some thoughts on our recent redesign of Goizueta's main external site.

Think in Components

When designing, don't think in terms of page templates, think of components that are assembled as pages. Each component is its own, independent piece that is fitted with others to make up pages. For Goizueta, each component has its own CSS file, and, if necessary, its own JavaScript file. Write components to be fluid width, agnostic to their placement within a page; let their width be implicitly determined by their containing elements. This makes it a relatively minor issue to move components into new contexts.

Extend, Extend, Extend

Read Scalable and Modular Architecture for CSS and apply what you've read. Start everything component from a generic implementation and extend with classes to more specific implementations. Let your basic HTML elements look like what they are. Don't reset styles, normalize styles. The first pass at styling a component should be as flexible as possible. Extend the component with additional, optional classes to modify its behavior for more specific instances. Make your CSS selectors as least specific as possible. Cascade styles with the minimum specificity required. Don't tie component styling to page regions.

Encapsulate Your JavaScript, Expose an Interface

A component that requires JavaScript is a component that requires a JavaScript object. If the component needs to be easily accessible to other components, write it as a module pattern in the global scope, exposing only the properties and methods needed. Otherwise write it within an immediately invoked function expression. If using jQuery, write a plugin interface for you objects. Write your JS objects with callbacks and triggers. Make it easy for  components to connect to each others' functionality as and when needed. You don't know all the ways you may want access at the beginning.

Use a CSS Preprocessor

CSS preprocessors are the biggest influences for more productive front-end development that I've seen. Use one. I use SASS. SASS + SMACSS is a winning formula.

Package Your Assets

With the modular, component approach, you end up with a whole lot of CSS and JS files. Separate your components into global, section, and page frequencies, and package your CSS and JS accordingly. You should have a global.js file  that contains all of your scripts that are required on 99% of pages, several [section].js files that contain scripts unique to specific sections, and [component].js files for components that are not consistently used in the site or a section. Same thing for CSS, except don't use [component].css files. CSS needs to be loaded to prevent FOUC. So you'll just have global.css and [section].css. Minify your CSS with your preprocessor. Uglify and minify your JS with a build tool like grunt.js.

Load As Needed

It should be obvious that every page will load the global.js and global.css, and that each section will load its [section].js and [section].css, but what about the [component].js scripts? Use a resource loader. For each component that doesn't make it at least into [section].js, test for the component's existence on the page and load the component's JS file. We're using yepnope and have had minimal problems. In the same vein, if a component requires another component to work, require that component via the resource loader. Yepnope keeps up with what has been loaded and what hasn't, so it won't load duplicate scripts. I hear more advanced resource loaders might take care of these dependencies for you, but I don't have the hands on experience to provide insight into it.

Conclusion

Building our site as an amalgamation of components caused some extra time during design and development. Building and testing each component individually results in extra testing time, but the benefits in maintainability and robustness far outweigh the initial time cost. We can iterate and improve components without worrying about how it will affect other pieces. We can add, remove, and replace components on pages without consequence. Keep it modular, keep everything decoupled. Production and development files should be optimized for each environment: lots of commented development files, few minified production files. Moving forward, we hope to also move our content to more modular, structured storage and presentation.