Development - xpf0000/FlyEnv GitHub Wiki
Development Guides
Thank you to everyone who wishes to contribute to this project! This guide outlines the project's file structure, architecture, and interface style to help contributors get started quickly.
Git Branches
The project has three branches, each corresponding to a different platform:
- master: macOS
- Win: Windows
- Linux: Linux
Please select the appropriate branch based on your development environment.
Setup Development Environment
- Fork the project
- Clone the repository locally
git clone <repository-url>
- Install Node.js (Version 20+ recommended)
- Install Python (Version 3.12+ recommended)
- Configure Visual Studio Build Tools
- Install Node.js and the "Desktop development with C++" workload.
- Under Individual Components, add:
- Windows SDK (version matching your target)
- Spectre-mitigated libraries (required for security hardening)
- Install node-gyp globally
npm install -g node-gyp
- Install project dependencies
npm install
- Launch development mode
npm run dev
Interface Style
The current front-end interface is built using Element Plus. While it may not be the most visually stunning, it provides a comprehensive set of components with a consistent style. We welcome contributions to improve the interface design!
Current Styling Approach
- Previously, many custom classes were used.
- Now using Tailwind CSS for styling.
Design Principles
-
Simplicity and Directness As a developer tool, all functionalities should be straightforward. Minimize the number of clicks required to perform actions.
-
Consistency While aesthetics can be subjective, maintaining a consistent interface is essential for a good user experience.
Project Architecture and File Structure
The application's workflow is illustrated below:
Main Process
The main process acts as a command relay station.
- Commands (e.g., start/stop) initiated from the rendering process (App interface) are forwarded to the forked asynchronous process for execution.
- Results are passed back to the main process, which then relays them to the rendering process.
Directory: /src/main
Key Technologies:
Forked Asynchronous Process
All commands are executed here. Being asynchronous, it prevents the main thread from blocking, ensuring the application remains responsive.
Directory: /src/fork
Key Technologies:
Module Structure
Services are split into separate module files located in /src/fork/module
.
A typical module file includes the following:
interface SoftInstalled {
version: string; // Service version
bin: string; // Executable file for the service
path: string; // Installation path of the service
}
class Module extends Base {
constructor() {
super();
this.type = 'apache';
}
/**
* Start the service
* @param version - The service version to start
*/
async _startServer(version: SoftInstalled) {
// Start services using Node.js's child_process.exec/spawn
}
/**
* Stop the service
* @param version - The service version to stop
*/
async _stopService(version: SoftInstalled) {
// Stop the service by identifying the process and sending a termination signal
}
/**
* Fetch all available online packages
*/
async fetchAllOnLineVersion() {
// Parse the official download page or GitHub release API
}
/**
* Download and install an online package
*/
async installSoft() {}
}
Rendering Process (App Interface)
Directory: /src/render
Key Technologies:
Module Structure
Modules are organized under /src/render/components
and are loaded automatically.
Defining a Module
- Add a module flag in
src/render/core/type.ts
:
export enum AppModuleEnum {
caddy = 'caddy',
nginx = 'nginx',
php = 'php',
mysql = 'mysql',
// ... other modules
}
- Create a module folder in
/src/render/components
and add aModule.ts
file with the following content:
import { defineAsyncComponent } from 'vue';
import type { AppModuleItem } from '@/core/type';
const module: AppModuleItem = {
typeFlag: 'redis',
label: 'Redis',
icon: import('@/svg/redis.svg?raw'),
index: defineAsyncComponent(() => import('./Index.vue')),
aside: defineAsyncComponent(() => import('./aside.vue')),
asideIndex: 11,
isService: true,
isTray: true,
};
export default module;
AppModuleItem Description
export type AppModuleItem = {
typeFlag: AllAppModule; // Module flag defined in AppModuleEnum
label?: string | LabelFn; // Module label displayed in Setup -> Menu Show/Hide & Tray Window
icon?: any; // Module icon displayed in Tray Window
aside: any; // Left aside module component
asideIndex: number; // Sort order in the left aside
index: any; // Module home page component
isService?: boolean; // Whether the module is a service (can be started/stopped)
isTray?: boolean; // Whether the module is shown in the tray window
};
Internationalization (i18n)
Directory: /src/lang
FlyEnv supports dynamic loading of language packs. Contributors can modify and test language packs locally. Once validated, they can be integrated into the project.