preface

NodeJS is playing an increasingly important role in the front-end space, not only allowing front-end workers to write backend code in javascript, but also making it easy to build responsive, scalable web applications. Node.js uses an event-driven, ** non-blocking I/O ** model to be lightweight and efficient, making it ideal for running data-intensive, real-time applications on distributed devices.

Therefore, as an excellent front-end engineer, it is necessary to understand and master Node.js. I’ll walk you through how to build an online automated packaging workflow from scratch, using the real-time online download code feature in the H5-Dooring project.

You will reap

  • The basic idea of designing an online workflow
  • Nodejs common API usage
  • How does Nodejs use parent-child processes
  • Use the exec implementation of child_process to parse and execute command line instructions
  • Socket. IO pushes messages in real time
  • Use jszip to compress files on the server and support front-end download of ZIP packages

The body of the

We’ve all used things likegulp.webpackThey can easily help us package and compile our code and write our engineering code in a relatively elegant way. But when we think about it, there’s a lot of stuff behind all these productsnodejsandbabelDo low-level support.We did nothing more than design an architectural pattern through Babel’s loader andnodejsThe ability of the service to place code by jS-ast-JS process (ignore CSS and plug-in processing here).

After that, let’s introduce how to design an online workflow.

1. Basic ideas for designing an online workflow

Online workflow is a general term, in fact any product line has its own unique workflow, but ultimately it is back to business. So the author introduces here speciallyH5-DooringReal-time download code for an online workflow. Let’s look at the following design process:Since NodeJS is single-threaded, we can use parent-child communication and asynchronous model to handle complex and time-consuming tasks without blocking the process. In order to inform the user of the completion status of tasks, we can use socket for two-way communication. In the current scenario, when the code is compiled and compressed, the browser is notified so that the browser can display the download status popup. There are three states:ongoing.Has been completed.failure. Corresponding to the interface as shown in the following figure:As for why there is no download failure status, don’t ask me, ask is not failed (finished, looking for abuse).

The above is h5-Dooring real-time compilation and download workflow design, as for more practical online needs, we can also refer to the above design to achieve, the next author to describe the implementation process.

2. nodejsHow to use parent-child processes

When we want to implement an automated workflow, one of the key issues to consider is when and how tasks are executed. Since the user needs to wait for the H5 page to be packaged, compiled and compressed before downloading the code, and this process takes a certain amount of time (8-30s), we can consider it a time-consuming task.

When we usenodejsAs a background server, due tonodejsItself is single-threaded, so when a user request comes innodejsWhen,nodejsHaving to wait for this “time consuming task” to complete before proceeding with other requests will result in other requests on the page waiting for this task to complete, so we have to consider multi-process processing for better user experience and smoother response. The good news is that NodeJS is designed to support child processes, so we can put time-consuming tasks into a child process and notify the main process when the child process is finished. The whole process is shown in the figure below:nodejsThere are three ways to create a child process, which I briefly describe hereforkThe way. The usage is as follows:

// child.js
function computedTotal(arr, cb) {
    // Time consuming computing task
}

// Communicate with the main process
// Listen for the main process signal
process.on('message'.(msg) = > {
  computedTotal(bigDataArr, (flag) = > {
    // Send a completion signal to the main processprocess.send(flag); })});// main.js
const { fork } = require('child_process');

app.use(async (ctx, next) => {
  if(ctx.url === '/fetch') {
    const data = ctx.request.body;
    // Tell the child process to start executing the task and pass in data
    const res = await createPromisefork('./child.js', data)
  }
  
  // Create an asynchronous thread
  function createPromisefork(childUrl, data) {
    // Load the child process
    const res = fork(childUrl)
    // Notify the child process to start work
    data && res.send(data)
    return new Promise(reslove= > {
        res.on('message'.f= > {
            reslove(f)
        })
    })  
  }
  
  await next()
})
Copy the code

In the workflow packaged on the H5-Dooring line, we use the exec method of child_process to parse and execute command line instructions. More applications for parent-child processes can be explored on your own.

Use 3.child_processtheexecImplement parsing and executing command line instructions

In the Dooring workflow described above, we learned that in order to implement real-time packaging, we needed an H5 Template project that would act as a packaging master that, when the user clicked to download, would pass the PAGE’s JSON Schema data to the Node server. Then the Node server cleans the JSON schema and generates a template-. json file and moves it to the H5 Template master. At this time, the master obtains the data source, packages and compiles it, and finally generates an executable file.

The above process is very critical, here the author draw a general flow chart:In order to achieve the above process, we need two key steps:

  1. The user-configured data is processed and a JSON file is generated, and then moved to the H5 Template master
  2. The package compilation script is automatically executed in the master

The first link is very good to implement, we only need to use nodeJS FS module to generate files to the specified directory, here the author focuses on the implementation of the second link.

After we generate the JSON data into the H5 Template, we can package the data. However, this process needs to be handled automatically. We cannot manually execute NPM start or YARN start as we did before. We needed the program to automatically execute this command line command for us. I was looking at the NodeJS API and suddenly found that child_process’s exec method, which can be used to parse the command, was just what we needed, so we started implementing it. The code is as follows:

import { exec } from 'child_process'
const outWorkDir = resolve(__dirname, '.. /h5_landing')
const fid = uuid(8.16)
const cmdStr = `cd ${outWorkDir} && yarn build ${fid}`

/ /... Exec related code
const filePath = resolve(__dirname, '.. /h5_landing/src/assets/config.json')
const res = WF(filePath, data)

exec(cmdStr, function(err,stdout,stderr){
  if(err) {
    // Error handling
  } else {
    // Processing succeeded}})Copy the code

The above code is easy to understand. We just define the packaged instruction string (in almost the same way as the command line operation) and pass the first argument to exec, who parses the string and executes the corresponding command line command. After the execution is complete, we can determine the result of the execution based on the parameter values in the callback function (second parameter). The whole process is asynchronous, so we don’t have to worry about blocking. In order to get real-time feedback on progress, we can use the socket to push progress information to the browser.

4. socket.ioRealize real-time message push

There are also some details that can be optimized in the exec implementation of parsing and executing command line instructions described above, such as feedback on the process of code execution, and feedback on the state of execution. Since we are using asynchronous programming, requests are not kept waiting. Without any optimization, it is impossible for the user to know when the code has been packaged and compiled, or if it has failed to compile, so several common scenarios are used:

  • The client requests long polling
  • Postmessage Message push
  • Websocket two-way communication

Obviously using WebSocket for two-way communication would be more appropriate for this project. Here we directly use socket. IO, which is popular in the community. Because there are many introductions on the official website, I will not explain it here. Let’s look directly at the code used in the business:

/ / the node
exec(cmdStr, function(err,stdout,stderr){
  if(err) {
    console.log('api error:'+stderr);
    io.emit('htmlFail', { result: 'error'.message: stderr })
  } else {
    io.emit('htmlSuccess', { result: dest, message: stderr })
  }
})

// The browser side
const socket = io(serverUrl);
/ /... Omit other business code
useEffect(() = > {
  socket.on('connect'.function(){
    console.log('connect')}); socket.on('htmlFail'.function(data){
    // ...
  });
  socket.on('disconnect'.function(e){
    console.log('disconnect', e)
  });
}, [])
Copy the code

This enables the server task flow to be fed back to the browser in real time.

5. UsejszipImplement the server compression file and support front-end downloadzippackage

The implementation of front-end download function is actually very simple, because the user-configured H5 project contains a variety of resources, such as CSS, JS, HTML, image, so in order to improve the download performance and convenience, we need to package the whole website and generate a ZIP file for users to download. The principle is to use jszip to compress the directory, and then return the compressed path to the front end, the front end using a label for download. As for how to achieve directory traversal compression and traversal read directory, here I do not say, interested can refer to the author of other NodeJS articles.

6. Summary

The above tutorial has been integrated into H5-Dooring, and some of the more complex interactive features are also possible with proper design, which you can explore on your own.

Github: H5 Online editor H5-Dooring

The last

If you want to learn more H5 games, Webpack, node, gulp, CSS3, javascript, nodeJS, Canvas data visualization and other front-end knowledge and practical, welcome to “Interesting Talk front-end” to learn and discuss together, and explore the boundary of the front-end.

More recommended

  • Introduction to online IDE development: Implement an online code editor from scratch
  • React+Koa based h5 page visualization editor -Dooring
  • In-depth analysis of Github star number 15.1k open source project Redux-Thunk
  • TS core knowledge summary and project actual case analysis