This semester, the school opened the open source course. In order to broaden my knowledge and technology stack, I chose Dokit-Web of Didi to read and analyze the source code

I. Dokit Project Overview

Dokit is short for DoraemonKit, which means being able to provide A variety of tools to his owner like doraemon. Dokit is a functional platform that allows every App to quickly access development AIDS, test efficiency tools, visual AIDS that you may or may not have implemented, as well as the perfect Doraemon panel to access some of the non-common AIDS that you have implemented that are tightly coupled with the business. And with dokit platform, so that the function is extended, easy access, easy to expand. Dokit is a broad front-end application platform, including Android, ios, applets, Web, Flutter and other platforms. It can realize cross-platform communication, providing users with a convenient and efficient functional interface.

The main features of Dokit can be summarized as follows:

1, DoraemonKit can quickly make your business test code can be unified management here, unified closure;

2, DoraemonKit built-in many common tools, avoid repeated implementation, one access, you will have a powerful tool set;

3. With doKit platform, Mock interface, health check and file synchronization assistant make it easy for you to cooperate with others, greatly improving the efficiency of research and development.

Ii. Introduction to Web Module

Web module is an important part of the whole Dokit ecosystem. It mainly realizes some functional interfaces for HTML pages and can be connected with mobile terminals. The main programming languages are front-end HTML, CSS and Javascript (JS). The main application of JS is Vue3 framework, which can be responsible for the realization and rendering of various events, components, interactive data and communication jumps in web pages. HTML and CSS are mainly responsible for the layout and aesthetic design of web pages. At present, the Web side mainly covers logging, interface fetching, view element viewing, resource viewing, application storage, and interface mock. The basic and close functions of each part are shown in the following table:

Table 2-1 Overview of Web components

The module The log Interface to grab View attempted elements Resource view Application of storage Interface mock
Basis function – Supports all ‘console’ methods – supports filtering and clearing logs – supports simple ‘javascript’ commands – Supports fetching common interface types’ XHR ‘and’ fetch ‘- Displays request details – Displays response details – Display the entire page ‘Dom’ tree – support to expand, close, select (highlight elements) – support to view the content of a particular element – view the style of the element – view the box model of the element – Display ‘javascript’ resources – Display ‘CSS’ resources – Display ‘image’ and other media resources – Support view and modify ‘LocalStorage’ – support view and modify ‘SessionStorage’ – support view ‘Cookie’ – Support for non-invasive one-click Mock – support for automatic synchronization of real request data to the platform side and with fast creation
Advanced features – Enables you to view logs on multiple devices

Code reading tools

IDE: VS Code 1.54. VS Code is a cross-platform source editor for writing modern Web and cloud applications running on Mac OS X, Windows, and Linux. It runs on the desktop and is available for Windows, macOS, and Linux. It has built-in support for JavaScript, TypeScript, and node.js, and is rich in other languages (e.g. C++, C#, Java, Python, PHP, Go) and runtimes (e.g. NET and Unity) extended ecosystems. VS Code also integrates all the features expected of a modern editor, including syntax highlighting, customizable hotkey bindings, bracket matching, and snippet collection, as well as out-of-the-box support for Git. Operating system: Windows Reading method: Offline reading, using Git to clone the project to the local, and can follow up the update of the project at any time.

Iv. Web project parsing

4.1 Overall Structure

The main structure of the Web project is shown in Figure 4-1. The READme file is a brief description of the entire project. It mainly introduces each module and its functions, similar to the previous one. The package.json and lerna.json files mainly describe the versions of some dependent libraries; Node_modules is the underlying support library for the project. Packages are the main components of a project. Key functional modules are packaged in the Packages directory. Playground is equivalent to the main program or startup program; Script is a JS file that is used by the project runtime request server.

4.2 the main program

The main program is the index.html file, which is the main webpage to be opened. The main program is very simple and clear, partly explaining the encoding form and title and other main contents. The calling part only has the dokit.js file, that is, all the functions of each module are integrated in the dokit.js file.

Packages contains all the major components of a Web project, which are subdivided into three modules: Core, Utils, and Web. The core part mainly defines the container required by the web page, such as frame, canvas and other content, and realizes the communication between containers, as well as routing management. Utils encapsulates some utility classes, such as the distinction between operating systems, which are mainly low-level applications. The Web part is the application interface of the web page level, as well as the top-level application. For example, the logging function mentioned above comes from the Web encapsulation. Using such three-level modules, the container and application can be decoupled, so that application developers can concentrate on the design of the corresponding functions of the application, without too much docking between the application and the container. This article will focus on the application part of the analysis, because the rest of the project is also around the application function.

4.4 the Web module

The application interface is mainly realized in the Web module. The application function in the Web page in the Dokit framework can be decoupled from the container Settings, so the implementation of the application is the first concern. Currently, there are three simple functions: Hello World, application information display, and log synchronization. These three functions are independent of each other and are implemented separately and bound together in a unified container.

Hello World: This function is the simplest. You only need to display the corresponding information at a specific position on the page and set the corresponding style, such as font size, color, and alignment. In terms of language division, HTML language defines different div blocks in the web page. In this application, it is mainly the text that needs to be displayed. CSS code defines the rendering style of each block, which in this case is the completion length and text alignment position

Application information: To display application information, bind the corresponding information to a component. In this example, the Card component is in the common file. The Card component has only one Title property. Dokit-card defines some render features of card components that are obvious, and sets the background color to blue. The main function of the component is to display the Title string.

In contrast to Hello World, application presentation requires data, such as page data and the user’s current device data, which can be retrieved by calling methods in the global Window class or by retrieving the DOM element element in the window from the Document class. The backbone of an HTML document is a tag, and according to the Document Object Model (DOM), each HTML tag is an object. Nested tags are children of closed tags. The text inside the tag is also an object. All of these objects are accessible through JavaScript, and we can use them to modify the page.

Each node of a tree is an object. Tags are called element nodes (or just elements) and form a tree structure: < HTML > at the root node, and are its children. The text inside the element forms a text node, marked # text. A text node contains only one string. It has no children and is always the leaf of the tree. For example, the

tag contains the text “About elk”. Application information is mainly divided into “user information” and “device information”, which are respectively displayed in the Card component mentioned above. The specific data is presented in a table in HTML:

export default {
  components: {
    Card  //Card is a component of the current Vue application
  },
  data() {// AppInfo Data to obtain
    return {
      ua: window.navigator.userAgent,  // Browser and user data
      url: window.location.href,       // The browser url
      ratio: window.devicePixelRatio,  // Page scaling
      screen: window.screen,            // Screen size information
      viewport: {
        width: document.documentElement.clientWidth,    // The width of the screen used by the user
        height: document.documentElement.clientHeight   // Screen user range height}}}},Copy the code
<template>
  <div class="app-info-container">     <! -- Bind first level container style -->
    <div class="info-wrapper">         <! -- Bind secondary container style -->
      <Card title="Page Info">         <! The information to be displayed is bound to two Card containers, page information and device information.
        <table border="1">             <! -- Use table to show specific data -->
          <tr>
            <td>UA</td>                <! Table header: User info -->
            <td>{{ua}}</td>             <! Vue object ua -->
          </tr>
          <tr>
            <td>URL</td>                <! Table header: url address -->
            <td>{{url}}</td>            <! Vue data url binding -->
          </tr>
        </table>
      </Card>
    </div>
Copy the code

Console log: Displays the data generated by the console command console.log on the web page, and collapses or expands the corresponding labels and details. This section is a bit more complex than the previous two and requires the support of the two components Detail and Logitem. Const TYPE_CAN_FOLD = [‘Object’, ‘Array’]

There is only one unfold data in the Detail instance that controls whether or not the transformation is folded. The transformation is triggered when the component is clicked, that is, the component instance’s @click event binds a method unfoldDetail(),

  data () {
    return {
      unfold: false}},Copy the code
  methods: {
    unfoldDetail() {
      this.unfold = !this.unfold
    }
  }
Copy the code
 <div @click="unfoldDetail" v-html="displayDetailValue"></div>
Copy the code

Detail can display different details according to the data type of the log. The key of Detail is self-nesting, which can realize the nesting of iterable data. If the data in the log itself belongs to the non-iterable type, the data content, such as string and shaping data, can be displayed directly. If it is the iterable data, canfold data is used to judge, and the data is again encapsulated as a Detail component, which can display the details inside the iterated object in a tree structure.

export default {
  components: {
    Detail
  },
Copy the code
    <template v-if="canFold">
      <div v-show="unfold" v-for="(key, index) in detailValue" :key="index">
        <Detail :detailValue="key" :detailIndex="index"></Detail>
      </div>
    </template>
Copy the code

The Logitem corresponds to each console.log, with Detail as a child component, and can display log details. By default, the content of each metadata in the current log will be displayed in text form. If there is an iterable type, it will indicate the data type (Object /Array). Each metadata in each log will be encapsulated as detail. Since the subcomponent Detail is included, the task of displaying the details is implemented entirely from within the Detail.

export default {
  components: {
    Detail
  },
Copy the code
  methods: {
    toggleDetail () {
      this.showDetail = !this.showDetail
    }
  }
Copy the code
<div v-if="showDetail">
      <div class="list-item" v-if="typeof value === 'object'" v-for="(key, index) in value">
        <Detail :detailValue="key" :detailIndex="index"></Detail>
      </div>
    </div>
Copy the code

Console log function: Back to the specific log function, if Logitem is used as a sub-component, each log data needs to be encapsulated in a Logitem, and each log is stored in a Loglist data

  components: {
    LogItem
  },
  data() {
    return {
      logList: []}},Copy the code

Call the Created () method in the lifecycle, which means that content in console.log() in the console can be bound at any time after creation. To implement this, you need to bind the window.console method of the global window to get the data in the log and not update it to its own loglist property.

  created () {
    let self = this
    let originConsole = window.console;
    ['log'].forEach(type= > {
      let origin =  originConsole[type].bind(originConsole)
      originConsole[type] = function (. args) { self.logList.push(args) origin(... args) } }) }Copy the code

4.5 Application Encapsulation

The existing three applications are independent of each other, and after completing their separate functional design, they need to be wrapped as three independent components into an application container called ToolsContainer. During the package, use tabs data to store all component functions and prompt names, use V-for to traverse all application components, use

label to determine the activated application, and click the corresponding application to dynamically switch the activated application.

  components: {
    ToolConsole,
    ToolHelloWorld,
    ToolAppInfo
  },
  data() {
    return {
      tabs: [{
        component: 'console'.displayName: 'Console'}, {component: 'app-info'.displayName: 'AppInfo'}, {component: 'hello-world'.displayName: 'HelloWorld'}].currentTab: 'console'}},Copy the code

4.6 Web Module Design Summary

By the preceding analysis, you can see that the web application layer surface design has a strong hierarchy, where a layer of function only needs to encapsulate the next layer, without the need to involve more at the bottom of the module calling, this is very clear on the design logic level, makes realize decoupling between modules, so that we can better optimize the single module, avoid single point. Take the log function as an example. Each piece of data in a log, such as strings, integers, arrays, and objects, is encapsulated in the Detail component, while the entire log is encapsulated in the Logitem component. The overall log function can be invoked with the Logitem as the smallest unit without considering the Detail at the next level. Furthermore, the encapsulation of basic functions can combine individual function units (HelloWorld, application information, and log) without considering the components required within each function. This hierarchy can be simply shown in the following figure:

5. Experimental verification

Let’s run the project to get a more intuitive feel for the design of Web functionality

1. Clone the project from Github. According to the instructions in development. md, execute command lines NPM run bootstrap and NPM run Dev: Playground on the terminal to apply for network service and open the page. Port for http://localhost:3000/playground, the interface is simple, the bottom of the icon is the function of entrance

2. Click the icon to see the existing functions. It can be seen that the container framework of the whole page can be divided into title bar, basic function bar, platform function bar and version information bar, indicated by the red arrow, and these contents are defined under the Core folder. The container inside the function bar is the bar corresponding to each function, that is, the icon delimited in the blue box. The bar class also belongs to the container defined in the core module.

3. Click the ICONS in the “Basic Functions” bar respectively to see the corresponding application pages. The following figure shows the interfaces of Hello World, Application information and log functions respectively. The Hello World page is relatively simple with just the title text; In the application information section, the blue title box pointed by the red arrow is the Card container mentioned above, and the table pointed by the blue arrow is the table label inside the Card component

4. Logging needs with the console in the web console. The log to interact, thus we open a console input some data to see the effect by function, you can see the information in the console can reappear in the interface, below the picture on the right of the two rows of data for the logitem components mentioned above, click can trigger events, the details of the presentation, The Detail display function is the function of the Detail component, as indicated by the blue arrow.

5. As mentioned above, the Detail component can nest itself to achieve the detailed nesting of iterable data. When we enter such data in the console to see the effect, we can see that there are two logs in the interface, that is, two logItems corresponding to the Logitem component, and two elements in the Loglist array.

In the second log, a string “ABC”, an Array Array and an Object are entered. Each data becomes a Detail component. Click to trigger the corresponding event and view the detailed data information: The Array and the object themselves are iterable data, and the Detail is nested into a new Detail, while the third element in the Array is Array[3,4,5], which is again nested into a Detail component, so you can click on the component repeatedly to see the data content, resulting in the following result: As you can see, by nesting the Detail component, you can display the details of the iterated data in a tree structure.

Six, summarized

The Web project of Dokit is mainly composed of core, Utils and Web. The core part mainly realizes the definition of container and route management. Utils partially encapsulates some underlying application interfaces. The Web part defines the application function in the web page. The three parts are decoupled, so that the page function can be implemented without undue consideration of the container problem. We focus on the web application part, analyze the design framework of the existing three functions, among which the log part uses nested components to realize the expansion of the iterable data type. On the whole, the design of Web project has realized progressive layer upon layer and module separation, which makes the project have better extensibility, and also facilitate the location and improvement of bugs. This code design style is worth learning and reference.