"Forwarding" builds a highly scalable web-interactive system (bottom)

Source: Internet
Author: User

Translated from: http://kb.cnblogs.com/page/504518/

This article is the third of a series of articles on building a highly scalable web interactive system, taking the Nej framework of NetEase as an example to analyze and introduce the scalability of the module.

  Example analysis

The NEJ framework is implemented according to the description of the first two articles, and the following is a concrete example of how to use the module scheduling system in Nej to split a complex system, develop test modules, integrate systems, and so on.

  System decomposition

  Draw a hierarchy diagram

When we get a complex system, we can draw a hierarchical diagram of the modules that make up the system according to the interactive draft, and determine the modules that the system can access externally.

  Abstract dependency Tree

From the module's hierarchical diagram, we can easily abstract the dependency tree of the module:

We then format the abstract dependency tree according to the Umi rule. The main operations for formatting include:

    • Add a root node called "/" (can also change "m" Node to "/")
    • Each node adds "/" to the child nodes as the default node

The dependency tree for this output has the following characteristics:

    • Any node (outside the root node) to the root node path node name is combined with "/" to be the Umi value of the node, such as the Umi value of the list node is/m/blog/list
    • The modules on any node depend on the existence of modules on his ancestor nodes (registered modules), such as the blog node and the list node are registered with the module, then the module display on the list node must be a prerequisite for the display of the module on the blog node.

  Identify the external module registration node

Five externally accessible modules: Log, tag, basic information, personal experience, permission settings, find the right node in the dependency tree (leaf node, hierarchical tree in the dependency tree corresponding node or "/" node) to register externally accessible modules:

  Determining the Layout Module registration node

The nodes that are registered from the accessible module go to the root node, where the nodes that meet the two-module intersection are registered nodes of the layout module, and the modules related to the system need to be registered to the root node, so that any module can be used to ensure that the components are already loaded.

  Mapping module functions

Principle: The common parent node of the node implements the public function of the module registered on the node.

For example: blog node and setting node of the common parent node is m node, then we can switch the blog module and setting module to identify the same function as the M module implementation of the function, the same with other modules.

  Decomposition of complex modules

Further decomposition of the complex modules, generally need to decompose the modules include:

    • A common module, such as a log list, can be rendered on the Log Management page or displayed in a projectile layer.
    • There is no logical connection between the module, such as the log module in the log list and the right side of the label to view the list of labels there is no inevitable connection between the removal or addition of any one module will not affect the business logic of another module

At this point we can get two system decomposition of the dependency tree-External module dependency tree:

and the Private Module dependency tree:

  Drawing Module Function Specification table

In this example, all the decomposed modules are decomposed in order to illustrate the decomposition process. The actual project to see the specific situation, such as the/?/tab/module of the M-module here can be directly implemented in the/M module, without the need to create a new/?/tab/module to achieve this function.

The canonical table example looks like this:

  Building a Directory

  Project directory

The project directory is built as shown in:

Description of each directory

Webroot                    Project Front-end development related Directory   |                  -res static resource file directory, can be configured to use the static resources in this directory with version information   |-src                  front-end source directory, the directory will not be deployed to the line when the final release       |-HTML            | module      Catalog, the implementation of all modules of the system is in this directory            |-app.html    single page entry file

  Module Unit Catalog

According to the module encapsulation rule A module unit consists of the following parts:

    • Module testing: module-implemented functions can be tested independently via the module test page
    • Module structure: The structure of the module involved in the decomposition of a number of template collection
    • Module logic: module business logic implemented according to module specification, inheriting from module base class
    • Module Style: module-specific style, generally this part of the style can be directly implemented in the CSS directory

The structure example is as follows:

At this point we can get the directory structure of all the modules as follows:

  Module implementation

  Structure

Here we assume that the static page of the system has been done, the implementation of the module here is based on the original structure of the structure decomposition and the implementation of business logic, part of the structure of the module is mainly related to the static structure into several nej template. Attention:

    • An external resource in the template, such as a Css,js file address, is relative to the module's HTML file path if you are using a relative path
    • The external resources in the template collection must be identified with the @template tag, which is described in detail in the following package release chapters

Nej Template Description

Example of modular structure

<meta charset= "Utf-8"/><textarea name= "txt" id= "m-ifrm-module" >  <div class= "N-login" >    <div class= "Iner j-flag" >      <span class= "cls J-flag" >x</span>      <span class= "min j-flag" >-</span>    </div>    <div class= "cnt j-cnt" ></div>  </div></textarea ><!--@TEMPLATE--><textarea name= "JS" data-src= "./index.css" ></textarea><textarea name= "JS "Data-src="./index.js "></textarea><!--/@TEMPLATE

  Logic

Depending on the Util/dispatcher/module module, we extend the module base class of a project from the _$ $ModuleAbstract, completing the abstraction of the module-specific properties and behaviors in the project.

/* *------------------------------------------* Project module base class implementation file * @version  1.0 * @author   genify ([email protected]) *------------------------------------------*/nej.define ([    ' Base/klass ',    ' util/dispatcher/module '), function (_k,_t,_p) {    //variable declaration    var _pro;    /**     * Project Module base class object     * @class   {_$ $Module}     * @extends {_$ $ModuleAbstract}     * @param   {Object}  Optional configuration parameters, the list of processed parameters is as follows     *    /_p._$ $Module = _k._$klass ();    _pro = _p._$ $Module. _$extend (_t._$ $ModuleAbstract);    /** *     Operation     * @param  {Object}     * @return {Void}     *    /_pro.__dosomething = function (_args) {        //TODO    };    TODO    return _p;});

Depending on the state of the module, we need to implement the following interfaces when implementing a module:

Interfaces for each phase:

    • Build-__dobuild: Build the module structure, the nodes that the cache module needs to use, and initialize the configuration parameters of the combined control
    • Display-__onshow: Place the module in the specified container, assign the combined control, add related events, and execute __onrefresh's business logic
    • Refresh-__onrefresh: Get the data and show it according to the parameter information entered by the outside world (mainly doing data processing)
    • Hide-__onhide: Modules are put into memory to reclaim the combined controls and added events that are assigned in the __onshow, recycling the views generated in the __onrefresh (where possible to ensure that after the completion of the execution, the recovery to the post-__dobuild state)

Concrete Module Implementation Examples

/* *------------------------------------------* Project module implementation FILE * @version 1.0 * @author genify ([email protected]) *-- ----------------------------------------*/nej.define ([' Base/klass ', ' util/dispatcher/module ', '/path/to/project    /module.js '],function (_k,_e,_t,_p) {//variable declaration var _pro; /** * Project Module Object * @class {_$ $ModuleDemo} * @extends {_$ $Module} * @param {object} optional configuration parameter */_p._$$    Moduledemo = _k._$klass ();    _pro = _p._$ $ModuleDemo. _$extend (_t._$ $Module); /** * Building blocks, mainly dealing with the following business logic *-building the module structure *-Cache subsequent required nodes *-Initialize the configuration information of the component to be used * @return {Void} */_pro._        _dobuild = function () {this.__super ();    TODO};     /** * Display module, mainly dealing with the following business logic *-Add Event *-Assign Component *-Process input information * @param {Object} input parameter * @return {Void} */        _pro.__onshow = function (_options) {this.__super (_options);    TODO};    /** * Refresh the module, mainly dealing with the following business logic *-assigning components, assigning prior verification *-processing input information *-Sync Status *-load Data * @return {Void} */_pro.__onrefresh = function (_options) {this.__super (_options)        ;    TODO}; /** * Hidden modules, mainly dealing with the following business logic *-Recycling events *-Recycling components *-try to ensure the recovery to the state of the build * @return {Void} */_pro.__onhide = f        Unction () {this.__super ();    TODO};    Notify Dispatcher _e._$regist (' Umi_or_alias ', _p._$ $ModuleDemo); return _p;});

  News

Point-to-point messages

The module can send messages to the specified Umi module via the __dosendmessage interface, or it can receive messages from other modules by implementing the __onmessage interface.

Send Message

_pro.__dosomething = function () {    //TODO    this.__dosendmessage (        '/m/setting/account/', {            A: ' aaaaaa ') ,            B: ' bbbbbbbbb '        }    );

Receiving messages

_pro.__onmessage = function (_event) {    ///_event.from Message source    //_event.data message data, this could be {a: ' aaaaaa ', B: ' BBBBBBBBB '}    //TODO};

  Publish a subscription message

Publish a message

_pro.__dosomething = function () {    //TODO    this.__dopublishmessage (        ' OnOK ', {            A: ' aaaaaa ',            b : ' BBBBBBBB '        }    );

Subscribe to Messages

_pro.__dobuild = function () {    //TODO    this.__dosubscribemessage (        '/m/message/account/', ' OnOK ',        This.__onmessagereceive._$bind (this)    );};

  Self - rated

Create HTML pages and use templates to introduce module implementation files

<!--template box--><div id= "Template-box" style= "Display:none;" >  <textarea name= "html" data-src= ". /index.html "></textarea></div>

The module is placed in the container specified by the Document.mbody

Nej.define ([    ' Util/dispatcher/test '],function (_e) {    document.mbody = ' module-id-0 ';    Test module    _e._$testbytemplate (' Template-box ');});

  System integration

  Mapping dependency Trees

When the system is integrated, we only need to map the node that needs to register the module in the dependency tree with the module implementation file.

External module Integration

Private Module Integration

  Extracting System configuration Information

Rule Configuration Example

rules:{rewrite:{' 404 ': '/m/blog/list/', '/m/blog/list/': '/m/blog/', '/m/setting/account/': '/m/set ting/'}, title:{'/m/blog/tag/': ' Log tag ', '/m/blog/list/': ' Log list ', '/m/setting/permission/': ' Rights Management ', '/m/setting/account/': ' Basic information ', '/m/setting/account/edu/': ' Educational experience '}, alias:{' System-tab ': '/?/t        ab/', ' blog-tab ': '/?/blog/tab/', ' blog-list-box ': '/?/blog/box/', ' blog-list-tag ': '/?/blog/tag/',        ' Blog-list-class ': '/?/blog/class/', ' blog-list ': '/?/blog/list/', ' setting-tab ': '/?/setting/tab/', ' Setting-account-tab ': '/?/setting/account/tab/', ' layout-system ': '/M ', ' layout-blog ': '/m/blog ', ' Layo '         Ut-blog-list ': '/m/blog/list/', ' layout-setting ': '/m/setting ', ' layout-setting-account ': '/m/setting/account ', ' Blog-tag ': '/m/blog/tag/', ' setting-edu ': '/m/setting/account/edu/', ' setting-profile ': '/m/setting/ac count/', ' setting-permission ': '/m/setting/permission/'}} 

Module Configuration Example

modules:{'/?/tab/': ' module/tab/index.html ', '/?/blog/tab/': ' module/blog/tab/index.html ', '/?/blog/box/': ' module/ Blog/list.box/index.html ', '/?/blog/tag/': ' module/blog/list.tag/index.html ', '/?/blog/class/': ' module/blog/ List.class/index.html ', '/?/blog/list/': ' module/blog/list/index.html ', '/?/setting/tab/': ' module/setting/tab/ Index.html ', '/?/setting/account/tab/': ' module/setting/account.tab/index.html ', '/M ': {module: ' module/layout/ System/index.html ', composite:{tab: '/?/tab/'}, '/m/blog ': {module: ' Module/layout /blog/index.html ', composite:{tab: '/?/blog/tab/'}, '/m/blog/list/': {module: ' MoD            Ule/layout/blog.list/index.html ', composite:{box: '/?/blog/box/', tag: '/?/blog/tag/',     List: '/?/blog/list/', Clazz: '/?/blog/class/'}, '/m/blog/tag/': ' module/blog/tag/index.html ', '/m/setting ': {module: ' Module/layout/setting/index.html ', composite:{tab: '/?/setting/tab/'}}, '/m/setting/account ': {        Module: ' module/layout/setting.account/index.html ', composite:{tab: '/?/setting/account/tab/' }}, '/m/setting/account/': ' module/setting/profile/index.html ', '/m/setting/account/edu/': ' module/setting/edu/ Index.html ', '/m/setting/permission/': ' module/setting/permission/index.html '}

  Module combination

The module opens the container of the combined module through the __export property, and the parent in __export is the container node of the submodule, and the top-level module (such as "/M") can be overridden by __doparseparent to explicitly specify the container in which the application resides.

_pro.__dobuild = function () {    this.__body = _e._$html2node (        _e._$gettexttemplate (' module-id-l2 ')    );    0-box Select    //1-class list box    //2-tag list box    //3-sub module box    var _list = _e._$getbycl Assname (this.__body, ' J-flag ');    This.__export = {        box:_list[0],        clazz:_list[1],        tag:_list[2],        list:_list[3],        parent:_ LIST[3]    };

Configuring module combinations with Composite

'/m/blog/list/': {    module: ' module/layout/blog.list/index.html ',    composite:{        box: '/?/blog/box/',        tag: '/?/blog/tag/',        list: '/?/blog/list/',        clazz: '/?/blog/class/'    }

You can specify the processing state of the combined module when the module is combined:

    • OnShow-The combined module is configured here only when the module is displayed, and subsequent module refresh operations do not result in the refresh of the combined module, which is suitable for modules that will not change with the external input after display
    • Onrefresh-The modules configured here are combined when the module is displayed, followed by a refresh operation if the module is refresh, for modules that need to be synchronized with the external input for the combined module
    • Modules that do not specify OnShow or Onrefresh are equivalent to Onrefresh-configured modules
composite:{    onshow:{        //module OnShow when combined        //Combined modules are not refreshed during module Onrefresh    },    onrefresh{        // Module OnShow when the combination        //combination of modules when the module Onrefresh also refresh    }//The    combination module configured here is equivalent to the module configured in Onrefresh}

  Launch the App

Launch apps based on configuration

Nej.define ([    ' Util/dispatcher/dispatcher '],function (_e) {    _e._$startup ({        //rule configuration        rules:{            rewrite:{                //Rewrite rule configuration            },            title:{                //Header Configuration            },            alias:{                //alias configuration                // It is recommended that the module implement the registration in the file using the alias configured here            }        },        //module configuration        modules:{            //module Umi corresponding implementation file mapping table            //Simultaneous completion of module combination        }    });});

  Package release

Package release details Nej toolset related documents

  System changes

When the system requirements change and the module changes we just need to develop new modules or remove the module configuration

  New module

If you add a new module, just follow the logical implementation steps above to develop a module. If the new module functionality is already implemented in the system, you can simply modify the configuration. In the example above we need to add a copy of the tag module under Log Management to the blog settings, Access path is/m/setting/tag/

Modify Rule Configuration

rules:{    //...    alias:{        //...        ' Blog-tag ': ['/m/blog/tag/', '/m/setting/tag/'    }}

Modify the module configuration

modules:{    //...    ' /m/setting/tag/': ' module/blog/tag/index.html '}

If you want to add a label to the structure template of the/?/setting/tab module, you can

<textarea name= "txt" id= "module-id-8" >  <div class= "ma-t w-tab f-cb" >    <a class= "itm fl" href= "#/ setting/account/"data-id="/setting/account/"> Account management </a>    <a class=" itm fl "href=" #/setting/ permission/"data-id="/setting/permission/"> Permissions settings </a>    <a class=" itm fl "href=" #/setting/tag/" Data-id= "/setting/tag/" > Log labels </a>  </div></textarea>

  Deleting a module

Removing degraded modules from the system simply remove the module's corresponding Umi configuration from the module configuration without having to modify the specific business logic.

  Summarize

With the rapid development of web technology, the application of single-page system (SPA) has become more and more extensive, and as the complexity of such systems increases, the demand for the scalability of platforms and modules becomes more and more important. For these two aspects, the industry has given a lot of solutions, this article we mainly discuss the NetEase Nej framework in these aspects of the solution. NetEase in the single page system has also done a few years of practice and technology accumulation, such as in recent years, NetEase cloud Music PC version, easy letter Webim, NetEase mailbox assistant, such as the early years of NetEase album, NetEase mailbox, mobile NetEase Cloud album ipad, Lofter Android version and other products, Are the application of this kind of single-page system. The students who are interested in this field can make further exchanges in the course of practice.

"Forwarding" builds a highly scalable web-interactive system (bottom)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.