Translation | Chapter 19 of "JavaScript Everywhere" Integrating Existing Web Applications with Electron
Write at the top
Hello everyone, I am Mao Xiaoyou, a front-end development engineer. An English technical book is being translated.
In order to improve everyone's reading experience, the structure and content of sentences have been slightly adjusted. If you find any flaws in this article, or if you have any comments or suggestions, you can leave a message in the comment area, or add my WeChat: code
_maomao, welcome to communicate and learn from each other.
(σ゚∀゚)σ…:*☆Oh, good
Chapter 19 Integrating Existing Web Applications with Electron
I like to collect browser bookmarks, just like a child collecting shells on the beach. I don't have to collect them, but by the end of the day, I have opened many tabs in several browser windows. I'm not showing off, but I suspect it's more than me. So, I used Web
desktop versions of some of the most commonly used applications. Usually, these applications have no advantages over the web version, but the convenience of standalone applications makes them easy to access, find, and switch throughout the day.
In this chapter, we will study how to get existing Web
applications and package them in Electron Shell
. Before proceeding, you will need to install a local copy of the sample API
and Web
application. If you have not read the entire book, please visit the appendix A
and appendix B
to operate.
Integrate our web application
In the previous chapter, we set up the Electron
application load index.html
file. We can also load specific ones URL
. In this example, we will start by loading a locally running Web
application URL
. First of all, make sure that your Web
application is API
running locally. Then we can update the src/index.js
file, first BrowserWindow
in the nodeIntegration
set false
. This will avoid the security risks of locally running node applications accessing external sites.
webPreferences: {
nodeIntegration: false
},
Now, change window.loadFile
(' index.html
'); as follows:
window.loadURL('http://localhost:1234');
Run the web application
Web
The local instance of your application will need to 1234
be running on the port. If you have been reading this book, please run from Web
the root of the application directory npm start
to start the development server.
This will indicate Electron
loading URL
, not file. Now, if you use to npm start
run the application, you will see that it has been loaded into the Electron
window, but there are some warnings.
Warnings and errors
Electron
The browser developer tools and our terminal display a lot of warnings and errors. Let's take a look at each of them (see picture 19-1
).
Figure 19-1
. Our application is running, but it shows a lot of errors and warnings.
First of all, our terminal displays a lot SyntaxError
: Unexpected Token errors.
In addition, our developer tools will display several corresponding warnings, indicating that it DevTools
cannot be parsed SourceMap
. These two errors are related Parcel
to the way they are generated source map
and Electron
read source map
. Unfortunately, combined with the technology we are using, there seems to be no reasonable solution to this problem. The best option is to disable JavaScript
source mapping. In the developer tools of the application window, click "Settings" and uncheck "Enable JavaScript
source mapping" (see image 19-2
).
Figure 19-2
. Disabling source mapping will reduce the number of errors and warnings
Now, if you quit and restart the application, you will no longer see issues related to the source map. Cost of doing so is that Electron
within debugging client JavaScript
may be more difficult, but the good news is, we can still Web
access this feature and our application browser.
The last two warnings are related Electron
to security. We will fix these issues before bundling production applications together, but now it is worth exploring what these warnings are.
-
Electron Security Warning
(Insecure Resources
) Electronic safety warning (resources are not safe)This warning informs us that we are
http
loadingWeb
resources through the connection . In production, we should alwayshttps
load resources to ensure privacy and security. In development, byhttp
loading the local host is not a problem, because we will refer to the hosting website, which is used in the bundled applicationhttps
. -
Electron Security Warning
(Insecure Content-Security-Policy
) Electronic security warning (unsafe content security policy)This warning informs us that we have not yet set a content security policy (
CSP
).CSP
Allows us to specify the domain from which our application is allowed to load resources, which greatly reduces the risk of cross-site scripting (XSS
) attacks. Again, this is not a problem during local development, but it is important in production. We will use it later in this chapterCSP
.
After solving our error, we can set the application configuration file.
Configuration
When developing locally, we want to be able to run Web
the local version of the application, but when bundling the application for others to use, we want it to reference the publicly available URL
. We can set up a simple configuration file to handle this problem.
./ in our src
catalog, we will add a config.js
file, in which we can attribute to store application-specific. I have included a configuration template. You can use it to easily copy it from the terminal:
cp src/config.example.js src/config.js
Now we can fill in the properties of the application:
const config = {
LOCAL_WEB_URL: 'http://localhost:1234/',
PRODUCTION_WEB_URL: 'https://YOUR_DEPLOYED_WEB_APP_URL',
PRODUCTION_API_URL: 'https://YOUR_DEPLOYED_API_URL'
};
module.exports = config;
Why not use .env?
In the previous environment, we used env
.files to manage environment-specific settings. In this case, because of the way the Electron
application bundles its dependencies, we use JavaScript
configuration files.
Now in Electron
the main process of the application, we can use the configuration file to specify what we want to load in development and production URL
. Now src/index.js
, first import the config.js
file:
const config = require('./config');
Now, we can update the loadURL
function to load different for each environment URL
:
// load the URL
if (is.development) {
window.loadURL(config.LOCAL_WEB_URL);
} else {
window.loadURL(config.PRODUCTION_WEB_URL);
}
By using configuration files, we can easily Electron
provide environment-specific settings.
Content security policy
As mentioned earlier in this chapter, it CSP
allows us to restrict whether the application has the right to load the domain name of the resource. This helps limit potential XSS
and data injection attacks. In Electron
, we can specify CSP
settings to help improve the security of the application. To learn more about electronics and Web
applications CSP
, I suggest you MDN
articles on the subject .
Electron
Provides CSP
built-in for API
, but the electronic-util
library provides a simpler and more concise syntax. At src/index.js
the top of ours , update the electronic-util
import statement to include setContentSecurityPolicy
:
const {
is, setContentSecurityPolicy } = require('electron-util');
Now, we can set up for the production version of the application CSP
:
// set the CSP in production mode
if (!is.development) {
setContentSecurityPolicy(`
default-src 'none';
script-src 'self';
img-src 'self' https://www.gravatar.com;
style-src 'self' 'unsafe-inline';
font-src 'self';
connect-src 'self' ${
config.PRODUCTION_API_URL};
base-uri 'none';
form-action 'none';
frame-ancestors 'none';
`);
}
By writing CSP
, we can use the CSP
evaluation program tool to check errors. If we intend to URL
access resources through other , we can add them to the CSP
rule set.
src/index.js
The contents of our final file are as follows:
const {
app, BrowserWindow } = require('electron');
const {
is, setContentSecurityPolicy } = require('electron-util');
const config = require('./config');
// to avoid garbage collection, declare the window as a variable
let window;
// specify the details of the browser window
function createWindow() {
window = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: false
}
});
// load the URL
if (is.development) {
window.loadURL(config.LOCAL_WEB_URL);
} else {
window.loadURL(config.PRODUCTION_WEB_URL);
}
// if in development mode, open the browser dev tools
if (is.development) {
window.webContents.openDevTools();
}
// set the CSP in production mode
if (!is.development) {
setContentSecurityPolicy(` default-src 'none';
script-src 'self';
img-src 'self' https://www.gravatar.com;
style-src 'self' 'unsafe-inline';
font-src 'self';
connect-src 'self' ${
config.PRODUCTION_API_URL};
base-uri 'none';
form-action 'none';
frame-ancestors 'none'; `);
}
// when the window is closed, dereference the window object
window.on('closed', () => {
window = null;
});
}
// when electron is ready, create the application window
app.on('ready', createWindow);
// quit when all windows are closed.
app.on('window-all-closed', () => {
// On macOS only quit when a user explicitly quits the application
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
// on macOS, re-create the window when the icon is clicked in the dock
if (window === null) {
createWindow();
}
});
In this way, we can Electron Shell
run the Web
application in (as 19-3
shown).
Figure 19-3
. The Electron
app we shell
run in the Web
app
in conclusion
In this chapter, we integrate existing Web
applications into Electron
desktop applications, which allows us to quickly bring desktop applications to the market. It is worth noting that this approach requires trade-offs, as it provides desktop-specific advantages and requires a Internet
connection to access the full functionality of the application. For those of us who want to bring desktop applications to market, these shortcomings may be worthwhile. In the next chapter, we will study how to build and distribute Electron
applications.
If there is any inadequate understanding, please correct me. If you think it's okay, please like to collect or share it, hoping to help more people.