Learning Electron - Part 1
Over the holidays this year I indulged myself in some guilt-free play: learning Electron. I ran across it reading my Medium feed, via this article demonstrating how to build a sound-machine app using Electron. I didn't build the sound-machine, but I built a bunch of other stuff.
What is Electron
In a nutshell, Electron is a framework that allows you to build a desktop application (for Windows, Mac or Linux) using HTML, CSS and Javascript. So if you can create a website, you can create a desktop application.
It does this by combining Node.js and the Chromium browser engine. Node allows it to access system resources like files and networks and such, and Chromium displays the user interface. It takes these applications and packages them to create a .bim or .exe or whatever.
Node is a Javascript library that normally runs on a web server. It creates a number of functions you can use to create websites. With Node, you don't need to run a server like Apache, and you can create web applications using the same language you use in web pages. You can also download it and run it on your own computer.
Chromium, meanwhile, is the rendering engine used in some web browsers, including (most notably) Chrome, Opera, and (starting in 2019) Microsoft Edge.
Electron has been around for a few years. A number of well-known applications already use it, including Skype, Slack, Github Desktop, Beaker Browser, Ghost, Workpress, Visual Studio Code, and Atom.
Electron is open source, and learning it would make a great holiday project.
The Udemy Courses
To begin I did a fair amount of searching on the web. There's quite a bit about Electron if you look for it. I found another Medium article showing how to make an Electron BitCoin wallet. It looked intriguing (and it's something to do this spring) but I wasn't quite ready for the extra complexity.
Part of the problem was that it runs on Node, and I really didn't know Node. The articles generally assumed you had the whole Node development set-up (whatever that amounted to). After a day of scouting the terriroty I ultimately broke down and paid for a couple of Udemy courses:
- Beginner's Guide to Electron Framework - "The course will start will a detailed introduction and overview of Electron, and include topics such as understanding the IDE, modularizing your apps, utilizing associated JavaScript files, working with different Electron components."
- Building Electron Applications - "In this course, you will learn how to effectively apply your web development skills to the desktop paradigm, so you can get your desktop idea to market without any friction."
The 'regular' price for the first is $44 and the second around $125, which is quite a lot, but they were both available for $15 each back on December 25 (they're showing at about $25 today) so the price was right. I wouldn't have paid for them at the higher price.
I worked on the first course over the holidays; I haven't started the second course yet.
Getting Stated
The first thing the Udemy course talked about was the choice of Visual Studio Code to create examples and run applications.
This is an integrated development environment (IDE) from Microsoft. It is open source and runs on multiple platforms. I had been using Atom, but this runs a lot more smoothly, and even better, has a built-in terminal window so I don't have to mess around with PowerShell.
If nothing else, pointing me to Visual Studio Code made the course worth the price of admission.
Next up was Node. As I mentioned above, you have to install node on your computer. It downloads and installs like any other application. But it works more like a language (like Python or Perl) than it does an application. You run it using the terminal window. For example:
downess> node startup.js
Usually the way it works is that you write a Javascript application and then run it using Node. Doing this gives your Javascript application access to Node's built-in functions.
The Node Package Manager (NPM) is used to download and install additional functions. Like Node, it is run from the command line. For example:
downess> npm install feedreader
I found that I had to add Node to the path in order to make the 'node' and 'npm' commands work in the Microsoft terminal. It was just saying 'command not found'. I found the instructions in Stack Overflow on this page.
Node also integrates with Git. I didn't set that up, but the instructions are here.
Once the mode and npm commands are working (test them by typing node -v and npm -v) you're ready to start. This was all a lot less complicated than even these few paragraphs suggest.
Making an Application
The first module in the course took us step-by-step through a standard process for making an application. In general, we work as follows:
- create a fresh clean directory to work from
- launch Visual Studio Code and open that directory, and (under 'View') open a terminal window
- in the terminal window, type npm init (It will ask a bunch of questions; just hit Enter for each of them.)
- install Electron by typing: npm install electron
- write your code, installing any other packages you may need as you go along
- make sure your application works by running it
- build the application:
-- add a build command in package.json
-- run the build command using npm
Basically, when we're making an application, we're working with a file called package.json. Here's a sample package.json file:
When you type npm init this will build a package.json file for your new project. This file tells Node what packages it needs, how to start up, and so on. If you already have a package.json file, it will execute the file, downloading all the requirements, etc.
Next we need to install Electron. The way we do this is to install Electron as a Node package using npm. If you look inside package.json after you'll see Electron listed as a dependency. This will be true for any other package you install. This is really useful if you want to share your application; someone else can use your package.json file and install all the dependencies automatically.
The package.json file also tells Node how to run your application.Notice there's a parameter called 'main' pointing to a file called 'bootstrap.js'. Electron will start by running this file.Bootstrap does three major things:
- it sets up the communication between the different processes using something called 'ipc' (Inter Process Communication) - the course spends a lot of time explaining and showing ipc.
- it creates and sizes a browser window and loads a web page into it; the web page is the main application interface we are designing
- it creates a mechanism for shutting down the application when we're done.
You can view a sample bootstrap.js file by clicking on this link.
To build the application, we first define the build command in package.json. In the example above, you can see the command in the 'scripts' element:
"build": "rimraf hello-world-* && electron-packager . --out=win --platform=win32 --arch=x64 --overwrite --asar"
Notice that it calls three Node packages: rimraf, electron-packager, and electron-package. We had to install each of these using the npm install command. If I wanted to output versions for Apple and Linux I would include them in the same command.
Issues
The first thing I noticed was that the course was two years old, and some of the references even older. None of this impacted how everything worked, but it did occur to me that there are probably more modern ways of doing some of this stuff.
That said, I hit a big issue in this section of the course.
The instructor wanrted to do two things: first, explain in a fairly detailed way how ipc works, and second, get us into the habit of modular programming. These were both good things to do, but they weren't well done.
To show us ipc, we created an application with more than one page, such that if you clicked a button on one page, it opened a second page, and if you did something on the second page, the result could be sent to the first page. This all worked and was a really good demo of ipc.
The problem is, when we went to build the application, it didn't work. The first page would load OK, but the second page would remain blank. It wasn't just me - I could see the traces of complaints from previous students who encountered the same problem.
That's when I discovered just how awful Udemy support is. As nearly as I can just, the 'TA' has two standard responses:
- "We'll look into it." (ofd course, they don't, and we never heard from them again)
- Here's a url on Stack Overflow related to your issue (the URL is not related to the issue, it's just the first result from a quick search)
It took me a day to figure it out. The script necessarily uses relative URLs to load pages, since it will be bundled and run in some random location. However, the way the course author was identifying the current working directory functioned differently when running the script from the command line and running the executable file (this may be unique to Windows; I'm not sure).
As I wrote in the (moistly empty) discussion thread:
Confirmed, the same solution worked for me. In main.js, use the line:
win2.loadURL(path.join('file://',process.cwd(), 'resources/app/src/window2.html'))
The reason is that the packaged app refers to the source in the new packaged directory, not the original /src directory.
The video should be edited to reflect this. Although this will create the same error (only in reverse) when running 'npm start', because it won't be able to find the second window. Maybe putting stuff into a subdirectory wasn't such a great idea after all. Something to think about.
Looking at the javascrit itself, the problem seemed to be related to the use of process.cwd() instead of __dirname to identify the second files working directory, but I never fully solved this.
The whole matter left me feeling a bit jaded. It appeared to me that the scripts hadn't been properly tested before being used in the course, and worse, that the help provided by Udemy was completely indifferent.
In Part 2 (of 2) - I'll look at the applications I studied in the course.
What is Electron
In a nutshell, Electron is a framework that allows you to build a desktop application (for Windows, Mac or Linux) using HTML, CSS and Javascript. So if you can create a website, you can create a desktop application.
It does this by combining Node.js and the Chromium browser engine. Node allows it to access system resources like files and networks and such, and Chromium displays the user interface. It takes these applications and packages them to create a .bim or .exe or whatever.
Node is a Javascript library that normally runs on a web server. It creates a number of functions you can use to create websites. With Node, you don't need to run a server like Apache, and you can create web applications using the same language you use in web pages. You can also download it and run it on your own computer.
Chromium, meanwhile, is the rendering engine used in some web browsers, including (most notably) Chrome, Opera, and (starting in 2019) Microsoft Edge.
Electron has been around for a few years. A number of well-known applications already use it, including Skype, Slack, Github Desktop, Beaker Browser, Ghost, Workpress, Visual Studio Code, and Atom.
Electron is open source, and learning it would make a great holiday project.
The Udemy Courses
To begin I did a fair amount of searching on the web. There's quite a bit about Electron if you look for it. I found another Medium article showing how to make an Electron BitCoin wallet. It looked intriguing (and it's something to do this spring) but I wasn't quite ready for the extra complexity.
Part of the problem was that it runs on Node, and I really didn't know Node. The articles generally assumed you had the whole Node development set-up (whatever that amounted to). After a day of scouting the terriroty I ultimately broke down and paid for a couple of Udemy courses:
- Beginner's Guide to Electron Framework - "The course will start will a detailed introduction and overview of Electron, and include topics such as understanding the IDE, modularizing your apps, utilizing associated JavaScript files, working with different Electron components."
- Building Electron Applications - "In this course, you will learn how to effectively apply your web development skills to the desktop paradigm, so you can get your desktop idea to market without any friction."
The 'regular' price for the first is $44 and the second around $125, which is quite a lot, but they were both available for $15 each back on December 25 (they're showing at about $25 today) so the price was right. I wouldn't have paid for them at the higher price.
I worked on the first course over the holidays; I haven't started the second course yet.
Getting Stated
The first thing the Udemy course talked about was the choice of Visual Studio Code to create examples and run applications.
This is an integrated development environment (IDE) from Microsoft. It is open source and runs on multiple platforms. I had been using Atom, but this runs a lot more smoothly, and even better, has a built-in terminal window so I don't have to mess around with PowerShell.
If nothing else, pointing me to Visual Studio Code made the course worth the price of admission.
Next up was Node. As I mentioned above, you have to install node on your computer. It downloads and installs like any other application. But it works more like a language (like Python or Perl) than it does an application. You run it using the terminal window. For example:
downess> node startup.js
Usually the way it works is that you write a Javascript application and then run it using Node. Doing this gives your Javascript application access to Node's built-in functions.
The Node Package Manager (NPM) is used to download and install additional functions. Like Node, it is run from the command line. For example:
downess> npm install feedreader
I found that I had to add Node to the path in order to make the 'node' and 'npm' commands work in the Microsoft terminal. It was just saying 'command not found'. I found the instructions in Stack Overflow on this page.
Node also integrates with Git. I didn't set that up, but the instructions are here.
Once the mode and npm commands are working (test them by typing node -v and npm -v) you're ready to start. This was all a lot less complicated than even these few paragraphs suggest.
Making an Application
The first module in the course took us step-by-step through a standard process for making an application. In general, we work as follows:
- create a fresh clean directory to work from
- launch Visual Studio Code and open that directory, and (under 'View') open a terminal window
- in the terminal window, type npm init (It will ask a bunch of questions; just hit Enter for each of them.)
- install Electron by typing: npm install electron
- write your code, installing any other packages you may need as you go along
- make sure your application works by running it
- build the application:
-- add a build command in package.json
-- run the build command using npm
Basically, when we're making an application, we're working with a file called package.json. Here's a sample package.json file:
When you type npm init this will build a package.json file for your new project. This file tells Node what packages it needs, how to start up, and so on. If you already have a package.json file, it will execute the file, downloading all the requirements, etc.
Next we need to install Electron. The way we do this is to install Electron as a Node package using npm. If you look inside package.json after you'll see Electron listed as a dependency. This will be true for any other package you install. This is really useful if you want to share your application; someone else can use your package.json file and install all the dependencies automatically.
The package.json file also tells Node how to run your application.Notice there's a parameter called 'main' pointing to a file called 'bootstrap.js'. Electron will start by running this file.Bootstrap does three major things:
- it sets up the communication between the different processes using something called 'ipc' (Inter Process Communication) - the course spends a lot of time explaining and showing ipc.
- it creates and sizes a browser window and loads a web page into it; the web page is the main application interface we are designing
- it creates a mechanism for shutting down the application when we're done.
You can view a sample bootstrap.js file by clicking on this link.
To build the application, we first define the build command in package.json. In the example above, you can see the command in the 'scripts' element:
"build": "rimraf hello-world-* && electron-packager . --out=win --platform=win32 --arch=x64 --overwrite --asar"
Notice that it calls three Node packages: rimraf, electron-packager, and electron-package. We had to install each of these using the npm install command. If I wanted to output versions for Apple and Linux I would include them in the same command.
Issues
The first thing I noticed was that the course was two years old, and some of the references even older. None of this impacted how everything worked, but it did occur to me that there are probably more modern ways of doing some of this stuff.
That said, I hit a big issue in this section of the course.
The instructor wanrted to do two things: first, explain in a fairly detailed way how ipc works, and second, get us into the habit of modular programming. These were both good things to do, but they weren't well done.
To show us ipc, we created an application with more than one page, such that if you clicked a button on one page, it opened a second page, and if you did something on the second page, the result could be sent to the first page. This all worked and was a really good demo of ipc.
The problem is, when we went to build the application, it didn't work. The first page would load OK, but the second page would remain blank. It wasn't just me - I could see the traces of complaints from previous students who encountered the same problem.
That's when I discovered just how awful Udemy support is. As nearly as I can just, the 'TA' has two standard responses:
- "We'll look into it." (ofd course, they don't, and we never heard from them again)
- Here's a url on Stack Overflow related to your issue (the URL is not related to the issue, it's just the first result from a quick search)
It took me a day to figure it out. The script necessarily uses relative URLs to load pages, since it will be bundled and run in some random location. However, the way the course author was identifying the current working directory functioned differently when running the script from the command line and running the executable file (this may be unique to Windows; I'm not sure).
As I wrote in the (moistly empty) discussion thread:
Confirmed, the same solution worked for me. In main.js, use the line:
win2.loadURL(path.join('file://',process.cwd(), 'resources/app/src/window2.html'))
The reason is that the packaged app refers to the source in the new packaged directory, not the original /src directory.
The video should be edited to reflect this. Although this will create the same error (only in reverse) when running 'npm start', because it won't be able to find the second window. Maybe putting stuff into a subdirectory wasn't such a great idea after all. Something to think about.
Looking at the javascrit itself, the problem seemed to be related to the use of process.cwd() instead of __dirname to identify the second files working directory, but I never fully solved this.
The whole matter left me feeling a bit jaded. It appeared to me that the scripts hadn't been properly tested before being used in the course, and worse, that the help provided by Udemy was completely indifferent.
In Part 2 (of 2) - I'll look at the applications I studied in the course.
This comment has been removed by a blog administrator.
ReplyDelete