Ivan Velasquez
Jun 11, 2020
Electron, TypeScript & React - The Holy Trinity
Ivan Velasquez
Jun 11, 2020
Electron, TypeScript & React - The Holy Trinity
Ivan Velasquez
Jun 11, 2020
Electron, TypeScript & React - The Holy Trinity
Ivan Velasquez
Jun 11, 2020
Electron, TypeScript & React - The Holy Trinity
Ivan Velasquez
Jun 11, 2020
Electron, TypeScript & React - The Holy Trinity
Electron, TypeScript & React - The Holy Trinity
During the past weeks I’ve been working on a project that involves getting Electron, TypeScript & React working together. When I started the project I did what every Sr. Software Engineer would do, I went to Google and typed “How to setup TypeScript, React & Electron”. I was expecting find a solution on the first results but I didn’t find what I was looking for. After some research, many tabs on my browser and several attempts I was able to setup correctly my development environment.
I decided to create this blog post to share with you what I called The Holy Trinity.
Project Setup
First of all you need to start your project by running
yarn init
or
npm init
After answering the questions that were prompted, it's time to install the dependencies that you need.
Project structure
This is the folder structure that I used, not sure if it is the best but it worked for me
webpack.config.js
tsconfig.json
package.json
src/
assets/
electron.ts
index.tsx
index.html
Electron
Installing Electron is the easiest task, all what you need is to install the dependency and add it to your package.json
yarn add electron -D
You can corroborate that Electron was installed correctly by creating a Hello World, just create a new file index.js
const { app } = require('electron')
app.on('ready', () => {
console.log('Hello world');
});
And then just run
electron index.js
TypeScript
In order to setup TypeScript all what you need is just to install the dependencies
yarn add typescript -D
After that you need to write your tsconfig.json. This worked like a charm for me
{
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "dom"],
"module": "es6",
"moduleResolution": "node",
"sourceMap": false,
"target": "es5",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"baseUrl": ".",
"paths": {
"@app/*": ["src/*"],
}
},
"exclude": [
"**/*.spec.ts",
"node_modules",
"vendor",
"public"
],
"compileOnSave": false
}
This may change depending on your folder structure, I like to put all my code inside a src/ directory and I also wanted to avoid the relative path hell
import Component from '.../.../../../component';
So I just declared an absolute path
....
"paths": {
"@app/*": ["src/*"],
}
...
React
yarn add react react-dom
Given that you already installed TypeScript, you might want to install @types/react as well
yarn add @types/react @types/react-dom -D
You may noticed that you didn’t used the -D when you added react and react-dom, this is due to all your JSX is converted to a syntax similar to React.createElement and hence you would require your app to have React during run time as well.
Webpack
You just installed The Holy Trinity dependencies but you still need to compile your TypeScript/React code and generate a bundle file that Electron can read, that's a task for Webpack.
You just need to install a “few” dependencies, you probably won’t need some of them.
yarn add webpack webpack-cli copy-webpack-plugin css-loader file-loader postcss-loader sass-loader style-loader ts-loader url-loader html-webpack-plugin precss autoprefixer -D
Then you must configure Webpack, this is the webpack.config.js that worked for me but it might change depending on your project folder structure.
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const mode = process.env.NODE_ENV || 'development';
module.exports = [
{
mode,
entry: {
electron: path.resolve('./src/electron.ts'),
},
target: 'electron-main',
node: false,
module: {
rules: [
{
test: /\.ts$/,
include: /src/,
use: [{ loader: 'ts-loader' }]
}
]
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js'
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
alias: {
'@app': path.resolve(__dirname, 'src/')
}
}
},
{
mode,
node: false,
entry: {
index: path.resolve('./src/index.tsx'),
},
target: 'electron-renderer',
module: {
rules: [
{
test: /\.ts(x?)$/,
include: /src/,
use: [{ loader: 'ts-loader' }]
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(scss)$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader',
}, {
loader: 'postcss-loader',
options: {
plugins: function () {
return [
require('precss'),
require('autoprefixer')
];
}
}
}, {
loader: 'sass-loader'
}]
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
issuer: {
test: /\.jsx?$/
},
use: ['babel-loader', '@svgr/webpack', 'url-loader']
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader'
},
{
test: /\.(jpe?g|png|gif)$/i,
loader: 'url-loader'
}
]
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
alias: {
'@app': path.resolve(__dirname, 'src/')
}
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CopyWebpackPlugin([
{ from:'src/assets',to:'assets' }
])
]
},
]
If you are familiarized with Electron, you might know that it has a main and render process, so I decided that the best would be writing a configuration for each process.
We need to specify an entry point and a target for each process.
Main process
entry: {
electron: path.resolve('./src/electron.ts'),
},
target: 'electron-main',
Render process
entry: {
index: path.resolve('./src/index.tsx'),
},
target: 'electron-renderer',
That's it!!! You should be able to compile your TypeScript code and execute your Electron application by just running:
./node_modules/webpack/bin/webpack.js --config ./webpack.config.js
electron ./build/electron.js
The best would be write this as scripts in the package.json
Conclusions
Setting up a development environment is not easy, it always depends on what you need. There is always the option to look for a boilerplate application and modify according to your needs. I have found that this small configuration worked perfect to me but you will need to add/remove some dependencies if you don’t need them.
You can find a boilerplate using this configuration at https://github.com/densitylabs/typescript-react-electron-boilerplate
Did you already have experience with The Holy Trinity? Would you change or add something else?
Electron, TypeScript & React - The Holy Trinity
During the past weeks I’ve been working on a project that involves getting Electron, TypeScript & React working together. When I started the project I did what every Sr. Software Engineer would do, I went to Google and typed “How to setup TypeScript, React & Electron”. I was expecting find a solution on the first results but I didn’t find what I was looking for. After some research, many tabs on my browser and several attempts I was able to setup correctly my development environment.
I decided to create this blog post to share with you what I called The Holy Trinity.
Project Setup
First of all you need to start your project by running
yarn init
or
npm init
After answering the questions that were prompted, it's time to install the dependencies that you need.
Project structure
This is the folder structure that I used, not sure if it is the best but it worked for me
webpack.config.js
tsconfig.json
package.json
src/
assets/
electron.ts
index.tsx
index.html
Electron
Installing Electron is the easiest task, all what you need is to install the dependency and add it to your package.json
yarn add electron -D
You can corroborate that Electron was installed correctly by creating a Hello World, just create a new file index.js
const { app } = require('electron')
app.on('ready', () => {
console.log('Hello world');
});
And then just run
electron index.js
TypeScript
In order to setup TypeScript all what you need is just to install the dependencies
yarn add typescript -D
After that you need to write your tsconfig.json. This worked like a charm for me
{
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "dom"],
"module": "es6",
"moduleResolution": "node",
"sourceMap": false,
"target": "es5",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"baseUrl": ".",
"paths": {
"@app/*": ["src/*"],
}
},
"exclude": [
"**/*.spec.ts",
"node_modules",
"vendor",
"public"
],
"compileOnSave": false
}
This may change depending on your folder structure, I like to put all my code inside a src/ directory and I also wanted to avoid the relative path hell
import Component from '.../.../../../component';
So I just declared an absolute path
....
"paths": {
"@app/*": ["src/*"],
}
...
React
yarn add react react-dom
Given that you already installed TypeScript, you might want to install @types/react as well
yarn add @types/react @types/react-dom -D
You may noticed that you didn’t used the -D when you added react and react-dom, this is due to all your JSX is converted to a syntax similar to React.createElement and hence you would require your app to have React during run time as well.
Webpack
You just installed The Holy Trinity dependencies but you still need to compile your TypeScript/React code and generate a bundle file that Electron can read, that's a task for Webpack.
You just need to install a “few” dependencies, you probably won’t need some of them.
yarn add webpack webpack-cli copy-webpack-plugin css-loader file-loader postcss-loader sass-loader style-loader ts-loader url-loader html-webpack-plugin precss autoprefixer -D
Then you must configure Webpack, this is the webpack.config.js that worked for me but it might change depending on your project folder structure.
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const mode = process.env.NODE_ENV || 'development';
module.exports = [
{
mode,
entry: {
electron: path.resolve('./src/electron.ts'),
},
target: 'electron-main',
node: false,
module: {
rules: [
{
test: /\.ts$/,
include: /src/,
use: [{ loader: 'ts-loader' }]
}
]
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js'
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
alias: {
'@app': path.resolve(__dirname, 'src/')
}
}
},
{
mode,
node: false,
entry: {
index: path.resolve('./src/index.tsx'),
},
target: 'electron-renderer',
module: {
rules: [
{
test: /\.ts(x?)$/,
include: /src/,
use: [{ loader: 'ts-loader' }]
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(scss)$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader',
}, {
loader: 'postcss-loader',
options: {
plugins: function () {
return [
require('precss'),
require('autoprefixer')
];
}
}
}, {
loader: 'sass-loader'
}]
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
issuer: {
test: /\.jsx?$/
},
use: ['babel-loader', '@svgr/webpack', 'url-loader']
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader'
},
{
test: /\.(jpe?g|png|gif)$/i,
loader: 'url-loader'
}
]
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
alias: {
'@app': path.resolve(__dirname, 'src/')
}
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CopyWebpackPlugin([
{ from:'src/assets',to:'assets' }
])
]
},
]
If you are familiarized with Electron, you might know that it has a main and render process, so I decided that the best would be writing a configuration for each process.
We need to specify an entry point and a target for each process.
Main process
entry: {
electron: path.resolve('./src/electron.ts'),
},
target: 'electron-main',
Render process
entry: {
index: path.resolve('./src/index.tsx'),
},
target: 'electron-renderer',
That's it!!! You should be able to compile your TypeScript code and execute your Electron application by just running:
./node_modules/webpack/bin/webpack.js --config ./webpack.config.js
electron ./build/electron.js
The best would be write this as scripts in the package.json
Conclusions
Setting up a development environment is not easy, it always depends on what you need. There is always the option to look for a boilerplate application and modify according to your needs. I have found that this small configuration worked perfect to me but you will need to add/remove some dependencies if you don’t need them.
You can find a boilerplate using this configuration at https://github.com/densitylabs/typescript-react-electron-boilerplate
Did you already have experience with The Holy Trinity? Would you change or add something else?
Electron, TypeScript & React - The Holy Trinity
During the past weeks I’ve been working on a project that involves getting Electron, TypeScript & React working together. When I started the project I did what every Sr. Software Engineer would do, I went to Google and typed “How to setup TypeScript, React & Electron”. I was expecting find a solution on the first results but I didn’t find what I was looking for. After some research, many tabs on my browser and several attempts I was able to setup correctly my development environment.
I decided to create this blog post to share with you what I called The Holy Trinity.
Project Setup
First of all you need to start your project by running
yarn init
or
npm init
After answering the questions that were prompted, it's time to install the dependencies that you need.
Project structure
This is the folder structure that I used, not sure if it is the best but it worked for me
webpack.config.js
tsconfig.json
package.json
src/
assets/
electron.ts
index.tsx
index.html
Electron
Installing Electron is the easiest task, all what you need is to install the dependency and add it to your package.json
yarn add electron -D
You can corroborate that Electron was installed correctly by creating a Hello World, just create a new file index.js
const { app } = require('electron')
app.on('ready', () => {
console.log('Hello world');
});
And then just run
electron index.js
TypeScript
In order to setup TypeScript all what you need is just to install the dependencies
yarn add typescript -D
After that you need to write your tsconfig.json. This worked like a charm for me
{
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "dom"],
"module": "es6",
"moduleResolution": "node",
"sourceMap": false,
"target": "es5",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"baseUrl": ".",
"paths": {
"@app/*": ["src/*"],
}
},
"exclude": [
"**/*.spec.ts",
"node_modules",
"vendor",
"public"
],
"compileOnSave": false
}
This may change depending on your folder structure, I like to put all my code inside a src/ directory and I also wanted to avoid the relative path hell
import Component from '.../.../../../component';
So I just declared an absolute path
....
"paths": {
"@app/*": ["src/*"],
}
...
React
yarn add react react-dom
Given that you already installed TypeScript, you might want to install @types/react as well
yarn add @types/react @types/react-dom -D
You may noticed that you didn’t used the -D when you added react and react-dom, this is due to all your JSX is converted to a syntax similar to React.createElement and hence you would require your app to have React during run time as well.
Webpack
You just installed The Holy Trinity dependencies but you still need to compile your TypeScript/React code and generate a bundle file that Electron can read, that's a task for Webpack.
You just need to install a “few” dependencies, you probably won’t need some of them.
yarn add webpack webpack-cli copy-webpack-plugin css-loader file-loader postcss-loader sass-loader style-loader ts-loader url-loader html-webpack-plugin precss autoprefixer -D
Then you must configure Webpack, this is the webpack.config.js that worked for me but it might change depending on your project folder structure.
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const mode = process.env.NODE_ENV || 'development';
module.exports = [
{
mode,
entry: {
electron: path.resolve('./src/electron.ts'),
},
target: 'electron-main',
node: false,
module: {
rules: [
{
test: /\.ts$/,
include: /src/,
use: [{ loader: 'ts-loader' }]
}
]
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js'
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
alias: {
'@app': path.resolve(__dirname, 'src/')
}
}
},
{
mode,
node: false,
entry: {
index: path.resolve('./src/index.tsx'),
},
target: 'electron-renderer',
module: {
rules: [
{
test: /\.ts(x?)$/,
include: /src/,
use: [{ loader: 'ts-loader' }]
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(scss)$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader',
}, {
loader: 'postcss-loader',
options: {
plugins: function () {
return [
require('precss'),
require('autoprefixer')
];
}
}
}, {
loader: 'sass-loader'
}]
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
issuer: {
test: /\.jsx?$/
},
use: ['babel-loader', '@svgr/webpack', 'url-loader']
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader'
},
{
test: /\.(jpe?g|png|gif)$/i,
loader: 'url-loader'
}
]
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
alias: {
'@app': path.resolve(__dirname, 'src/')
}
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CopyWebpackPlugin([
{ from:'src/assets',to:'assets' }
])
]
},
]
If you are familiarized with Electron, you might know that it has a main and render process, so I decided that the best would be writing a configuration for each process.
We need to specify an entry point and a target for each process.
Main process
entry: {
electron: path.resolve('./src/electron.ts'),
},
target: 'electron-main',
Render process
entry: {
index: path.resolve('./src/index.tsx'),
},
target: 'electron-renderer',
That's it!!! You should be able to compile your TypeScript code and execute your Electron application by just running:
./node_modules/webpack/bin/webpack.js --config ./webpack.config.js
electron ./build/electron.js
The best would be write this as scripts in the package.json
Conclusions
Setting up a development environment is not easy, it always depends on what you need. There is always the option to look for a boilerplate application and modify according to your needs. I have found that this small configuration worked perfect to me but you will need to add/remove some dependencies if you don’t need them.
You can find a boilerplate using this configuration at https://github.com/densitylabs/typescript-react-electron-boilerplate
Did you already have experience with The Holy Trinity? Would you change or add something else?
Electron, TypeScript & React - The Holy Trinity
During the past weeks I’ve been working on a project that involves getting Electron, TypeScript & React working together. When I started the project I did what every Sr. Software Engineer would do, I went to Google and typed “How to setup TypeScript, React & Electron”. I was expecting find a solution on the first results but I didn’t find what I was looking for. After some research, many tabs on my browser and several attempts I was able to setup correctly my development environment.
I decided to create this blog post to share with you what I called The Holy Trinity.
Project Setup
First of all you need to start your project by running
yarn init
or
npm init
After answering the questions that were prompted, it's time to install the dependencies that you need.
Project structure
This is the folder structure that I used, not sure if it is the best but it worked for me
webpack.config.js
tsconfig.json
package.json
src/
assets/
electron.ts
index.tsx
index.html
Electron
Installing Electron is the easiest task, all what you need is to install the dependency and add it to your package.json
yarn add electron -D
You can corroborate that Electron was installed correctly by creating a Hello World, just create a new file index.js
const { app } = require('electron')
app.on('ready', () => {
console.log('Hello world');
});
And then just run
electron index.js
TypeScript
In order to setup TypeScript all what you need is just to install the dependencies
yarn add typescript -D
After that you need to write your tsconfig.json. This worked like a charm for me
{
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "dom"],
"module": "es6",
"moduleResolution": "node",
"sourceMap": false,
"target": "es5",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"baseUrl": ".",
"paths": {
"@app/*": ["src/*"],
}
},
"exclude": [
"**/*.spec.ts",
"node_modules",
"vendor",
"public"
],
"compileOnSave": false
}
This may change depending on your folder structure, I like to put all my code inside a src/ directory and I also wanted to avoid the relative path hell
import Component from '.../.../../../component';
So I just declared an absolute path
....
"paths": {
"@app/*": ["src/*"],
}
...
React
yarn add react react-dom
Given that you already installed TypeScript, you might want to install @types/react as well
yarn add @types/react @types/react-dom -D
You may noticed that you didn’t used the -D when you added react and react-dom, this is due to all your JSX is converted to a syntax similar to React.createElement and hence you would require your app to have React during run time as well.
Webpack
You just installed The Holy Trinity dependencies but you still need to compile your TypeScript/React code and generate a bundle file that Electron can read, that's a task for Webpack.
You just need to install a “few” dependencies, you probably won’t need some of them.
yarn add webpack webpack-cli copy-webpack-plugin css-loader file-loader postcss-loader sass-loader style-loader ts-loader url-loader html-webpack-plugin precss autoprefixer -D
Then you must configure Webpack, this is the webpack.config.js that worked for me but it might change depending on your project folder structure.
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const mode = process.env.NODE_ENV || 'development';
module.exports = [
{
mode,
entry: {
electron: path.resolve('./src/electron.ts'),
},
target: 'electron-main',
node: false,
module: {
rules: [
{
test: /\.ts$/,
include: /src/,
use: [{ loader: 'ts-loader' }]
}
]
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js'
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
alias: {
'@app': path.resolve(__dirname, 'src/')
}
}
},
{
mode,
node: false,
entry: {
index: path.resolve('./src/index.tsx'),
},
target: 'electron-renderer',
module: {
rules: [
{
test: /\.ts(x?)$/,
include: /src/,
use: [{ loader: 'ts-loader' }]
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(scss)$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader',
}, {
loader: 'postcss-loader',
options: {
plugins: function () {
return [
require('precss'),
require('autoprefixer')
];
}
}
}, {
loader: 'sass-loader'
}]
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
issuer: {
test: /\.jsx?$/
},
use: ['babel-loader', '@svgr/webpack', 'url-loader']
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader'
},
{
test: /\.(jpe?g|png|gif)$/i,
loader: 'url-loader'
}
]
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
alias: {
'@app': path.resolve(__dirname, 'src/')
}
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CopyWebpackPlugin([
{ from:'src/assets',to:'assets' }
])
]
},
]
If you are familiarized with Electron, you might know that it has a main and render process, so I decided that the best would be writing a configuration for each process.
We need to specify an entry point and a target for each process.
Main process
entry: {
electron: path.resolve('./src/electron.ts'),
},
target: 'electron-main',
Render process
entry: {
index: path.resolve('./src/index.tsx'),
},
target: 'electron-renderer',
That's it!!! You should be able to compile your TypeScript code and execute your Electron application by just running:
./node_modules/webpack/bin/webpack.js --config ./webpack.config.js
electron ./build/electron.js
The best would be write this as scripts in the package.json
Conclusions
Setting up a development environment is not easy, it always depends on what you need. There is always the option to look for a boilerplate application and modify according to your needs. I have found that this small configuration worked perfect to me but you will need to add/remove some dependencies if you don’t need them.
You can find a boilerplate using this configuration at https://github.com/densitylabs/typescript-react-electron-boilerplate
Did you already have experience with The Holy Trinity? Would you change or add something else?
Electron, TypeScript & React - The Holy Trinity
During the past weeks I’ve been working on a project that involves getting Electron, TypeScript & React working together. When I started the project I did what every Sr. Software Engineer would do, I went to Google and typed “How to setup TypeScript, React & Electron”. I was expecting find a solution on the first results but I didn’t find what I was looking for. After some research, many tabs on my browser and several attempts I was able to setup correctly my development environment.
I decided to create this blog post to share with you what I called The Holy Trinity.
Project Setup
First of all you need to start your project by running
yarn init
or
npm init
After answering the questions that were prompted, it's time to install the dependencies that you need.
Project structure
This is the folder structure that I used, not sure if it is the best but it worked for me
webpack.config.js
tsconfig.json
package.json
src/
assets/
electron.ts
index.tsx
index.html
Electron
Installing Electron is the easiest task, all what you need is to install the dependency and add it to your package.json
yarn add electron -D
You can corroborate that Electron was installed correctly by creating a Hello World, just create a new file index.js
const { app } = require('electron')
app.on('ready', () => {
console.log('Hello world');
});
And then just run
electron index.js
TypeScript
In order to setup TypeScript all what you need is just to install the dependencies
yarn add typescript -D
After that you need to write your tsconfig.json. This worked like a charm for me
{
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es6", "dom"],
"module": "es6",
"moduleResolution": "node",
"sourceMap": false,
"target": "es5",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"baseUrl": ".",
"paths": {
"@app/*": ["src/*"],
}
},
"exclude": [
"**/*.spec.ts",
"node_modules",
"vendor",
"public"
],
"compileOnSave": false
}
This may change depending on your folder structure, I like to put all my code inside a src/ directory and I also wanted to avoid the relative path hell
import Component from '.../.../../../component';
So I just declared an absolute path
....
"paths": {
"@app/*": ["src/*"],
}
...
React
yarn add react react-dom
Given that you already installed TypeScript, you might want to install @types/react as well
yarn add @types/react @types/react-dom -D
You may noticed that you didn’t used the -D when you added react and react-dom, this is due to all your JSX is converted to a syntax similar to React.createElement and hence you would require your app to have React during run time as well.
Webpack
You just installed The Holy Trinity dependencies but you still need to compile your TypeScript/React code and generate a bundle file that Electron can read, that's a task for Webpack.
You just need to install a “few” dependencies, you probably won’t need some of them.
yarn add webpack webpack-cli copy-webpack-plugin css-loader file-loader postcss-loader sass-loader style-loader ts-loader url-loader html-webpack-plugin precss autoprefixer -D
Then you must configure Webpack, this is the webpack.config.js that worked for me but it might change depending on your project folder structure.
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const mode = process.env.NODE_ENV || 'development';
module.exports = [
{
mode,
entry: {
electron: path.resolve('./src/electron.ts'),
},
target: 'electron-main',
node: false,
module: {
rules: [
{
test: /\.ts$/,
include: /src/,
use: [{ loader: 'ts-loader' }]
}
]
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js'
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
alias: {
'@app': path.resolve(__dirname, 'src/')
}
}
},
{
mode,
node: false,
entry: {
index: path.resolve('./src/index.tsx'),
},
target: 'electron-renderer',
module: {
rules: [
{
test: /\.ts(x?)$/,
include: /src/,
use: [{ loader: 'ts-loader' }]
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(scss)$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader',
}, {
loader: 'postcss-loader',
options: {
plugins: function () {
return [
require('precss'),
require('autoprefixer')
];
}
}
}, {
loader: 'sass-loader'
}]
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
issuer: {
test: /\.jsx?$/
},
use: ['babel-loader', '@svgr/webpack', 'url-loader']
},
{
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
loader: 'url-loader'
},
{
test: /\.(jpe?g|png|gif)$/i,
loader: 'url-loader'
}
]
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
alias: {
'@app': path.resolve(__dirname, 'src/')
}
},
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CopyWebpackPlugin([
{ from:'src/assets',to:'assets' }
])
]
},
]
If you are familiarized with Electron, you might know that it has a main and render process, so I decided that the best would be writing a configuration for each process.
We need to specify an entry point and a target for each process.
Main process
entry: {
electron: path.resolve('./src/electron.ts'),
},
target: 'electron-main',
Render process
entry: {
index: path.resolve('./src/index.tsx'),
},
target: 'electron-renderer',
That's it!!! You should be able to compile your TypeScript code and execute your Electron application by just running:
./node_modules/webpack/bin/webpack.js --config ./webpack.config.js
electron ./build/electron.js
The best would be write this as scripts in the package.json
Conclusions
Setting up a development environment is not easy, it always depends on what you need. There is always the option to look for a boilerplate application and modify according to your needs. I have found that this small configuration worked perfect to me but you will need to add/remove some dependencies if you don’t need them.
You can find a boilerplate using this configuration at https://github.com/densitylabs/typescript-react-electron-boilerplate
Did you already have experience with The Holy Trinity? Would you change or add something else?
Guadalajara
Werkshop - Av. Acueducto 6050, Lomas del bosque, Plaza Acueducto. 45116,
Zapopan, Jalisco. México.
Texas
5700 Granite Parkway, Suite 200, Plano, Texas 75024.
© Density Labs. All Right reserved. Privacy policy and Terms of Use.
Guadalajara
Werkshop - Av. Acueducto 6050, Lomas del bosque, Plaza Acueducto. 45116,
Zapopan, Jalisco. México.
Texas
5700 Granite Parkway, Suite 200, Plano, Texas 75024.
© Density Labs. All Right reserved. Privacy policy and Terms of Use.
Guadalajara
Werkshop - Av. Acueducto 6050, Lomas del bosque, Plaza Acueducto. 45116,
Zapopan, Jalisco. México.
Texas
5700 Granite Parkway, Suite 200, Plano, Texas 75024.
© Density Labs. All Right reserved. Privacy policy and Terms of Use.