DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

aurel kurtula
aurel kurtula

Posted on • Updated on

Creating a text editor in Electron: part 1 - Reading files

Let's start by creating the package.json file, and installing the required packages

{
  "name": "intro-to-electron",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "start": "electromon main.js  --ignore static"
  },
  "author": "Aurel Kurtula",
  "license": "ISC",
  "dependencies": {
    "electromon": "^1.0.10",
    "electron": "^2.0.8"
  }
}
Enter fullscreen mode Exit fullscreen mode

Now we need to create the main.js file. This is where our electron app is going to start from:

const { app, BrowserWindow } = require('electron')
const path = require('path')

app.on('ready', function(){
    let window = new BrowserWindow({width:800, height:600})
    window.loadURL(path.join('file://', __dirname, 'static/index.html'))
})
app.on('close', function() {
    window = null
})
Enter fullscreen mode Exit fullscreen mode

When the app is ready we create a window, load a static file to be rendered in. When the app closes, we make sure the browser window is removed.

Let's create the static/index.html file.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Hello World!</title>
  <link rel="stylesheet" href="./styles/main.css">
</head>
<body class="index">
  <div class="container">
    <ul id="titles"></ul>
    <div id="content" contenteditable="true">
        <p>Select a title <br />  &#x2190</p>
    </div>
  </div>
  <script src="scripts/index.js"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

It's simple really, #titles will have file titles and the #content will show their content. As you can see, it's the usual front end stuff. We have CSS and javascript.

Reading system files

I created a bunch of markdown files, placed them in a ./data directory and now we'll read them and add the titles to the app. We'll do that in static/scripts/index.js

const fs = require('fs')
const path = require('path')
const { readTitles } = require(path.resolve('actions/uiActions'))
readTitles('./data').map(({title, dir}) => {
    el = document.createElement("li");
    text = document.createTextNode(`${title.split('.md')[0]}`);
    el.appendChild(text)
    el.addEventListener('click', function(e){ // clicking on sidebar titles
        fs.readFile(dir, (err, data) => {
        if (err) throw err;
        fileDir = dir;
        document.getElementById('content').innerHTML = data;
        });
    })
    document.getElementById('titles').appendChild(el)
}) 
Enter fullscreen mode Exit fullscreen mode

In the third line I just require my module readTitles which simply reads the title and returns them as array object. I look through them, create a list element, then add an event listener which injects the contents of the file in the #content

I think this is a good point to end this introductory tutorial.

Note that the window is just a chrome browser, you are able to open dev tools on it. You can do so as usual from the view menu or you could get electron to open devtools on start. It can be done in ./main.js page

window.webContents.setDevToolsWebContents(devtools.webContents)
window.webContents.openDevTools({mode: 'detach'})
Enter fullscreen mode Exit fullscreen mode

Next time we'll start editing our data files and create our own custom menu

View code at github. Branch: part1

Top comments (7)

Collapse
 
simonhaisz profile image
simonhaisz

l ❀️ Electron apps, I don't care how much ram it eats!

I know dynamic updating html is not the core off this tutorial, but since the app is updating the DOM from files I would be amiss if I didn't flag the use of innerHTML instead of innerText. What if I wanted to include an html snippet in my README.md?

Collapse
 
defman profile image
Sergey Kislyakov

I don't care how much ram it eats!

Sad to hear that.

Collapse
 
paulgeorge92 profile image
Paul George

Files are not showing in the left pane. When I open in chrome, it shows as error require is not defined. I added reference to require.js still not working. I ran the app using node. Still not able to see the files

Collapse
 
andriybaran profile image
andriy-baran

For electron version >= 5 in main.js

mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      nodeIntegration: true // <--- Add this
    }
  })
Enter fullscreen mode Exit fullscreen mode
Collapse
 
tauseedzaman profile image
Tauseed Zaman

you imported css file which does not exists

Collapse
 
tauseedzaman profile image
Tauseed Zaman

your imported uiactions file but did not created at

Some comments may only be visible to logged-in visitors. Sign in to view all comments.

typescript

11 Tips That Make You a Better Typescript Programmer

1 Think in {Set}

Type is an everyday concept to programmers, but it’s surprisingly difficult to define it succinctly. I find it helpful to use Set as a conceptual model instead.

#2 Understand declared type and narrowed type

One extremely powerful typescript feature is automatic type narrowing based on control flow. This means a variable has two types associated with it at any specific point of code location: a declaration type and a narrowed type.

#3 Use discriminated union instead of optional fields

...

Read the whole post now!