Getting Started with Electron, Typescript, React and Webpack

Initialise and an empty electron project

npm init -y
npm install --save-dev electron
// src/electron.js
const { app, BrowserWindow } = require('electron');
function createWindow () {
// Create the browser window.
let win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
});
// and load the index.html of the app.
win.loadFile('index.html');
}
app.on('ready', createWindow);
<!-- // src/index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<div id="app">
<h1>Hello World!</h1>
</div>
</body>
</html>
// package.json
"scripts": {
"start": "electron src/electron.js"
}

Adding TypeScript

npm install --save-dev typescript
touch tsconfig.json
"scripts": {
"build": "tsc src/electron.ts"
}

Adding Webpack

npm install --save-dev webpack webpack-cli ts-loader
// webpack.config.js
module.exports = [
{
mode: 'development',
entry: './src/electron.ts',
target: 'electron-main',
module: {
rules: [{
test: /\.ts$/,
include: /src/,
use: [{ loader: 'ts-loader' }]
}]
},
output: {
path: __dirname + '/src',
filename: 'electron.js'
}
}
];
  • mode: develop Development build (as opposed to production).
  • entry: './src/electron.ts Location of the entry point
  • target: 'electron-main' Specifies which environment to target; Webpack knows about the electron main process specifically.
  • test: /\.ts$/ Specifies that this rule should match all files that end with the .ts extension.
  • include: /src/ Specifies that all files within src should be considered for matching this rule.
  • use: [{ loader: 'ts-loader' }] Specifies which loader(s) to use when this rule matches.
  • path: __dirname + '/src' Directory where all output files will be placed.
  • filename: 'electron.js' Primary output bundle filename.
// package.json
"scripts": {
"build": "webpack --config ./webpack.config.js",
"start": "npm run build && electron ./src/electron.js"
}

Adding React

npm install --save-dev react react-dom @types/react @types/react-dom
// src/react.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
const Index = () => {
return <div>Hello React!</div>;
};
ReactDOM.render(<Index />, document.getElementById('app'));
// tsconfig.json
{
"compilerOptions": {
"jsx": "react"
}
}
npm install --save-dev html-webpack-plugin
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = [
...
{
mode: 'development',
entry: './src/react.tsx',
target: 'electron-renderer',
devtool: 'source-map',
module: { rules: [{
test: /\.ts(x?)$/,
include: /src/,
use: [{ loader: 'ts-loader' }]
}] },
output: {
path: __dirname + '/dist',
filename: 'react.js'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
}
];
  • target: 'electron-renderer' Specifies which environment to target; Webpack knows about the electron renderer process specifically.
  • plugins ... Specifies any plugins used during the build process. Plugins differ from loaders in that plugins operate at the bundle level and can more deeply integrate with the build process via hooks. Loaders operate at the file level. The HtmlWebpackPlugin will automagically add a reference to the output bundle in the specified template file.
// webpack.config.js
...
output: {
path: __dirname + '/dist',
filename: 'electron.js'
}
"scripts": {
...
"start": "npm run build && electron ./dist/electron.js"
}

Conclusion

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Achuth hadnoor

On my way to be an indie developer, creator creating a focus on better living.