This is the 63rd article without water, if you want to get more original articles, please scan the qr code at ð. This article is launched in front of the early chat: cross-terminal and cross-stack serial 3/7: Electron build cross-platform desktop application
To introduce myself
Welcome to today’s special talk about cross-terminal and cross-stack. Today, MY topic is “How to develop cross-terminal Applications based on Electron”. First, I would like to introduce myself. My name is Lu Ziyang. I joined Zhengcaiyun in 17 years, and now I am mainly responsible for the front-end engineering platform Dunhuang of Zhengcaiyun and the construction of its electronic bidding client. Here is our team’s wechat official account. If you want to know more about our team, you can pay attention to our official account.
The first piece we share is called terminal extension. I don’t know if you are familiar with this picture, some time ago we should have heard the news, Silicon Valley Iron Man Elon Musk released the first commercial manned dragon spacecraft, this picture is the dragon spacecraft console, someone on Zhihu comments on this picture called JS heaven. Why say JS heaven? It was rumored to be based on Electron, but this has not been confirmed. But one thing we can confirm is that the shuttle’s touch interface UI is based on Chromium + JavaScript architecture. This, to some extent, illustrates the usability and stability of this architecture.
Let’s review the development of the front end in the whole field. In the early days, the definition of front-end engineer might be Web development based on the browser runtime environment, but with the emergence of Node.js in 2009, front-end engineer has the ability to develop outside of the browser runtime environment. We have the capability to develop towards the server side, and the front-end capability extends to the server side.
With the development of THE HTML5 standard and the development of mobile device technology, front-end engineers can also embrace more development for mobile scenarios. There are also cross-platform technology solutions like React Native, a mobile domain, which the two lecturers talked about this morning. As mobile APP becomes a mainstream, the front-end is also popularized to Iot devices based on these intelligent devices and the computing power of chips. The front-end can have the development capability for Iot, and JS framework for Iot devices development like Thing.js is born.
CLI -> GUI
Today’s topic is the desktop, and with the advent of cross-terminal JS frameworks like Electron, the capabilities of front-end engineers extend to the desktop as well. What is the value of having such a desktop development capability? First, let’s take a look at how the desktop experience is different. On the left, you can see an early DOS operating screen shot, and on the right, in 1983, Apple Lisa was the first PERSONAL computer in the world to have a graphical user interface, or GUI, as we call it. Let the late popularization of personal computer to achieve the popularization. The reason why it drives the popularity of personal computers is that graphical interfaces are more visually acceptable to users and the cost of learning has dropped dramatically. I believe that students who have used the MAC system will have a profound feeling of apple’s excellent interface design and overall interactive experience.
So what difference does this desktop GUI technology make to my front-end development work?
I believe you are familiar with the process on the left. What might we need to do when we start new project development? The first step might be to create a Git repository, clone the repository locally, and then run a command such as XXX -cli create to create a project after installing the CLI tool within the team. After creating the project, if you want to develop it, you need to run NPM Install, install the required dependencies, and eventually commit the entire project to a Git repository. This is the creation of our new project, an operation process based on CLI.
What changes can we make based on the capabilities of the client? As we can see, the figure on the right is the system screenshot of dunhuang, the front-end engineering platform of our team. To create a new project, just select your own creation method and enter the necessary parameters such as the Git repository Group you want to create, project name, and scaffolding type. Click Create Project and it will automatically complete the process shown on the left. That is to say, the six steps on the left are simplified to two steps, greatly simplifying the operation link.
Value given by GUI
What value does the GUI give us? First of all, it can be dispersed task point to a series of integrated, provides a more simplified the operation of the link, at the same time it also can be erased the differences between different students when using some process, as well as the process relies on some of the differences in environment, and based on GUI is an integrated ability, we can also use other ability for a horizontal collusion, And designing plug-in mechanisms through GUIs can also create a co-built ecosystem. At the same time, the low learning cost of gui-based graphical interface operation, as well as its hosting of the whole process, can greatly reduce the research and development complexity of the team students.
Service Scenario Application
The following are landing scenarios of some key applications developed based on Electron. This is the business of the electronic bidding client of zhengcai Cloud, which I am responsible for. Its main function is to help users to change from the traditional offline bidding, paper bidding, to electronic bidding, we provide such a client can help users to series the whole process of bidding. At the same time, based on the capability of Node.js provided by Electron, users can read and write local bidding files, as well as encrypt and decrypt local files, all of which can be completed inside the client.
Infrastructure Application
Here is the practice of Electron on our engineering platform, which is the front engineering platform we mentioned earlier – Dunhuang. What it does is it hosts the whole front-end development process, like the project creation we just mentioned. We will also introduce some of these applications in detail below.
Development mode
Above we have outlined some of the values of Electron. If we wanted to develop a cross-platform desktop application based on Electron, how would we do it? Let’s take a look at part 2: ** Development patterns. How is the development mode of **Electron different from our normal Web development?
Electron architecture
First of all, this is an overall architecture of Electron. It is an open source framework developed by Github that allows us to use HTML + CSS + Javascript to build and develop desktop applications, greatly reducing the complexity of desktop application development. The core of the overall architecture is Chromium + Node.js + Native APIs. Chromium provides UI capabilities, Node.js makes Electron capable of low-level operations, and Navtive APIs solve some cross-platform problems. For example, there are some differences between Windows, MAC OS and Linux, and it also provides a more unified experience of native capabilities.
Ability to point
Let’s talk about some of its core capability points.
-
First of all, Chromium, we can understand it as a Chrome browser with the latest browser features. The advantage it brings us is that we don’t need to consider the compatibility of browsers in the development process. We can use some of the latest ES6 and ES7 syntax, and we can safely use Flex layout. As well as the latest browser features, you can try them out, regardless of compatibility.
-
Node.js provides the ability to read and write files, call local commands, and extend third parties. Based on the entire node.js ecosystem, nearly hundreds of thousands of Node.js modules can be used in the entire client.
-
Native APIs provide the ability to provide a unified Native interface that includes system notifications, keyboard shortcuts, and access to system hardware information. It also provides basic desktop client capabilities, such as update mechanisms and crash reporting.
Comparison of selection of other desktop terminals
Electron offers these capability points that greatly reduce the cost of desktop development and the barriers to getting started. Of course, for desktop development, there will be some other models besides Electron, so let’s take a look at how it compares to other models.
- Native development is the first choice for desktop development. However, when developing different platforms, different languages need to be used. However, its advantages are better Native experience and better running performance, but its threshold is relatively high.
- QT is a cross-platform desktop development framework based on C++. The language it uses is C++. In terms of overall performance and experience, QT is comparable to Native development, but the development threshold is relatively high due to the technology stack.
- The other two are Electron and Nw.js. Both use Javascript as a development language. Compared to Native and QT, they are quite friendly to front-end engineers, and they have a similar architecture, both based on Chromium + Node.js, and both have a cross-platform support capability. However, the difference between the two is that Electron has a better community ecology and community activity. If we encounter some problems at ordinary times, there may be more and more perfect solutions in the community, and its response speed to issues is also relatively fast.
So based on the above comparison, Electron is a very good choice for front end engineers to develop desktop clients.
Structure for simple Electron applications
Now, what do you do if you want to develop a desktop client? Here is the simplest Electron desktop application structure. We only need three files. First, we define a startup entry for the application using the main field in package.json. We defined the entry file as main.js. What did we do in mian. First, app represents the entire application and monitors the state of the app. When the entire application reaches a ready state, a new BrowserWindow is created through the BrowserWindow provided by Electron. After creating the browser window, load the index. HTML file and you have a basic desktop application. How is developing a desktop application based on Electron different from developing a Web application based on Electron? We need to understand two core concepts: the main process and the renderer process, and how the communication between the two processes is implemented. In the example above, main.js is run in the main process and index.html is run in the renderer process. Let’s use a simple Demo to see how two processes can communicate and make some Node.js power calls through the main process.
Communication between processes
What we want to do is have a button on the page, and when the button is clicked, it sends a say-Hello message to the main process, and when the main process receives the message, it creates a file on the system desktop called Hello.txt. And write Hello Mac! . What exactly did we do?
First in the render process, we should have a button action event on the page. When the event is triggered, we send a message called say-Hello to the main process via the ipcRenderer API provided by Electron. When our main process receives such a message, we can call node.js’s FS module, which reads and writes files, directly from the main process. We start by creating a file and writing the transfer to it. After the file is written successfully, the renderer process is replied and the system Notification is displayed to inform the user by calling the Notification module provided by Electron. This is a simple Demo implementation. The core point is to pay attention to the concept of the main process and the renderer process. And how two processes communicate with each other through the IPC mechanism. Here is a simple implementation. There are a few more application scenarios that I won’t go into too much about the API here.
We will introduce the Electron development practice according to a practical application.
Engineering CLI -> GUI
Taking dunhuang, our front-end engineering platform, as an example, this paper introduces how we change the engineering capability from CLI to GUI through Electron. Let’s start with a video that demonstrates the entire process of creating a project that we mentioned at the beginning. As you can see, the whole process has completed the creation of the Git repository, the creation of the project template, the push of the project template to the repository, and the local cloning of the Git project. After the cloning is completed, the dependent installation will be carried out, and the process will be reloaded and managed on the client side. A series of previously scattered single point command operations through the GUI. This process is just one part of the engineering platform, in which we have realized a lot of single point command to workflow series.
I2P Install To Publish
Here is the system architecture of our whole front-end application management platform. The core process is an I2P concept written above, which is install to publish. It completes the component, template, and project levels, hosting the entire process from creation to release.
- The creation stage mainly provides local creation, Git creation, unified creation template management, creation process approval and creation completion feedback.
- In the development phase, it provides a Dev Server operation capability, project-level page management, dependency management, branch management, and one-click upgrade capability. At the same time, the CI/CD continuous integration capability is also opened.
- In the release stage, it provides a pre-release permission verification and compliance testing, resource push and release approval mechanism.
- Data analysis is a core part of our whole process. It is to precipitate some data of our whole process and output these data in the form of visual statements. Based on these data, the whole I2P process is connected with other capabilities.
Throughout the I2P process above, we precipitated some project data, including process data, and possibly some component management-like data. With data as the connection point, the whole R&D process can be connected in series with some other technical construction capabilities, including user behavior analysis, page-level, project-level performance analysis reports, and error monitoring mechanisms, which can be connected to the entire engineering platform. What underpins our entire engineering platform are some of the basic capabilities and the desktop capabilities that Electron provides. Basic capabilities, including some general GIt operations, NPM operations, some command execution, and some local Logger services. Electron provides desktop features including updates, window management, communications, and some native capabilities.
From point to line
Single point command -> Task flow
Let’s look specifically at how to implement a cascade from a single point of command to a task flow. To transform the operation of a single point of command into a concatenation pattern of task flow, we will do so from the following four entry points. ⢠First we will change some of the normal command calls into functional calls. ⢠Orchestrate and assemble a task flow based on these functional calls, customizing a task flow based on actual development scenarios. ⢠The third thing we need is the task progress feedback mechanism of the whole task flow, how to execute the task, through the ability of GUI, so that users can intuitively feel the execution link and progress of the whole task. ⢠Finally, an important piece of the overall task flow is data collection for the entire process.
Process design
Here is the architectural design of the project creation process we just demonstrated. When we call the project creation module, we will first create Git projects through the Server interface. After the verification is passed, a warehouse is created by calling Gitlab API. After that, a unified project template is pulled according to the selected template information, and a real project file is generated according to the project name, project description and other information entered by the user. Call the Gitlab API to push the entire project file to the repository you created. About the use of Gitlab API this piece, in the nuggets have been shared articles, if you are interested in it, you can go to know, here will not be detailed. After completing a series of Git creation operations on the server, the url of the successful repository will be sent to the desktop. After receiving the result of the successful creation, the desktop will start to execute some local operations. Clone the Git repository to your local workspace while completing the dependency installation for the entire project. After dependency installation, we will use desktop notification capabilities, including the pin interface to complete notification and feedback. Cloning, dependent installation, and notification feedback are done in the main process on our desktop. It has real-time message feedback with the renderer process throughout our task flow. We will communicate the progress of the whole task, including the log output of command execution and the result of command execution, with the rendering in real time through IPC, and finally give feedback to the user on the interface. Project and process data are also stored throughout the process.
What are the practical aspects of implementing this process? Let’s take a look at the code.
NPM install changes to npm.install()
First, change the command line call mode of NPM install to a functional call mode, which will be changed to NPM.install().
Git init becomes git.init()
Git commands are also called functionally
Promise the imperative execution
Let’s take a look at how to turn an imperative call into a functional call for a specific scenario. The first is to Promise the command. For example, git init, when executing the entire command, we care more about the result of the command execution than the output content during the command execution. This way we can start the spawn process in Node.js to execute the command. By listening to the output of the child process to determine the execution status of our entire command, and then wrapping the entire command with a Promise, we have changed a command line call to git init into an asynchronous function call to git.init().
Command execution logs are displayed in real time
In other scenarios, such as NPM install, dependent installation, or starting local development services, the entire command execution process may be longer, and we are more concerned with real-time logging during the process. How do we do that? First of all, we created an EventEmitter instance to manage the distribution of our logs. Similarly, we started a sub-process to execute commands through spwan, monitored the output of the sub-process in real time, and distributed the output logs through the Emitter instance. After we get such real-time log output in the main process, we can output the log to the rendering process in real time through the Electron main process and the IPC communication between the rendering process.
With the ability to turn imperative calls into functional calls, you can orchestrate the flow of tasks by calling these functions. For example, we mentioned project creation, which is probably a more general process, as well as component management, template management and project publishing. You can arrange your own task flow according to your actual business needs.
Analog terminal: feedback task progress
Above we mentioned some changes to the overall command execution in the main process. So how do we implement end-log feedback in our rendering process like the one in the previous video? There are many ways to give feedback. We can give feedback on the progress of the whole task by designing some step bars or progress bars. But a better way is to provide timely feedback on the progress of the task, including the entire task output log. Here we use xterm.js. It is a front-end terminal component written based on TS, can achieve terminal applications in the browser, VsCode is based on xterm.js to achieve the terminal. How do the main process of log to output to the rendering process, is mentioned above, we get the broadcast by a EventEmitter output, to pass the main process and the communication between the rendering process, will push data to the rendering process, the rendering process need to do a deal with, to accept to the command output, Render in real time to terminal components implemented by Xterm.
This completes the feedback mechanism for the entire task flow.
The above is the realization of a task flow in our engineering platform. With the help of Electron capability, we can easily realize the arrangement of tasks in the whole process and the interface interaction of the corresponding process, thus simplifying the whole process. In addition to the realization of the task flow, we need to be more concerned about is the process of data collection, including the process data and precipitation process created in the project, the component data, also include some abnormal data of process, because these data are the basis of the process and other construction ability, the basis of get through at the same time also can let us to the whole process of continuous optimization,
update
After completing the development of the client, we need to consider the subsequent update. Let’s take a look at how we can implement the automatic update function of the client.
Electron provides a relatively complete package update mechanism.
After building our application through election-Builder, we will output a latest-Mac. yml file and the application ZIP package, and put these two files on the update server. There are many implementation schemes of the update server, and we choose CDN as the update server. How do we design the entire update process? In the rendering process, there is usually a trigger entry to manually check the update, or through polling task, to periodically check the version update. After the renderer process initiates a version check, the renderer process calls the autoUpdater module, which is the update management module built into Electron. The first step is to set the feedUrl, which is the latest update package to update the server address. The checkForUpdates method is called after receiving a version check request from the renderer process. After that, the checkForUpdates method will trigger the following series of events. We can control the update process by monitoring the entire lifecycle of the update event.
The problem with Electron’s built-in update mechanism is that the update packet is large. Because the desktop application that we built with Electron, which integrates all Chromium, even if we wrote a tiny Hello World app, it would be about 40MB compressed, A typical application might take up about 100MB. The problem is that some small changes need to be fully updated, which is not very good for the user experience. What solutions do we have for these? First of all, we can make an optimization on the interaction design of the whole update. What we need to provide is a feedback on the progress of the whole update process, and the other thing is that we can download in the background through autoUpdater. After downloading the entire update package, we will notify users to restart the entire application and then update the entire application. In this way, from the interactive level, some impacts of incremental updates on users’ experience will be avoided to a certain extent. Of course, there is a problem with full update. If the number of users is large, network resources will be wasted.
delta
Here are some of our practices for incremental releases. First, the static resources of the entire Renderer layer are managed by CDN. For our entire application, static resources in the Renderer layer will not be packaged into the final desktop application, and resources will be remotely hosted. Meanwhile, according to some specific business scenarios, we can make use of the service worker ability to do an offline cache for the whole resource, and do version control for static resources.
Update process
An update process in the Renderer layer looks like this: when a page makes a request, it first matches the local cache for a resource, and if it matches a resource, it returns the result. If there is no local match, the latest resource is requested again and the requested resource is cached. If an error occurs throughout the request, a default version of the resource needs to be available and the error reported. One of the things we’ve implemented here is an incremental update based on the UI layer. In actual business scenarios, depending on the update frequency of different resources, it is necessary to decide whether to optimize the experience of the update, or to use the incremental update of the UI layer or the incremental update of the installation package.
Technical framework drawing of Dunhuang Engineering Platform
Over here is the architecture of the entire application management platform, in our practice, the whole project in addition to the implementation of the whole project, components and templates I2P whole process managed, we also provide other skills, such as team entry of convergence, including document entry, output entrance, will also be some of the tools for an integrated within the team, We integrate some tools scattered in various places, such as document site generation tool, graph bed tool and IconFONT management tool. Meanwhile, we also collect the user behavior data of the whole client and continue to iterate through data analysis.
More scenes
Above our practice based on Electron front-end engineering platform. Of course, Electron will have some other applications, so let’s take a look.
First of all, VS Code and the IDE of Alipay mini program are also based on Electron framework
On the left is an interface management desktop tool that provides ancillary functionality to the development process. Another Switchhosts, which is a local environment management tool. You can see the desktop application developed based on Electron. In our whole r&d process, our local environment management, process management, development assistance and r&d editing stages are involved. The engineering management platform is complicit in the whole process of the r&d life cycle, but in the actual coding stage, there is still a separate link, still need to rely on the ability of the IDE. Based on the possibility of Electron in IDE direction, one of our future directions is also to collude the local coding environment of the entire IDE with our whole R&D process, so as to realize the collusion and efficiency upgrade of the whole R&D link in a real sense.
Of course, there are many more possibilities, such as the aforementioned spaceX bigger scenario ~
Recommend a book
Here is a book I personally recommend, The Road Less Traveled, to learn how to look at problems with a more mature mind. As we grow, we are more likely to be constrained by cognitive and mental limitations. What kind of cognition and mentality to treat problems will determine what kind of response and what kind of ability to respond to these problems. This book will allow us to explore more how we can look at our problems with a more mature mind. I hope that through this book, we can learn how to better face the problems beyond technology and solve the problems better.
recruitment
Above is all my share today. Here is the QR code of our team’s official account, you can go to know some of our team’s output. At the same time, we are recruiting front-end interns, senior and senior front-end engineers recently. If you are interested, please send your resume to the email below. Thank you
QA
Ask ziyang: how to carry out hot update? As FAR as I know, the page packed by Electron is placed inside the package. How to update it online?
I understand that the problem should be UI level interface updates. In fact, I have mentioned just now, we have some static page resources is made a CDN managed, at the time of the update, there will be a testing update mechanism, it can be done by polling or server push, when I received the notice of static resources version updates, through the main process for rendering process a mandatory ignore the cache refresh, Alternatively, users can trigger page reloads to update static resources at the UI level through interaction in the main process, including upgrade reminders and update logs.
Ziyang: Can you compare the difference between Electron and Nw.js?
The biggest difference between the two is that the integration of node.js and Chromium event loops is handled differently. First of all, nw. js makes the Chromium and Node.js event loop mechanism open by modifying the source code. Electron implements the mechanism by enabling a new secure thread to forward events between Node.js and Chromium. One advantage of this is that the Chromium and Node.js event loops are not so strongly coupled. Another difference is that Nw.js supports XP, while Electron does not. Has more active community in comparison Electron, and more large applications such as VS code, Atom practice case, more can refer to the difference between Electron official introduction: www.electronjs.org/docs/develo…
Is the update package file stored on a private file server or Gitlab or Github?
There are many ways, our implementation is through the hosting of CDN, can also be through Github or private file server to build to achieve. Choose according to your actual business scenario and technology stack.
, recruiting
ZooTeam, a young passionate and creative front-end team, belongs to the PRODUCT R&D department of ZooTeam, based in picturesque Hangzhou. The team now has more than 50 front-end partners, with an average age of 27, and nearly 30% of them are full-stack engineers, no problem in the youth storm group. The members consist of “old” soldiers from Alibaba and netease, as well as fresh graduates from Zhejiang University, University of Science and Technology of China, Hangzhou Electric And other universities. In addition to daily business docking, the team also carried out technical exploration and practice in material system, engineering platform, building platform, performance experience, cloud application, data analysis and visualization, promoted and implemented a series of internal technical products, and continued to explore the new boundary of front-end technology system.
If you want to change what’s been bothering you, you want to start bothering you. If you want to change, you’ve been told you need more ideas, but you don’t have a solution. If you want change, you have the power to make it happen, but you don’t need it. If you want to change what you want to accomplish, you need a team to support you, but you don’t have the position to lead people. If you want to change the pace, it will be “5 years and 3 years of experience”; If you want to change the original savvy is good, but there is always a layer of fuzzy window… If you believe in the power of believing, believing that ordinary people can achieve extraordinary things, believing that you can meet a better version of yourself. If you want to be a part of the process of growing a front end team with deep business understanding, sound technology systems, technology value creation, and impact spillover as your business takes off, I think we should talk. Any time, waiting for you to write something and send it to [email protected]