开发者

Modularizing web applications

I was wondering how big companies tend to modularize components on their page. Facebook is a good example:

There's a team working on Search that has its own CSS, javascript, html, etc..

There's a team working on the news feed that has its own CSS, javascript, html, etc...

... And the list goes on

They cannot all be aware of what everyone is naming their div tags and whatn开发者_开发问答ot, so what's the controller(?) doing to hook all these components in on the final page??

Note: This doesn't just apply to facebook - any company that has separate teams working on separate components has some logic that helps them out.

EDIT: Thanks all for the responses, unfortunately I still haven't really found what I'm looking for - when you check out the source code (granted its minified), the divs have UIDs, my guess is that there is a compilation process that runs through and makes each of the components unique, renaming divs and css rules.. any ideas?

EDIT 2: Thanks all for contributing your thoughts - the bounty went to the highest upvoted answer. The question was designed to be vague- I think it led to a really interesting discussion. As I improve my build process, I will contribute my own thoughts and experiences.

Thanks all! Matt Mueller


Web development definitely brings some organizational challenge. HTML/CSS is not exactly the dream environment for splitting work. It is very important to define certain rules and strictly follow them.

My personal tactic I have come to is to prefix the names in shared sources (like CSS or markup components) with some module suffix. If you keep to the strategy, it will uniquify the names globally.

For example:

instead of

div.question_title
div.question_body

you could use

div.so_question_title
div.so_question_body

div.su_question_title
div.su_question_body

Also agree with teams on some shared data like colors of the color scheme. Define them somewhere globally and reuse them everywhere.

Another issue arrives when teams are working on different parts of the same page. Here if you're developing a page component, you may find one day something is broken because the guys working on the page itself changed something and changes propagated down the element hierarchy.

For example, if you define a CSS style in this manner:

div.main_news *
{
    /* ... */
}

it would be asking for trouble. I suggest that you have at as a rule to define CSS styles with the minimum possible scope which is sufficient for some technique to work.

One possible workaround: each submodule firstly resets all the styles for its top-level hierarchy element, like:

div.news_container
{
    /* Reset styles */
}

so that you can now work on the module resting assured the changes in some parent elements would be stopped at your perimeter.

UPDATE: Regarding divs with UIDs. If you mean Facebook, I'm not sure what UIDs you are referring to. Only hidden inputs have some long cryptic IDs as their values (main page, not logged in), but this is likely the result of the framework automatically generating these values for some reason. I once wrote some code (for ASP.NET MVC) for Html helpers to generate unique IDs application-wide (I wanted to bind checkboxes with labels by IDs completely automatically and transparently for me). Another case could be that a stateful event-driven framework (such as ASP.NET WebForms) has unique IDs generated server side as a requirement to support its operation. Each control has to have some unique ID so that it is possible to know on the server side which element raised an event on a page. Also some WYSIWYG editors would add auto IDs to elements when you drag them and drop to a form.

This all aside, it is of course possible to have some pre-build script to go over the code and inject unique IDs into markup and CSS code portions. But you really need to know exactly what and why you are doing this. I'm personally of the opinion this "uniquization" in general can be achieved manually by enforcing some simple rules in a team, while some work can of course be automatized, like what I described above.


From my experience, no matter how well you try to standardize everything, for big teams complete coherence, with everyone doing the same things the same way is almost impossible.

Don't try to solve the problem at the "standards level" or the "how to" level... solve it at the human level, at the management level.

We use a couple of techniques to maintain coherence at the management level:

  • Maintain the tools for the developer to inform the rest. That includes Wikis, internal discussion forums and so on.
  • Have enough middle management available. No body can be aware of everything but it makes sense for a person to be aware of everything that is at his level. That way the User Management group can sync with the Security group and the Security Group can be in sync with the Content Management group. The mission of this middle management is to know enough about everything, the do not need to know every detail, just enough to pass it the knowledge where it should be.
  • Add levels as you see fit, but in every level there should be one person looking up everyone is doing more or less the same things. He will be in charge to raise alarms if two groups are doing things in completely different ways.
  • Maintain a good information flow. Having standards is important but allowing people to actually KNOW they exits is even better and ensuring they use them, through code revision and weekly meeting is completely needed if you want to keep doing things rigth.

I know a lot of people do not like "management". They think is an extra layer that does nothing. Well, that ain't true. Management helps to solve problems like exactly this. Help to communicate big teams and have a general view of what's happening... there are a lot of "techniques" to define a standard on how to do things... all that techniques fail when there isn't a human being making sure people follow know and follow those standards.


A namespace clashes problem can be avoided by using a naming convention. Additional reading:

  • CSS Practice: Pseudo-Namespaces in Complex Projects
  • CSS Namespaces Support - Functional and Design Specification

In short: It depends how your system is built, but assuming that everything is composed out of modules, then name your CSS identifiers (or JS IDs etc.) as follows: SiteName-ModuleName-Function.

If you're willing to use your application language (e.g. PHP) to intervene with the CSS/JS code, then an "arbitrary" naming may be used, by assigning each module it's dynamically-generated numeric id and attaching that id to the identifier of the client-side language object. For instance:

# PHP script
class module_articles {
    public function __construct() {
        $this->GUI = new view;
    }
    public function display_articles() {
        // The CSS file is rendered first by the PHP engine and
        // the identifiers name is constructed with the $this->GUI->id property.
        $this->GUI->load_css('path/to/file.css');
    }
}

class view {
    private static $instance_number = 0;
    public $id;

    public function __construct() {
        $this->id = ++ self :: $instance_number;
    }
    public function load_css($path) {
        // $id can also be the CSS file path (slashes replaced with underscore)
        // or the module name itself (e.g. module_articles)
        $id = $this->id;
        include $path;
    }
}

Eventually, the CSS file should be something like this:

/* CSS of module_articles */

<?php echo $id ?>author_name { /*...*/ }
<?php echo $id ?>article_date { /*...*/ }

Note: The file should be included via PHP's include keyword! Use Output Buffering to output it later.


There is a lot to be said for CSS Frameworks like Shaun Inman's CSScaffold. It lets you subdivide stylesheets, define constants, easily handle local contexts, etc. It doesn't solve your problem, but it can be a big help.

On the Javascript side, it is possible to work with local contexts, although I've rarely if ever run into problems.

Naming of HTML elements is definitely tricky, but HTML 5 should help (fewer id's and classes are necessary) and precompilation as you mention can be another option.


i worked with several one-page-web-app projects, from my experience

your diff teams should sit down once to setup some simple css convention

for example

mod-search.css

.mod-search .title { }
.mod-search .text { }

mod-news.css

.mod-news .title { }
.mod-news .text { }

in production use your fav front end do lump all the resources into one

also do the same to js, actually js is easier to manager than css

make sure each module is wrapped in its own closure

i am using YUI as an example

mod-search.js

(function(){
   var node = Y.Node.create('<div/>').addClass('mod-search'); 
   // hook your event to this module node only
   node.delegate('click', handleSearch, 'button.search');
}());

mod-news.js

(function(){
   var node = Y.Node.create('<div/>').addClass('mod-news'); 
   // hook your event to this module node only
   node.delegate('click', handleViewNews, 'a.view-news'); 
}());

all-in-one.js.php

//
// php set content type text/javascript
//
YUI().use('node', 'event', function(Y){
   // php include mod-new.js
   // php include mod-search.js
}); 

the HTML

<html>
    <head>
        <link href='all-in-one.css.php' rel='stylesheet' />
    </head>
    <body>
        <script src='all-in-one.js.php' ></script>
    </body>
</html>


If you really want to know, just open up firebug and go spelunking through the facebook site.

30 seconds later you'll find out they rarely apply css to divs through IDs; and instead use a lot of the dot class notation.

Once you go down this path, separating dev groups into functionality is a whole lot easier. You can have one core group that is responsible for the main "shell" using ID's. Everyone else you force to use dot classes.

You can further restrict this by giving each group a prefix to work in.


Some applications use a portal server which is used as a proxy. It sits in front of all these web/application servers. The portal server gets the data/feeds of HTML these servers and then adds a prefix/suffix to the tags making them unique.

In a way you are correct, there is a component which handles such things.


My company does Business Web Applications.

Most of the times we use a SOA Architectre with ADF or PHP frontend, so it does not matter how things are named, because most of the HTML is rendered from components (It reduces the freedom you have in free HTML, but makes it faster to develop).

Also our Teams are not organized by Topics, they are put in different technical areas, like Database, GUI or Performance.

The big advantage is, that you can reuse some of the Web-services in different Applications, without having to contact to original developer.


UI conventions should be documented when multiple teams are developing UIs.

Preferably you should have the same team write/design the UI for all components, then break up the other layers as needed.


This isn't something that should happen on the fly, it's baked in the company structure. No telling how Facebook or any other specific site/company does it, but it can be as simple as maintaining a single database table. Like:

project_namespace

  • id
  • namespace
  • directory

So, you've got your core application (1, 'core', '/htdocs/core'). There's probably a PM or senior in charge of it, and some monkeys to create & maintain it - an extra database table if HR isn't already managing that relation, but that's irrelevant here. Each namespace would require a common structure, ./css for CSS files, ./templates for HTML templates, ./js, ./images, and so on. Again, there can be a db table for that, but irrelevant to this example. Add any number of other teams - search (2, 'search', '/htdocs/search'), accounts (3, 'users', '/htdocs/users'), the web services guys (4, 'services', '/htdocs/services/') and so on. Each value is unique, and I'm just making this up so please ignore the lack of detail.

Now you've got your build process - a script or series of scripts that pulls everything from source control, runs the CSS and JS minifiers, and generally compiles all the disparate parts into a website. It loads the namespaces from the db table and prepends them (or just the unique IDs) to every relevant CSS rule, HTML element ID, Javascript class, or whatever is needed. The "core" namespace would probably have some special rules, allowing other namespaces to call on it, sort of a meta-API (again not so relevant to the example, but realistic).

That's the gist of it at least, but it doesn't necessarily involve anything I just mentioned. For some teams that could just be an email reminder of "FTP your changes here, but jerk you best not overwrite my stuff," and for others it's a 3-ring binder of rules implemented with a rigid assembly line, wired to any number of bug trackers and code review tools, of automata performing unit tests and processing makefiles and checking permissions and so on and so forth. I'd guess Facebook leans more to the latter.

Long story short: information organization and a build process to maintain it.

So yes, everyone can (and should) be aware of what others are naming their div tags & JS functions and everything else important, thanks to this ominous MCP-looking entity maintaining the rules and handing out the names. With the right process and tools, you'll never not know.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜