
We do not notice, but the services and products we use are constantly becoming more complex.
- Sign in to the subway now - not just throw a penny, but attach a Troika card, recorded on the phone and taking into account the transfer.
- To make a phone call and watch TV — it’s been a long time since you’ve spent two wires in an apartment and paid a fixed monthly fee, but triple play with a bunch of options and features.
- See the diary of his son - on the holy encroached on the same! - now it is possible from the tablet, at the same time responding to the comment of the class teacher about his unsatisfactory behavior.
Well, I'm already silent about all sorts of Tinkoff, Apple Pay, Google Now, smart homes and much more.
')
As a result, IT departments are growing in any company. What several dozens of employees did before, now teams of thousands and tens of thousands of people are doing (by the way, share in the comments how your IT departments have grown).
Such large teams are forced to take a more responsible approach to the choice of technologies, including UI frameworks. And here's a throw in: it doesn't matter which UI framework is selected. And even harmful to limit yourself to the choice of one framework. But it is absolutely not harmful and it is even necessary to follow the rules for using these frameworks.
Technological development - increasing the speed, volume and ease of information exchange - has allowed large IT teams not to gather in one building, but to work as a distributed team. And now we have huge open-source projects, where many teams from different companies, countries and continents are working on one product.
The joint development of a large distributed team brought the following features, which, in turn, resulted in the development of appropriate tools, frameworks and best practices:
- Decapling Strict separation on the back-end and front-end. REST service for each individual UI.
- Microservices. Each team independently develops its own part, but all these parts must be put into one working application.
These features actually untied the hands of front-end developers and allowed different teams to choose front-end technologies depending on business objectives, team expertise, preferences and "religion".
That's why we are now witnessing active growth and the absence of an obvious and unconditional leader in UI frameworks: AngularJS, ReactJS, EmberJS, ExtJS, etc. At the same time, it’s quite possible that we should be prepared for the fact that tomorrow there will be a new front-end technology, which will be more effective and will be more actively supported / developed by the community. That is why I consider it wrong now to make a long-term choice and dwell on one front-end technology. Moreover, it is necessary to develop in such a way that the front-end technology is relatively cheap to replace, always keep this in mind when developing the architecture of a specific application. This is task number one.
In addition, with a further increase in the team, we will already have several front-end teams that are developing one UI application. Each team independently develops its own part, but all these parts must fit into one running application so that the UI of one team does not conflict with the UI of another. This is task number two.
To solve these problems, we, the front-end practice at Netcracker, develop architectural requirements that are mandatory for all products.
A bit of modular theory
The architectural requirements are based on an approach that implies independent JS blocks and their integration into each other. This approach has several names: Scalable JS Apps, Modular JavaScript, JS Portals. Such frameworks are relatively young and, one might say, made according to the principles of Nicholas Zakas: if you can write, just write a monolith, if integration with different blocks is needed, then you will have to use a modular approach.
Terminology
- Application (final application) - a set of html / js / css that is displayed to the user. The final application may not generally use the principles of Modular JavaScript and be written in any language, even on flash.
- Application Controller - JS-object that implements the principles of Modular JavaScript, which allows modules to communicate and integrate side by side and with each other.
- Module - JS application in any language like JS.
- Sandbox is an object through which the Module can communicate with the outside world.
- Service - utilitarian objects that have logic, but do not have a UI.
- BroadcastService is a service that allows modules to communicate.
- Plugin is a module embedded in the Application Controller. Application Controller can use it to get new functionality.

Modular javascript. Principles
The principles are based on the fact that we consider each module as a child. Therefore, the following rules apply to them:
- A module can only call its own methods or Sandbox methods.
- You can't look at the DOM outside your Sandbox.
- You can’t touch non-native global variables.
- If the module needs anything, you need to ask the Sandbox.
- Do not scatter toys (the module should not create global variables).
- Do not talk to strangers (the module should not directly call another module).
The original can be read
here .
These principles are implemented by Nicholas Zakas in a number of projects, for example here:
http://t3js.org . However, there are alternative implementations:
http://openf2.org/ (although the principles are the same there, they are described in the
video ).
Taking these principles as a basis, we began to refine and develop them in our projects.
Our specifics and architecture
Refinements and additional principles that are dictated by the specifics of our projects:
- The service does not have a UI;
- Service usually singleton;
- Modules can communicate via the chat service (this can be an EventBus or publish / subscriber);
- There is only one communication service common to all modules;
- Since we are dealing with JS, we need a static code analyzer (for example, ESLint ), which will prohibit making changes to the code in case of violation of the principles;
- The implementation of Modular JavaScript must be JS Agnostic, that is, the module can be written in any language similar to JS;
- Module support is needed in the module, as you often want to reuse the code (for example, the table module can be drawn inside the dashboard module, which, in turn, is drawn on the tab navigation module - like a panel with tabs for switching);
- Due to the fact that the module cannot go beyond its element, DialogManagerService, which manages the body, is required to display the dialog box; the module that wants to show the dialog box, uses the dialog module and sends it to the service;
- Since there can be a lot of modules in a project, compiling all in one package or pre-linking can lead to performance problems, so modules should be able to load asynchronously on demand and, of course, run only after all other modules and services are loaded. which they depend on; it follows that we will need to resolve conflicts between dependent modules.
And what is the architecture?

The T3-NC-powered unit is an Application Controller. The Application Controller has a set of basic plugins (triangles) that complement its functionality. Plugins do not have access to the Application Controller. The most important is a plugin that allows you to communicate with the server for “lazy” loading of modules.
Services can communicate with the Application Controller. The most important is the service for messaging between modules. Also services can use plugins. Services do not have a UI, as they provide JS functions.
When the module starts, the Sandbox is created by its name, which limits the module. The main API allows you to get the service and the DOM element in which the module needs to be integrated. If you need to run two modules with the same name, then the Application Controller will create two module instances whose internal id will be different.
Conclusion
The joint development of a large distributed team brought decoupling and microservices, which untied the hands of front-end developers and allowed different teams to choose different front-end technologies. This could create chaos and become an endless argument.
But we are clever. Modular development and architectural requirements allow us to assemble parts developed by various front-end teams into one UI application and guarantee a relatively cheap replacement of the front-end framework.
If you are interested in a modular approach or are already using it with might and main, write in the comments - let's share the experience. We, in turn, are ready to give more technical details if the community has an interest.