Skip to content

Commit b6ff12e

Browse files
itsanandersonJohn Kleinschmidt
andauthored
docs: update Quick Start Guide for Electron 12 (electron#28223)
* docs: Update Quick Start Guide for Electron 12 With `contextIsolation` enabled by default in Electron 12, the Getting Started Guide no longer works as it is written. In order for the basic example to display values from `process.versions`, we need to add a `preload.js` to the example. * fix: annotate preload code block with a language * docs: update quick-start Fiddle example to use preload to provide version info * fix: ensure example files end in a newline * docs: add security warning to instructions for turning off contextIsolation Co-authored-by: John Kleinschmidt <jkleinsc@github.com> * docs: treat preload as an adjective instead of a noun Co-authored-by: John Kleinschmidt <jkleinsc@github.com> Co-authored-by: John Kleinschmidt <jkleinsc@github.com>
1 parent 80f89a3 commit b6ff12e

File tree

4 files changed

+71
-28
lines changed

4 files changed

+71
-28
lines changed

docs/fiddles/quick-start/index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
<body>
99
<h1>Hello World!</h1>
1010
<p>
11-
We are using node <script>document.write(process.versions.node)</script>,
12-
Chrome <script>document.write(process.versions.chrome)</script>,
13-
and Electron <script>document.write(process.versions.electron)</script>.
11+
We are using Node.js <span id="node-version"></span>,
12+
Chromium <span id="chrome-version"></span>,
13+
and Electron <span id="electron-version"></span>.
1414
</p>
1515
</body>
1616
</html>

docs/fiddles/quick-start/main.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,31 @@
11
const { app, BrowserWindow } = require('electron')
2+
const path = require('path')
23

34
function createWindow () {
45
const win = new BrowserWindow({
56
width: 800,
67
height: 600,
78
webPreferences: {
8-
nodeIntegration: true,
9-
contextIsolation: false
9+
preload: path.join(__dirname, 'preload.js')
1010
}
1111
})
1212

1313
win.loadFile('index.html')
1414
}
1515

16-
app.whenReady().then(createWindow)
16+
app.whenReady().then(() => {
17+
createWindow()
18+
19+
app.on('activate', () => {
20+
if (BrowserWindow.getAllWindows().length === 0) {
21+
createWindow()
22+
}
23+
})
24+
})
1725

1826
app.on('window-all-closed', () => {
1927
if (process.platform !== 'darwin') {
2028
app.quit()
2129
}
2230
})
2331

24-
app.on('activate', () => {
25-
if (BrowserWindow.getAllWindows().length === 0) {
26-
createWindow()
27-
}
28-
})
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
window.addEventListener('DOMContentLoaded', () => {
2+
const replaceText = (selector, text) => {
3+
const element = document.getElementById(selector)
4+
if (element) element.innerText = text
5+
}
6+
7+
for (const type of ['chrome', 'node', 'electron']) {
8+
replaceText(`${type}-version`, process.versions[type])
9+
}
10+
})
11+

docs/tutorial/quick-start.md

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ From a development perspective, an Electron application is essentially a Node.js
3232
my-electron-app/
3333
├── package.json
3434
├── main.js
35+
├── preload.js
3536
└── index.html
3637
```
3738

@@ -55,45 +56,49 @@ The main script may look as follows:
5556

5657
```javascript fiddle='docs/fiddles/quick-start'
5758
const { app, BrowserWindow } = require('electron')
59+
const path = require('path')
5860

5961
function createWindow () {
6062
const win = new BrowserWindow({
6163
width: 800,
6264
height: 600,
6365
webPreferences: {
64-
nodeIntegration: true
66+
preload: path.join(__dirname, 'preload.js')
6567
}
6668
})
6769

6870
win.loadFile('index.html')
6971
}
7072

71-
app.whenReady().then(createWindow)
73+
app.whenReady().then(() => {
74+
createWindow()
75+
76+
app.on('activate', () => {
77+
if (BrowserWindow.getAllWindows().length === 0) {
78+
createWindow()
79+
}
80+
})
81+
)
7282

7383
app.on('window-all-closed', () => {
7484
if (process.platform !== 'darwin') {
7585
app.quit()
7686
}
7787
})
78-
79-
app.on('activate', () => {
80-
if (BrowserWindow.getAllWindows().length === 0) {
81-
createWindow()
82-
}
83-
})
8488
```
8589
8690
##### What is going on above?
8791
8892
1. Line 1: First, you import the `app` and `BrowserWindow` modules of the `electron` package to be able to manage your application's lifecycle events, as well as create and control browser windows.
89-
2. Line 3: After that, you define a function that creates a [new browser window](../api/browser-window.md#new-browserwindowoptions) with node integration enabled, loads `index.html` file into this window (line 12, we will discuss the file later).
90-
3. Line 15: You create a new browser window by invoking the `createWindow` function once the Electron application [is initialized](../api/app.md#appwhenready).
91-
4. Line 17: You add a new listener that tries to quit the application when it no longer has any open windows. This listener is a no-op on macOS due to the operating system's [window management behavior](https://support.apple.com/en-ca/guide/mac-help/mchlp2469/mac).
92-
5. Line 23: You add a new listener that creates a new browser window only if when the application has no visible windows after being activated. For example, after launching the application for the first time, or re-launching the already running application.
93+
2. Line 2: Second, you import the `path` package which provides utility functions for file paths.
94+
3. Line 4: After that, you define a function that creates a [new browser window](../api/browser-window.md#new-browserwindowoptions) with a preload script, loads `index.html` file into this window (line 13, we will discuss the file later).
95+
4. Line 16: You create a new browser window by invoking the `createWindow` function once the Electron application [is initialized](../api/app.md#appwhenready).
96+
5. Line 18: You add a new listener that creates a new browser window only if when the application has no visible windows after being activated. For example, after launching the application for the first time, or re-launching the already running application.
97+
6. Line 25: You add a new listener that tries to quit the application when it no longer has any open windows. This listener is a no-op on macOS due to the operating system's [window management behavior](https://support.apple.com/en-ca/guide/mac-help/mchlp2469/mac).
9398
9499
#### Create a web page
95100
96-
This is the web page you want to display once the application is initialized. This web page represents the Renderer process. You can create multiple browser windows, where each window uses its own independent Renderer. Each window can optionally be granted with full access to Node.js API through the `nodeIntegration` preference.
101+
This is the web page you want to display once the application is initialized. This web page represents the Renderer process. You can create multiple browser windows, where each window uses its own independent Renderer. You can optionally grant access to additional Node.js APIs by exposing them from your preload script.
97102
98103
The `index.html` page looks as follows:
99104
@@ -108,14 +113,38 @@ The `index.html` page looks as follows:
108113
<body style="background: white;">
109114
<h1>Hello World!</h1>
110115
<p>
111-
We are using node <script>document.write(process.versions.node)</script>,
112-
Chrome <script>document.write(process.versions.chrome)</script>,
113-
and Electron <script>document.write(process.versions.electron)</script>.
116+
We are using Node.js <span id="node-version"></span>,
117+
Chromium <span id="chrome-version"></span>,
118+
and Electron <span id="electron-version"></span>.
114119
</p>
115120
</body>
116121
</html>
117122
```
118123
124+
#### Define a preload script
125+
126+
Your preload script acts as a bridge between Node.js and your web page. It allows you to expose specific APIs and behaviors to your web page rather than insecurely exposing the entire Node.js API. In this example we will use the preload script to read version information from the `process` object and update the web page with that info.
127+
128+
```javascript fiddle='docs/fiddles/quick-start'
129+
window.addEventListener('DOMContentLoaded', () => {
130+
const replaceText = (selector, text) => {
131+
const element = document.getElementById(selector)
132+
if (element) element.innerText = text
133+
}
134+
135+
for (const type of ['chrome', 'node', 'electron']) {
136+
replaceText(`${type}-version`, process.versions[type])
137+
}
138+
})
139+
```
140+
141+
##### What's going on above?
142+
143+
1. On line 1: First you define an event listener that tells you when the web page has loaded
144+
2. On line 2: Second you define a utility function used to set the text of the placeholders in the `index.html`
145+
3. On line 7: Next you loop through the list of components whose version you want to display
146+
4. On line 8: Finally, you call `replaceText` to look up the version placeholders in `index.html` and set their text value to the values from `process.versions`
147+
119148
#### Modify your package.json file
120149
121150
Your Electron application uses the `package.json` file as the main entry point (as any other Node.js application). The main script of your application is `main.js`, so modify the `package.json` file accordingly:
@@ -283,7 +312,7 @@ ipcRenderer.invoke('perform-action', ...args)
283312
284313
##### Node.js API
285314
286-
> NOTE: To access the Node.js API from the Renderer process, you need to set the `nodeIntegration` preference to `true`.
315+
> NOTE: To access the Node.js API from the Renderer process, you need to set the `nodeIntegration` preference to `true` and the `contextIsolation` preference to `false`. Please note that access to the Node.js API in any renderer that loads remote content is not recommended for [security reasons](../tutorial/security.md#2-do-not-enable-nodejs-integration-for-remote-content).
287316
288317
Electron exposes full access to Node.js API and its modules both in the Main and the Renderer processes. For example, you can read all the files from the root directory:
289318

0 commit comments

Comments
 (0)