"Eello World example": Vite, React, Typescript and Eel
Table of Contents
Eello World example Vite React Typescript with Eel. This example is a newer version of example 07 - CreateReactApp by @KyleKing. This particular project was bootstrapped with npm create vite@latest ViteReactTS --template react-ts (Typescript enabled) and Python 3.11.
- Multiple instances To enable multiple instances of this application in production (i.e. the user opens the application multiple times), a new free socket port is searched for on app startup and injected in to
./dist_vite/index.htmland./dist_vite/assets/index.*.jsbefore eel.init(). - Splashscreen A default splash-screen is provided so the user had direct feedback when the .exe file opened
- Configure: In the app's directory, run
npm installandpip install virtualenv - Virtual envirioment Create a new virtual envirioment using
python -m venv env. Open a new powershell window in the project directory and runSet-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserto enable running venv activate script. Then activate the virtual envirioment with venv using.\env\Scripts\activate.ps1. Now using this virtual env runpip install -r requirements.txtSee the footnote about Bottle.py! - Demo: Build static files with
npm run buildthen run the application withpython main.pyfrom the venv powershell window. A Chrome-app window should open running the built code fromdist_vite/ - Distribute: (Run
npm run buildfirst) Build a binary distribution with PyInstaller usingpython -m eel main.py dist_vite --onedir --splash splashfile.png --path env/lib/site-packages --noconsolefrom the venv powershell window (See more detailed PyInstaller instructions at bottom of the main README). The .exe will be generated in.\dist\main\main.exe. Try to open two instances of the application, you will find that it just works :) - Develop: Open two prompts. In one, run
python main.py trueand the other,npm run dev. A browser window should open in your default web browser at: http://localhost:5173/. As you make changes to the JavaScript insrc/the browser will reload. Any changes tomain.pywill require a restart to take effect. You may need to refresh the browser window if it gets out of sync with eel.
Note # Bottle has a issue with stdout when using pyinstaller --noconsole. The latest developent version of bottle 0.13-dev (not available on pypi) has a fix for this issue. In env/site-packages replace Bottle.py with bottle=0.13-dev: https://github.com/bottlepy/bottle/blob/master/bottle.py
Use
window.eel.expose(func, 'func')to circumventnpm run buildcode mangling
npm run build will rename variables and functions to minimize file size renaming eel.expose(funcName) to something like D.expose(J). The renaming breaks Eel's static JS-code analyzer, which uses a regular expression to look for eel.expose(*). To fix this issue, in your JS code, convert all eel.expose(funcName) to window.eel(funcName, 'funcName'). This workaround guarantees that 'funcName' will be available to call from Python.
Critical files for this demo
-
web_src/App.tsx: Modified to demonstrate exposing a function from JavaScript and how to use callbacks from Python to update React GUI -
main.py: Basiceelfile- If run without arguments, the
eelscript will loadindex.htmlfrom the dist_vite/ directory (which is ideal for building with PyInstaller/distribution) - If any 2nd argument (i.e.
true) is provided, the app enables a "development" mode and attempts to connect to the React server on port 5173
- If run without arguments, the
-
web_src/index.html: Added location ofeel.jsfile based on options set in main.py<!-- Load eel.js from the port specified in the eel.start options --> <script type="text/javascript" src="http://localhost:5169/eel.js"></script>
