- Overview of the Application Architecture & Configuration
- Dependencies and Libraries
- Setup Development Mode
- Packaging & Deployment
- Security
- New Feature Workflow
- External Resources
The FINANCES app leverages the Electron framework, which allows for a separation of concerns between the backend logic ('main' process) and the rendering logic ('renderer' process).
src
: The source directory containing all the application code.data
: Stores data files used by the application, such astam_form_data.json
, which could contain form data for the Target Allocation Maintenance feature.main
: Contains the backend logic of the Electron app.main.js
: The entry point for the Electron main process.preload.js
: Script that can safely run before the renderer process is loaded.services
: Contains backend services.
renderer
: Contains the rendering logic for the Electron app.App.tsx
: The main React component that wraps the entire renderer process UI.api
: Contains API-related code, possibly for communicating between the renderer and main processes.assets
: Static assets like images, logos, etc.components
: Reusable React components.context
: React Contexts for state management across the application.pages
: React components that represent entire pages or routes in the application.styles
: Contains global CSS files for styling the application.utils
: Utility functions and types for the application.
The application is configured using several files:
package.json
: Lists all the dependencies and scripts needed for the project.package-lock.json
: Provides version information for all packages installed which ensures that the same version of a package is used on all environments.tsconfig.main.json
andtsconfig.renderer.json
: Configuration files for TypeScript compilation in the main and renderer processes respectively.webpack.main.config.js
andwebpack.renderer.config.js
: Define the configuration for Webpack to bundle the main and renderer process code..gitignore
: Specifies intentionally untracked files to ignore by Git..prettierrc
: Configuration for Prettier, an opinionated code formatter, ensuring code style consistency.postcss.config.js
: Configuration for PostCSS, a tool for transforming CSS with JavaScript plugins.tailwind.config.js
: Configuration for TailwindCSS, a utility-first CSS framework.public/index.html
: The main HTML file that serves as the entry point to the renderer process.
The app is built using a variety of dependencies listed in the project's package.json
file. Here is the list of key dependencies and development dependencies:
-
Main Dependencies:
chart.js
: Charting library used for visualizations like the pie and bar charts.formik
: Library to manage form state in React.fs
: Filesystem module to interact with the file system.lucide-react
: React icons library.path
: Utility module to handle file paths.react-chartjs-2
: React wrapper forchart.js
.react-hot-toast
: Library for creating toast notifications.react-router-dom
: DOM bindings for React Router.yup
: Schema builder for value parsing and validation.
-
Development Dependencies:
- Babel and TypeScript-related packages for compiling JavaScript and TypeScript.
- Electron and Webpack for bundling and running the Electron application.
- TailwindCSS and PostCSS for styling.
- Various loaders and plugins for handling different file types in the Webpack build process.
To optimize the development environment for efficiency, such as enabling hot reload, certain modifications are necessary:
-
In
main.js
:-
Disable
contextIsolation
and removepreload
innew BrowserWindow
parameters:contextIsolation: false // preload: path.join(__dirname, 'preload.bundle.js')
-
Load from localhost during development instead of the
index.html
file:// win.loadFile("index.html"); win.loadURL('http://localhost:8080')
-
Optionally, open the developer tools by default:
win.webContents.openDevTools()
-
-
In
public/index.html
:-
Disable the
Content-Security-Policy
meta tag, by adding 'unsafe-eval' in the script-src parameter of content attribute:<meta http-equiv="Content-Security-Policy" content=" default-src 'none'; script-src 'self' 'unsafe-eval'; <--- this connect-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; font-src 'self'; object-src 'none'; " />
-
-
In
renderer/api/electron.tsx
:If
preload
andcontextIsolation
were previously set, theipcRenderer
cannot be used directly. It is necessary to call functions defined inpreload.js
:-
Original code using
ipcRenderer
directly:import { ipcRenderer } from 'electron' export function useIpcRenderer() { const sendRequestData = () => { ipcRenderer.send('request-data-channel') } .... }
-
Modified code calling functions from
preload.js
:export function useIpcRenderer() { const sendRequestData = () => { window.electron.requestData() } .... }
-
-
In
./webpack.renderer.config.js
&./webpack.main.config.js
(OPTIONAL: for better quicker launch):-
Set
mode
todevelopment
:module.exports = { mode: 'development', ... }
-
Make sure to revert these changes when preparing the application for production to ensure security and proper file path resolution.
When you're ready to build the FINANCES app for production, certain parameters in the package.json
file under the build
property determine how the application is packaged for different operating systems:
appId
: The unique identifier for your app, usually in reverse domain notation. For this app, it is set as"io.dopee.finances"
.productName
: The name of the product as it should appear in the installer and on the computer. For this app, it is"Finances"
.directories
: Defines where the output of the build process should be placed. Here, it is set to the"dist_packaged"
directory.files
: Specifies which files and directories are included in the build. This typically includes thedist
folder,node_modules
, andpackage.json
.win
: Configuration specific to Windows builds.target
: The type of the installer, set to"nsis"
for a Windows installer.icon
: The path to the application icon file for Windows, set to"dist/icons/logo.ico"
.
mac
: Configuration specific to macOS builds.target
: The type of the distribution, set to"dmg"
for a macOS disk image.icon
: The path to the application icon file for macOS, set to"dist/icons/logo.icns"
.
linux
: Configuration specific to Linux builds.target
: The type of the distribution, set to"AppImage"
which is a common Linux package format.icon
: The path to the application icon file for Linux, set to"dist/icons/logo.png"
.
The package.json
also defines scripts to package the application:
"pack": "electron-builder --dir --mac"
: This command packages the app for macOS without creating an installer. The application is packaged in a directory (useful for testing the packaged app without installing it)."dist": "electron-builder --win --mac --linux"
: This command is used to package and create installers for all target operating systems (Windows, macOS, and Linux).
To package the app, you must follow these steps:
- Run
npm install
to ensure all node modules are installed. - Execute
npm run build
to create thedist
folder with all the files bundled for production. - Choose one of the following:
- Run
npm run pack
if you need to package the app for macOS in a directory format for testing purposes. - Run
npm run dist
if you want to create installers for one or all of the specified operating systems.
- Run
The pack
script is typically used for generating a testable build without generating an installer, while dist
is used for creating the final distribution installers that end-users would download and install.
For security within the Electron framework, the following practices are generally recommended and should be implemented:
- Use of
contextIsolation
in the Electron renderer process to ensure that preload scripts run in a separate context from the page. - Enable
nodeIntegration
andenableRemoteModule
only if absolutely necessary and understand the security implications of doing so. - Sanitize any data that is being sent from and to the renderer process to prevent code injection attacks.
For more details on Electron's security recommendations, it is advised to refer to the official Electron security documentation.
In the index.html
file, a critical security feature implemented is the Content Security Policy (CSP), which is defined by the following meta
element:
<meta
http-equiv="Content-Security-Policy"
content=" default-src 'none';
script-src 'self';
connect-src 'self';
img-src 'self' data:;
style-src 'self' 'unsafe-inline';
font-src 'self';
object-src 'none';"
/>
This CSP meta tag serves several important security purposes:
- default-src 'none';: This is the default policy for loading content such as JavaScript, Images, CSS, Fonts, AJAX requests, Frames, HTML5 Media. By setting it to 'none', it restricts all content sources by default, which means the page won’t load any content unless explicitly allowed by other CSP rules.
- script-src 'self';: Allows the execution of scripts only from the current origin (
'self'
). This means only scripts that are part of your application can be executed, significantly reducing the risk of XSS (Cross-Site Scripting) attacks. - connect-src 'self';: Restricts the URLs which can be loaded using script interfaces. Setting this to
'self'
only allows connections (AJAX requests, WebSockets) to the same origin as the application. This helps prevent data exfiltration to untrusted sources. - img-src 'self' data:;: Defines which images can be displayed on your application.
'self'
allows images from the same origin, anddata:
allows images to be included directly in the document using a data URI. - style-src 'self' 'unsafe-inline';: Specifies where styles can be loaded from.
'self'
allows only styles from the same origin.'unsafe-inline'
permits the use of inline styles, which can be necessary for some applications but is less secure as it allows the execution of inline scripts. - font-src 'self';: Controls which font resources can be loaded. Only fonts from the same origin are allowed.
- object-src 'none';: Prevents the application from loading plugins (like Flash or Java applets), which can be a security risk.
By defining a strict CSP, the application mitigates the risk of content injection vulnerabilities, including XSS attacks, which are a common threat to web applications.
To add a new feature to the FINANCES app, follow these steps which cover changes across both the main and renderer processes:
- Function Implementation: Implement the necessary functions within the
main
logic. This includes creating new service functions that the feature will require to operate. - Preload Endpoints: If using a
preload.js
file, define a new endpoint that the renderer process will use to access the new functions in the main process.
- API Endpoint: Add the new endpoint function within the
renderer/api/electron.js
file. This should mirror the structure of existing endpoints to maintain consistency. - Function Declaration: Declare the function signature in the
src/type.d.ts
file to provide TypeScript definitions, which will prevent IDE errors related to undefined functions. - Feature Page: Create a new page component in the
renderer/pages
directory that will serve as the interface for your new feature. Utilize the newly created API function within this component. - Routing: Integrate the new page into the application's routing by adding an entry in the
renderer/App.tsx
file. Assign it a route path that reflects the feature name (e.g.,/feature-name
). - Sidebar Link: Add a new link in the
renderer/components/Sidebar.tsx
for easy navigation to your feature. Ensure consistency with existing links and utilize an appropriate icon from the Lucide Icon Library. Icons can be searched and selected from the Lucide Icon Library. - Feature Development: Develop the feature using existing UI components like
Card
,Button
, and formFields
to ensure a consistent look and feel. For design patterns and component examples, you can reference the FlowBite Library. Note that it's not necessary to install FlowBite; it's merely for visual and functional reference.
For developers looking to enhance their understanding or streamline their workflow, the following resources may prove invaluable:
- Useful GPTs
- React + Electron: GPT React-Electron Guide
- Tailwind CSS: GPT Tailwind CSS Guide
- Icons
- Lucide Icons: Lucide Icon Library
- Tailwind UI Components
- Flowbite: Flowbite Tailwind UI
- Tailwind Cheat Sheet
- Tailwind Components: Tailwind CSS Cheatsheet