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.