How do I use a relative path without specifying a specific drive in my electron app? I need to use something like SRC="/FILE.HTML"
so my app will work on any drive installed not just a specific location. I know ./
and ../
go to previous parent folders but how can I go a few more directories back? I've seen things like %appdir%/MAIN DIR/SUB DIR/FILE.HTML
, however I'm not sure how that works? Maybe I can setup some kind of variable to use in my path like that? So far I've only been able to use direct paths to go to files in previous folder which constricts my software to a specific drive.
Example: MAIN DIR
/SUB DIR
/FILE.HTML
EDIT: My electron app isnt displaying my Main.html. I think it has to do with my paths but im not sure?
Using absolute paths will cause you issues, especially during / after build process. Your Electron application would be built referencing files in the wrong directories. Relevant file reference is the way to go here.
IMPORTANT: I am seeing a lot of inconsistent directory naming and file references in your directory structure. EG:
Main.html
is in yourJAVASCRIPT
directory.Main.js
(not your application entry point) is not shown in your directory structure. Same for yourIndex.css
file. As a result, answering this question accurately is difficult due to the many "norms" usually found in project structure and naming conventions. Comment at the bottom of this answer for more information / help.
Within your package.json
file, the "main": "..."
line is the entry point to your application. As this is
relative to your project root and your Main.js
file is at your project root, your entry point will be "Main.js"
PS:
"electron"
doesn't need to be a dependency, only a devDependency.
package.json
(project root)
{
"name": "electron.menu",
"version": "00.00.01",
"description": "Electron Menu Portable Start Menu",
"main": "Main.js"
"scripts": {
"start": "electron .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "Armored Security Group",
"license": "MIT",
"devDependencies": {
"electron": "^19.0.6"
}
}
Within your Main.js
file, the path to your index.html
file, or in your case, your Main.html
file, is again,
relative (this time to the Main.js
file as this is the file requiring it).
Using Node's path.join([...path]);
method (as you
have) will place you in good stead.
Note the use of
win.loadFile(...)
instead ofwin.loadURL(...)
Main.js
(main process)
const { app, BrowserWindow } = require('electron');
const url = require('url');
const path = require('path');
let win
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 600
});
win.loadFile(path.join(__dirname, 'ROOT.ASSETS/CODE.FILES/JAVASCRIPT/Main.html'));
return win;
}
app.on('ready', () => {
win = createWindow();
});
Lastly, within your Main.html
file, all paths will be relevant to the file itself. IE: Main.html
.
That said, I don't see Main.js
within your ROOT.ASSETS/CODE.FILES/JAVASCRIPT
directory.
Additionally, I don't see Index.css
within your ROOT.ASSETS/CODE.FILES/
STYLESHEET /INDEX.STYLE
directory.
PS: Place your Javascript file(s) after the closing tag of your
</body>
element. That way, you do not need todefer
and your script(s) will always have a full DOM to work with (unless you need to make an update to your DOM before the page is rendered).
ROOT.ASSETS/CODE.FILES/JAVASCRIPT/Main.html
(render process)
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="UTF-8">
<title>Electron Menu</title>
<link rel="stylesheet" type="text/css" href="../STYLESHEET/INDEX.STYLE/Index.css" />
</head>
<body>
...
</body>
<script src="/Main.js"></script>
</html>
PS: One final note, there is no real need to have directory names or file name use upper case unless you are using camelCase.
Path reference is different between file systems and internet URL's
For our file systems example we will use:
D:/
└── path
└── to
└── my
├── first
| └── file.txt
└── second
└── file.txt
Absolute paths are paths that refer to the whole file path. They are absolute.
D:/path/to/my/first/file.txt
D:/path/to/my/second/file.txt
Let's say are are somewhere in the D:/
drive. You could be anywhere.
To get to your "first" file you would use the full path to the first text file.
D:/path/to/my/first/file.txt
Alternatively, you could use
/path/to/my/first/file.txt
This will take you to the same location if you are already in the D:/
drive. If you are in another drive, it will take you to the absolute path in that drive instead.
To get to your "second" file you would use the full path to the second text file.
D:/path/to/my/second/file.txt
or
/path/to/my/second/file.txt
Relative paths are paths that refer to a point in the file system from another point in the file system.
Let's say we open a console starting at the D:/
directory. IE: The root of the D:/
drive.
D:/
To get to your "first" file you would use the path to the first text file. The reference will always start from the current directory. In this case, it happens to be the root of the D:/
drive.
path/to/my/first/text.file
From here, to get to your "second" file, you will need to move up one directory level ../
, which will take you to path/to/my
. From here you then need to move down into the second
directory to the second text file.
../second/file.txt
If you want to go to the root of the drive that you are currently in (without worrying about what drive you are in) use /
.
/
This will take you back to:
D:/
Linux also has ./
which is used to reference a relative path.
Similar to file systems, but used when referencing URL addresses.
For our Internet URL's example we will use:
www.example.com
└── path
└── to
└── my
├── cool
| └── page.html
└── other-cool
└── page.html
https://www.example.com/path/to/my/cool/page.html
Let's navigate to another page without using the absolute URL to the other page.
../other-cool/page.html
As we are already in the cool
path, this takes us up one level to my
and back down through other-cool
to page.html
.
IE:
https://www.example.com/path/to/my/other-cool/page.html
To move up two levels from here, would would use
../../
Which would take us to
https://www.example.com/path/to
After we finish coding our Electron application, we "build" it. Our newly "built" code must be placed in a different directory to that of our "source" code else we would overwrite our source code.
Thus we will use the dist
and src
names as folder names.
dist
holds our distributable code. EG myApp.exe
src
holds our source code.build
is often used as an intermediary to hold specific OS architecture output during the build process.
Project Root
├── build
├── dist
├── node_modules
├── src
├── tests
├── .gitignore
├── package.json
└── package-lock.json
As a personal preference, I then split my src
folder into directories / files like below.
src
├── main-process
| ├── dialogs
| ├── localization
| ├── menus
| | ├── main-menu.js
| | └── tray-menu.js
| ├── preferences
| ├── windows
| | └── main-window.js
| ├── main.js
| └── preload.js
├── render-process
| ├── css
| | └── index.css
| ├── html
| | └── index.html
| ├── images
| └── js
| └── index.js
└── config.json
Therefore, a basic package.json
file would refer to your main entry file main.js
like this.
package.json
{
"name": "myApp",
"productName": "My cool application",
"version": "1.0.0",
"main": "src/main-process/main.js"
"scripts": {
"watch": "",
"start": "electron .",
"lint": "",
"unit-test": ",
"clean": "",
"bundle-win": "electron-packager ./ server-x --overwrite --out=build/bundles --platform=win32 --arch=all --prune=true --asar --icon='./src/render-process/images/icons/icon.png'",
"dist-win": "electron-builder --windows ",
"release": ""
},
"devDependencies": {
"electron": "^19.0.0",
"electron-builder": "^23.0.0",
"electron-packager": "^15.0.0"
}
}
Your main.js
file would look like this.
main.js
(main process)
const { app, BrowserWindow } = require('electron');
const url = require('url');
const path = require('path');
let win
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 600
});
win.loadFile(path.join(__dirname, '../render-process/html/index.html'));
return win;
}
app.on('ready', () => {
win = createWindow();
});
And finally, your index.html
file would look like this.
index.html
(render process)
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="UTF-8">
<title>Electron Menu</title>
<link rel="stylesheet" type="text/css" href="../css/index.css" />
</head>
<body>
...
</body>
<script src="../js/index.js"></script>
</html>