I see a lot of problems with front-end development, especially the following three points.

  • The UI is getting old, so development has to keep up
  • Logic challenges, development also has to change the code, a lot of back-end processing logic in it
  • Composite interface, this is the historical reason, mainly with the backend caused by coordination. In fact, there is no Node BFF layer, it is done by components, which can be very problematic.

Recently, our open source project iMove gained 280+ star in one day and ranked no.1 on the Github Trend list. This is a good achievement, which shows that this project is positioned accurately and has really solved the problem of developers.

Today, through this article and we introduce the iMove open source project, the content includes the iMove function and implementation principle, the original online code running ability, and how to automatically resolve the node’s NPM package dependence, or there are many bright spots and innovation.

1. IMove is introduced

In short, our ideal front end can do the following four things.

  • Logical assemblability: This is the reuse of interfaces and UIs at a minimum of granularity.
  • Process visualization: These smallest reusable units can be orchestrated by processes to simplify operations.
  • Convergence of operation configuration: this is caused by high operation cost caused by multiple systems. It is best to put them together.
  • Gameplay capability precipitation: To precipitate the product gameplay into reusable capabilities.

For developers, iMove is the ideal tool to accomplish these goals. Move the mouse, write a node function, code export, into the specific project can be directly used, is not very convenient?

So, what is iMove?

  1. It’s a tool. It’s non-invasive.
  2. Double-click to write a function, and the choreographed process can export executable code for easy integration in a specific project.
  3. Test convenient, right click directly execute, there is innovation here.
  4. Let development be as functional as operational configuration, reuse and reuseLowcode.

1.1 for example 🌰

Let’s take a look at some examples

Suppose one day you receive a request for a detail page purchase button:

  • Get product information from the details page
  • The product information includes the following
    • Whether the current user has received a coupon
    • Commodity coupons need to pay attention to the store or join the membership
  • Depending on the product information returned, the buy button takes the following forms
    • If you have received the coupon, the button displays “Received coupon + Buy”.
    • If you don’t get a coupon
      • If the coupon needs to be paid attention to the store, the button will display “Pay attention to the store to get the coupon + buy”.
      • If you need to join the member to get the coupon, the button will display “Join the member to get the coupon + buy”.
    • In case of exception, display bottom pocket style
  • Note: If the user is not logged in, invoke the login page

We can convert this complex business logic into the following schematic pseudocode:

// Check login
const checkLogin = () = > {
  return requestData('/is/login').then((res) = > {
    const {isLogin} = res || {};
    return isLogin;
  }).catch(err= > {
    return false;
  });
};

// Get details page data
const fetchDetailData = () = > {
  return requestData('/get/detail/data').then((res) = > {
    const {
      hasApplied,
      needFollowShop,
      needAddVip,
    } = res;
    if(hasApplied) {
      setStatus('hasApplied');
    } else {
      if(needFollowShop) {
        setStatus('needFollowShop');
      } else if(needAddVip) {
        setStatus('needAddVip');
      } else {
        setStatus('exception');
      }
    }
  }).catch(err= > {
    setStatus('exception');
  });
};

checkLogin().then(isLogin= > {
  if(isLogin) {
    return fetchDetailData();
  } else{ goLogin(); }});Copy the code

As the above example shows, although the complexity of the business is not very high, the cost of communication and understanding behind it is not low. Presumably, the actual scenarios that you encounter in your own business are much more complicated and difficult than this. However, the complexity of the business logic determines the complexity of the code, and the more complex the code is, the more difficult it is to maintain. If one day you take on someone else’s project with complicated logic, the maintenance cost will be very high. However, this is one of the problems that iMove addresses, so let’s take a look at how to develop using iMove for the same business requirements described above.

As shown above, the originally obscure code logic is expressed in the form of flow chart through iMove, and now the business logic of the product is clear at a glance. In addition, every node in iMove supports writing code, and the direction of flow chart determines the execution order of nodes in the diagram. It can be said that “process visualization is a natural code annotation”.

Therefore, in terms of “legibility” and “maintainability” : iMove process visualization form > PRD text description form of product manager > program code form

1.2 Application Scenarios

The React component typically initiates a request in ComponentDidMount and performs rendering or other business logic based on the successful data of the request, which is a completely UI-free Ajax request processing. In addition to the component declaration cycle, there are only various interaction events, which are usually a mixture of UI and Ajax scenarios.

  1. Front-end processes, such as click events, component lifecycle callbacks, and so on.
  2. Back-end processes, such asNode.jsServerlessField.
  3. Front end plus back end, like front click events,AjaxRequests and the back endAPI.

1.3 advantage

The above mentioned content is only the tip of the iceberg of iMove, let’s take a look at the advantages of iMove:

1) Logic reusable

Faced with the daily business requirements of frequent iterations, we are bound to encounter many similar, repetitive development efforts. In code it can be a generic utils tool method or a generic business logic code (such as sharing), but at heart it is a code snippet. To improve code reuse, we tend to encapsulate it into generic classes or functions and then copy and paste it from project to project (if we do a better job, we can encapsulate it into an NPM package, but the process of changing the distribution is a bit more tedious).

In iMove, each reusable snippet can be encapsulated as a node in a flowchart. When you want to reuse logic in different projects, you can directly introduce the corresponding node/sub-process, and each node also supports parameter configuration, which further improves the reuse of nodes, and the use experience can be said to be very simple.

If iMove has precipitated a certain amount of business nodes in a business scenario, can the logical part be directly assembled by reusing existing nodes when similar business requirements are met next time? This can greatly improve the efficiency of research and development, shorten the project research and development cycle.

2) Function oriented

In terms of node design, iMove is relatively restrained. Each node is essentially exporting a function, so there is almost no cost to get started in the coding experience, as long as you have basic JavaScript. You can import other NPM packages as usual without worrying about global variable naming contamination between nodes, just like a normal JS file.

3) Process visualization

We refer to this development approach to process visualization as “logical choreography,” and the benefits of it (more intuitive and easier to understand logic) have already been described and will not be repeated here.

4) Logic /UI decoupling

We often see it in our daily business development: UI styles change frequently, business logic is stable, and there are even ABTest requirements to see the effect of the revision.

However, many developers do not envisage this step at the beginning of component development, so a business component often couples “business logic” with “UI style “. However, when it comes to revision, it is not easy to extract and reuse business logic, and maintenance costs increase greatly.

However, as you develop with iMove, the component code automatically breaks down into “business logic” + “UI style “. In addition, different versions of the UI can be maintained multiple sets, but the business logic part of iMove to maintain only one set. This approach not only maximizes the reuse of business logic code, but also improves project maintainability.

5) Simpler code testing

In order to improve the use experience of iMove, we implemented the function of “online running node code on the browser side”. This means that when a node’s functions are complete, you can always mock out various inputs on the browser side to see if the node behaves as you expect.

In other words, you can test the functions of a node without introducing a testing framework, out of context, which greatly reduces the cost and barrier of code testing. At the same time, you can easily save each test input/output as a test case, and gradually form a complete test case, which not only ensures the quality of the node code, but also can be more secure in other projects.

6) No language/scene restrictions

Although iMove itself is a JavaScript tool library, iMove has no restrictions on the language and scenarios used in our design. That is, you can use iMove not only to orchestrate JS code in your front-end projects, but also Java code in your back-end projects, and even other languages in other scenarios. All of this, in the end, depends on what language iMove compiles the flowchart into.

2. IMove principle

After having a certain understanding of the project background of iMove, this article will take you to uncover the technical principle behind it

2.1 How to build a drawable flowchart application?

Apart from the iMove partial development of the function not to say, we can put it as a flow chart drawing tool to use (after painting can also export pictures to save to the local ~). So how does iMove draw a flowchart? We must be curious about this, here we must give ants team do X6 engine a thumbs up 👍, really good ~

X6 itself doesn’t come bundled with React or Vue, so you can use it with X6 in any framework. In addition, it provides a series of out-of-the-box interaction components and easy-to-use node customization capabilities that can be quickly implemented with a few simple API calls.

Node configuration

A follow-up article will show how iMove can quickly build a drawable flowchart application using X6.

The core of iMove is based on X6 protocol.

  • Nodes: useX6Visual interface for easy reuse and orchestration.
  • With pointing edge: that is, process visualization, simple and intuitive, the edge can also take parameters.
  • There arefunctionschema2formSupport for function definitions, which are developer oriented. supportform, so that each function can be configured into the parameter, this part is based on ali open sourceform-renderThe implementation.

The whole project is not difficult. Based on the further integration of X6 and form-Render, the writing method will be standardized and the arrangement tool will be used. Such restrained design makes iMove have the characteristics of small and beautiful, which is convenient for development and use.

2.2 How to compile a flowchart into runnable code?

What makes iMove more attractive than charting a flowchart is that it can compile the flowchart into actually runnable code in a business project.

2.2.1 Online Compilation vs. Local Compilation

First of all, iMove supports both browser-side online compilation and ZIP package download, and local command line watch real-time compilation.

1) Online compilation

To reduce the cost of getting started with iMove, we’ve added the ability to compile code online in the browser, so developers can download compiled code without installing tools.

How do you do that? After investigating, we found that JsZip is a JavaScript library that can read/write/modify ZIP files all in one, and also supports browser-side running. Therefore, we can simply generate a JSON file from the directory of the code and throw it to JsZip for packaging, then use file-Saver to download it.

// key is the name of the file and value is the content of the file.
{
  "nodeFns": {
    "node1.js": "..."."node2.js": "..."."index.js": "..."
  },
  "context.js": "..."."dsl.json": "..."."index.js": "..."."logic.js": "..."
}
Copy the code

2) Local compilation

Online compilation is simple, but there is a problem in project development: every time you modify the code, you need to re-download the ZIP package and decompress it to the specified directory, especially during debugging, it is very inconvenient to modify the code frequently. In order to solve this problem, iMove provides a local compilation method to compile codes into business projects in real time by saving the flow chart of Watch.

How do you do that? The key of the above problem is: how to listen to the flow chart save operation on the browser side locally. But on the flip side, why not send a message locally when the flowchart is saved? This way, we can either use a library such as socket. IO to set up websocket communication between the browser and the local, or use a library such as KOA/Express to start an HTTP server locally by triggering compilation when we receive a flowchart save signal.

2.2.2 Basic principle of iMove code operation

Having solved the problem of how iMove compiles code, let’s take a look at how iMove compiles code.

To run code, iMove needs to solve two core problems:

  1. How to execute the nodes in the order of the flowchart
  2. How to process the data stream (e.g., the return value of the previous node is the input of the next node)

RxJS seems like a good choice, and functional responsive programming seems like a natural solution to this problem. However, considering that the cost of getting started would undoubtedly be a huge mental burden on iMove users, we didn’t adopt this solution.

1) For the first sequential execution problem, iMove adopts a low-cost way to solve it:

  • First of all,X6Supports flow chart exportjsonData, we can simplify it and save it as a copyDSLFile.
  • Secondly, according to thisDSLFile, from which we can extract the code part of each node into a separate file, and then form aNodal function set.
  • Finally, all you need to do is call the corresponding node functions in order of upstream and downstream relationship between nodes and edges.

2) For the second data flow problem, iMove designs four data read and write modes considering various scenarios of node data operation in practical applications:

  • Config: read-only. Nodes are configured and do not interfere with each other.
  • payload:ROM,logic.invokeWhen the logic is triggered, one can be passedpayloadValue that can be read by each node.
  • Pipe: read-only, the output of the previous node is the input of the next node.
  • context:Read-write, public data in a logical flow, if the ancestor node passes againsetContextSet the data so descendant nodes can pass across the nodesgetContextAccess the data

At this point, iMove solves the problem of flowchart code running. If you look at the compiled iMove code, you can see the following structure:

2.2.3 understand Flow

The basic concept of Flow is very simple. It is a directed acyclic graph (DAG) in which data flows between nodes.

  • Node Node
    • The node is the main unit of the stream, which is responsible for processing the data flowing into the node and outputting it to the subsequent nodes for further processing.
  • Port to Port
    • Each node has input and output ports. The input port is responsible for data flow into the node, and the output port is responsible for data flow out of the node. Each node may have one or more input and output ports.
  • Connect the Link
    • The output port of one node is connected to the input port of another node, and the data processed by the node flows into the following node through the connection.

The basic idea of Flow is to use a function to realize a node, and the input port is mapped to the input parameter of the function. The output port is mapped to the return value of the function.

A Node in the stream is set as an End Node. Through the connection relationship between nodes, all dependencies are searched through the connection from the End Node (tree search) to get a stack of nodes to run. For example, in the figure above, we can get a stack like node1, node2, node3. Performing the functions of each node in a sequential stack runs the entire stream. (Note that this is a simple version of Flow implementation, still a batch, not streaming)

It is necessary to assume that the function of each node is stateless, so that the input and output ports can be used to cache the calculated results. However, if the input value is a calculated value, the calculated value is directly returned without calculation.

Above is the Flow concept in flow-base Programing (FBP). This is actually the same concept as iMove. IMove based on X6, X6 to solve the DAG implementation and visualization problems, combined with node extension function writing, and then realize the developer’s logical orchestration tools. It’s as simple as that.

2.3 How Do I Run Node Codes online?

IMove has a cool function that you can run node function code online in the browser and see the results in real time. This WYSIWYG development experience is very user friendly, not only greatly reduces the cost of testing and debugging, but also can become a test case set to further guarantee the quality of nodes.

Write code in iMove, double-click the node.

Right-click the code to complete the test of a single node.

Open the running panel and fill in the corresponding parameters to execute the specific code.

Running the iMove node code online needs to solve the following problems:

  • How does the browser run the node directlyimport/exportesmStandard code
  • A nodeimportCome innpmThe bag could still becjsSpecification, how should the browser work
  • How do you run code when multiple nodes are selected

The principle behind the implementation of iMove is mainly based on HTTP-import, and we will write a special article to introduce its implementation principle, please look forward to ~

2.4 How can I automatically resolve NODE NPM package dependencies?

Because each iMove node supports the import of other NPM packages, each node has NPM dependencies. However, this would have been a very bad experience for developers to fill in manually, so we made automatic parsing.

The principle is actually relatively simple, understand the NPM view command. Take NPM view lodash.get for example. If you look at the command line output, you can see:

$NPM view lodash. Get [email protected] | MIT | deps: none | versions: 13 The lodash method `_.get` exported as a module. https://lodash.com/ dist .tarball: https://r.cnpmjs.org/lodash.get/download/lodash.get-4.4.2.tgz shasum: 2d177f652fa31e939b4438d5341499dfa3825e99 maintainers: - phated <[email protected]> dist-tags: latest: 4.4.2 Published over a year ago by Jdalton <[email protected]>Copy the code

As mentioned above, this command successfully gets the latest version of the package lodash.get. Of course, the NPM view command is not suitable for execution on the browser side, but it is essentially a web request. Get –verbose NPM view lodash.get –verbose NPM view lodash.get –verbose: r.cnpmjs.org/lodash.get

The next step is simply to match the dependencies in the node code with the re according to the import syntax rules, and then call the above API to automatically resolve the package dependencies of the node.

3. Summary

There’s a design-to-code tool like ImgCook on the UI side, and that’s enough to handle change. But in logic, there are very few developers who can really solve problems, and iMove is an exploration in this direction. I believe that through the above explanation, we can feel its charm.

The slogan of iMove is Move your mouse, generate code from flow chart. That is, you can write node functions by moving the mouse, export the code, and use it directly in specific projects. Developed as an operational configuration, this is no longer a wish, but a reality. If you are interested in iMove, you can also participate in open source projects.