preface

For front-end students, we will often use a variety of small tools, such as: map bed, color pickup, two-dimensional code generator, URL management, text comparison, JSON formatting. Of course, we can manage all kinds of online gadgets in Chrome Favorites, but as a front-end with pursuit, we not only need to use ourselves, but also can give some useful tools to the team to use, improve the team’s research and development efficiency.

Therefore, based on the above demands, some client tools are made on the market or in many companies to meet the needs of their teams, most of which are implemented based on Electron. However, if this article only introduces how to make a toolset by Electron, it will be small and the pattern will be small! We don’t just empower the front end, we empower the back end, the testing, the UI, the product, even the boss. So once you get big, the toolbox is going to get very bulky and bulky. With each update, everyone has to upgrade to experience the new features. In view of the above problems, we need to design a pluggable design method, which can only be installed when it is used, and it is not necessary to install and use if it is not used. Plug-ins are distributed separately from the toolkit.

If you are also interested in such a tool, read on about the implementation process. But you can directly on the source code first:

Rubick source

The name

The first step of the beginning is to choose a good name and occupy a pit in accordance with my previous routine. I wrote a booklet of Visual Construction from 0, in which I chose the name of Coco based on DOTA. This time I named it Rubick, which means Rabick. If you know Rubick’s skill, you’ll know what it means, mainly because you can use any skill you want, and it’s pluggable. It’s also very much in line with our philosophy:

implementation

Initialize the project

Here I use Electron-Vue to do the project scaffolding, and directly follow the introduction on the official website to start to create an Electron project:

NPM install -g vue-cli vue init simulatedgreg/electron-vue rubick # install and run your program CD rubick yarn # install -g vue-cli vue init simulatedgreg/electron-vue rubick Or NPM install yarn run dev # or NPM run dev

It should be noted here that since the Electron-Vue version is too low, and the official Electron document has been updated to the latest, so if we only develop according to the Electron-Vue version and refer to the official document, You will find that there are many cases in the document that are not available. So try to upgrade to the latest version.

If you are a Windows user and experienced problems with Node-gyp, the C++ library, etc., please refer to the official documentation for the solution.

The main and renderer processes

Before development, it is necessary to understand the relationship between the main process of Electron and the Renderer process, and what is the main process: The process that runs main.js when the electron project starts is the main process, and a project has one and only one main process where all system events, such as window creation, take place. Simply put, our Electron project has only one main process, and the execution code of the main process needs to be written to main.js, where all the code related to system events will be written.

What is a renderer process? At the simplest level, the Renderer process is responsible for rendering the UI of the page that we are familiar with. There’s actually a blog post here that sums it up very well, and if you want to follow up on that you can check it out here and I’m going to start by quoting this image. This chart contains the capabilities of the main and renderer processes.

<img width=100% src=https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8210627debeb410da0317123dd40ff87~tplv-k3u1fbpfcp-watermark.image />

With this basic knowledge in mind, suppose you have reached a level of basic familiarity with electron. Let’s get started on the development. In the following development, I will refer to the design interaction of UTools to design an Electron toolbox similar to UTools step by step.

Window initialization

Electron can create a new window object through BrowserWindow. At this time, we need to build a main search window of 800 * 60. Open main.js to adjust the size and size of the window:

mainWindow = new BrowserWindow({
    height: 60,
    useContentSize: true,
    width: 800,
    frame: false,
    title: '拉比克',
    webPreferences: {
      webSecurity: false,
      enableRemoteModule: true,
      webviewTag: true,
      nodeIntegration: true
    }
})

There are a few WebPreferences parameters that need to be explained:

  • WebSecurity ifBrowserWindowSome cross-domain requests were made. Websecurity can be set to false
  • EnableRemoteModule can letrendererThe process usingremoteThe module
  • WebViewTag is allowedwebviewThe label
  • NodeIntegration allows you to use it within a Web pagenode

At this point, we can see a basic interaction window!

Developer Mode

Plug-in development needs to be coordinated with Rubick, so Rubick needs to support developer mode to help developers develop plug-ins better. To start, we’ll create a plugin.json that describes the basic information of the plug-in:

{"pluginName": "test plugin ", "author": "muwoo", "description":" My first Rubick plugin ", "main": "index.html", "version": "Hundreds" and "logo", "logo. The PNG", "name" : "rubick - plugin - demo", "gitUrl" : ""," the features ": [{" code" : "hello", "explain" : "This is a test of the plug-in", "CMDS" : [" hello222 ", "hello"]}], "preload" : "preload. Js"}
Core field description
  • namePlug-in repository name for GitHub Dowload Peugeot
  • pluginName: Plug-in name.
  • description: Plug-in description, succinctly explaining what the plug-in does
  • main: entry file. If no entry file is defined, this plug-in becomes a template plug-in
  • version: The version of the plug-in that conforms to the Semver (Semantic Version) specification. Used for version update prompts
  • features: A list of plug-in core features
  • features.code: The code passed to you when you enter the plugin. It can be used to distinguish between different functions and display different UIs
  • features.cmds: How can you access this function? Chinese will automatically support pinyin and pinyin initials. There is no need to add them again

Json into Rubick’s search box, so you need to listen for a change event in the search box to read the current clipboard copy:

OnSearch ({commit}, paylpad) {// Get the file path of clipboard copy const fileUrl = clipboard.read(' public-file-url ').replace('file://'), "); If (fileUrl && Value === 'plugin.json') {// Read the JSON file const config = JSON.parse(fs.readFileSync(fileUrl, 'utf-8')); Const PluginConfig = {... Config, // record the path of index. HTML sourceFile: path.join(fileUrl, '.. ') / ${config. The main | | 'index.html'} `), id: uuidv4 (), / / tag type: for developers' dev, / / read icon icon: 'image://' + path.join(fileUrl, `.. ${config.logo} '), subType: (() => {if (config.main) {return "} return 'template'; ()}}); }}

At this point we can get the most basic information about the plug-in based on the copied plugin.json. Now we need to show the search box:

Commit (' CommonUpdate ', {options: [{name: 'New Rubick Development Plugin ', value: 'new-plugin', icon: 'https://static.91jkys.com/activity/img/b37ff555c748489f88f3adac15b76f18.png' desc: 'new rubick development plug-in, click: (router) => {Commit (' CommonUpdate ', {showMain: true, selected: {key: 'Plugin ', name:' New Rubick '}, current: ['dev'], }); ipcRenderer.send('changeWindowSize-rubick', { height: Router.push ('/home/dev')}}, {name: 'copy path', value: 'copy path', icon: 'https://static.91jkys.com/activity/img/ac0d4df0247345b9a84c8cd7ea3dd696.png', click: () => { clipboard.writeText(fileUrl); commit('commonUpdate', { showMain: false, selected: null, options: [], }); ipcRenderer.send('changeWindowSize-rubick', { height: GetWindowHeight ([])}); remote. The Notification (' Rubick notice, {body: 'copy success'});}}});

Here, when the copy plugin.json is entered into the search box, two options will appear directly, a new plugin and a copy path function:

When you click the “New Rubick Plugin” function, you will need to jump to the Home page to load the basic class contents of the plugin. The only thing you need to note is that the height of the content loaded on the Home page should be the height of the largest window of Rubick. So we need to resize the window:

 ipcRenderer.send('changeWindowSize-rubick', {
    height: getWindowHeight(),
 });

I won’t go into details about the Vue code in the renderer, because it’s mostly CSS. Let’s go straight to the display interface:

Now that you’re done with developer mode, let’s look at how to get your plug-in running in Rubick.

Run the plugin

Containers are needed to run plug-ins, and Electron provides a WebView container to load external web pages. So we can take advantage of WebView’s ability to achieve dynamic web page rendering, here the so-called web page is a plug-in. But web pages can’t use Node’s capabilities, and the purpose of our plugins is to open up and constrain, so we need to open up some built-in API capabilities to plugins. The good news is that WebView provides a preload capability that can be preloaded to a script when the page is loaded.

This means that we can write a preload.js for our plugin to load. Preload.js: Preload.js: Preload.js: Preload.js: Preload.js: Preload.js: Preload.js: Preload.js: Preload.js: Preload.js: Preload.js:

// webview plugin.vue <webview id="webview" :src="path" :preload="preload"></webview> <script> export default { name: "Index.vue ", data() {return {path: 'File://${this.$route.query.sourcefile}', // Load preload.js preload in the current static directory: `File://${path.join(__static, './preload.js')}`, webview: null, query: this.$route.query, config: {}, } } } </script>

For preload.js we can use it like this:

if (location.href.indexOf('targetFile') > -1) { filePath = decodeURIComponent(getQueryVariable('targetFile')); } else { filePath = location.pathname.replace('file://', ''); } window.utools = {// All API implementations of utools} // Preload.js require(path.join(filePath, '.. '). /preload.js'));

Now that the plug-in has been loaded, let’s look at the effect:

conclusion

In this article, we will show you how to implement a plug-in loading process similar to UTools. However, this is far from the full scope of UTools. In the next installment, we will show you how to implement the global plug-in of UTools, such as screen color, screenshot, search, etc. Feel free to issue any questions you have about Rubick and we’ll give you feedback.

In addition, if think design implementation approach is useful to you, and welcome to a Star:https://github.com/clouDr-f2e…