The selected UI framework is harmful. Architectural Requirements - Profit



    We do not notice, but the services and products that we use are constantly becoming more complicated.

    • Enter the subway now - not just throw a piglet, but attach a Troika card recorded on the phone and taking into account the transplant.
    • Make a phone call and watch TV - it’s been a long time since you didn’t put two wires into the apartment and paid a fixed monthly fee, but triple play with a bunch of options and features.
    • View the son’s diary - they encroached on the holy! - Now you can 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 dozens of employees did before is now done by teams of thousands and tens of thousands of people (by the way, share in the comments how your IT departments grew).

    Such large teams are forced to take a more responsible approach to the selection of technologies, including UI frameworks. And here is the stuff for you: it does not matter which UI framework is selected. And it’s 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 - an increase in the speed, volume and convenience of information exchange - 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 various companies, countries and continents are working on one product.

    The joint development by a large distributed team brought the following features, which, in turn, were expressed in the development of relevant tools, frameworks and best practices:

    • Decoupling Strict separation of 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 combined 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 tasks, team expertise, preferences and “religion”.

    In many respects, therefore, we are now seeing active growth and the absence of an explicit and unconditional leader in UI frameworks: AngularJS, ReactJS, EmberJS, ExtJS, etc. At the same time, it is quite likely that you need to be prepared for the fact that tomorrow there will be a new front-end technology, which will be more effective and more actively supported / developed by the community. That is why I think it’s wrong to make long-term choices now and dwell on one front-end technology. Moreover, it is necessary to conduct development so that the front-end technology is relatively cheaply replaced, always keep this in mind when developing the architecture of a particular application. This is the number one task.

    In addition, with a further increase in the team, we will already have several front-end teams that are developing a single UI application. Each team independently develops its own part, but all these parts must be combined into one working application so that the UI of one team does not conflict with the UI of the other. This is task number two.

    To solve these problems, we, a front-end practitioner at Netcracker, develop architectural requirements that are mandatory for all products.

    A little theory of the modular approach


    The architectural requirements are based on an approach that involves 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, are made according to the principles of Nicholas Zakas: if you can write, just write a monolith, if you need integration with various blocks, 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 can generally not use the principles of Modular JavaScript and can be written in any language, at least in flash.
    • Application Controller - JS-object that implements the principles of Modular JavaScript, allowing modules to communicate and embed next to each other.
    • Module is a JS application in any language like JS.
    • Sandbox - an object through which Module can communicate with the outside world.
    • Service - utilitarian objects that have logic but no UI.
    • BroadcastService - a service that allows modules to communicate.
    • Plugin is a module built into 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:

    1. A module can only call its own methods or Sandbox methods.
    2. You cannot look at the DOM outside of your Sandbox.
    3. Do not touch non-native global variables.
    4. If the module needs anything, you need to ask Sandbox.
    5. Do not scatter toys (the module should not create global variables).
    6. 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 ).

    Based on these principles, we began to refine and develop them in our projects.

    Our specifics and architecture


    Clarifications and additional principles that are dictated by the specifics of our projects:

    1. The service does not have a UI;
    2. The service is usually singleton;
    3. Modules can communicate through a communication service (this can be an EventBus or publish / subscriber);
    4. There is only one communication service common to all modules;
    5. Since we are dealing with JS, we need a static code analyzer (for example, ESLint ), which will prohibit changes to the code in case of violation of the principles;
    6. The implementation of Modular JavaScript should be JS Agnostic, that is, the module can be written in any language like JS;
    7. Support for the module in the module is needed, because 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);
    8. Due to the fact that the module cannot go beyond the scope of its element, DialogManagerService is required, which controls the body to display a dialog box; the module that wants to show the dialog box uses the dialog module and passes it to the service;
    9. Since there can be many modules in a project, compiling all into one package or pre-linking can lead to performance problems, therefore, modules should be able to load asynchronously on demand and, of course, only be started after all other modules and services are loaded, from which they depend; it follows that we will need to resolve conflicts between dependent modules.

    And this is how the architecture turns out.



    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 the plugin that allows you to communicate with the server for the "lazy" loading of modules.

    Services can communicate with Application Controller. The most important is the service for exchanging messages between modules. Services can also use plugins. Services do not have a UI, as they provide JS functions.

    When a module starts, Sandbox is created by its name, which restricts the module. The main API - makes it possible to get a service and a DOM element into which the module needs to be integrated. If you need to run two modules with the same name, then Application Controller will create two instances of the modules whose internal id will be different.

    Conclusion


    Joint development by a large distributed team brought decoupling and microservices, which freed up the hands of front-end developers and allowed different teams to choose different front-end technologies. This could create chaos and turn into an endless debate.

    But we’re tricky) Modular development and architectural requirements make it possible 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 in full, write in the comments - let's share our experience. We, in turn, are ready to give more technical details if the community has interest.

    Also popular now: