Reputation: 4402
I have just started learning Electron from the official Quick Start guide. At the end of the guide, they've recommended to use Electron Forge as the tool to create the distributable package. Another tool for the same purpose is Electron Builder.
I've used the latter before and out of curiosity I created the quick start app build with both the tools. To my surprise, there is a huge difference between the dmg builds that were created for the same app on MacOS:
I understand the Electron builds are fairly large in size due to the shipment of Chromium and Node along with the package but this significant difference (~134.2 MB) between the builds of a quick start app is quite not clear to me.
package.json
:
{
"name": "my-electron-app",
"version": "1.0.0",
"description": "Hello World",
"main": "main.js",
"scripts": {
"test": "test",
"start": "electron-forge start",
"package": "electron-forge package",
"make": "electron-forge make"
},
"license": "MIT",
"devDependencies": {
"@electron-forge/cli": "^6.0.0-beta.57",
"@electron-forge/maker-deb": "^6.0.0-beta.57",
"@electron-forge/maker-rpm": "^6.0.0-beta.57",
"@electron-forge/maker-squirrel": "^6.0.0-beta.57",
"@electron-forge/maker-zip": "^6.0.0-beta.57",
"electron": "^13.1.6",
"electron-builder": "^22.11.7",
"electron-log": "^4.3.5",
"electron-reloader": "^1.2.1"
},
"dependencies": {
"electron-squirrel-startup": "^1.0.0"
},
"config": {
"forge": {
"packagerConfig": {},
"makers": [
{
"name": "@electron-forge/maker-squirrel",
"config": {
"name": "my_electron_app"
}
},
{
"name": "@electron-forge/maker-zip",
"platforms": [
"darwin"
]
},
{
"name": "@electron-forge/maker-deb",
"config": {}
},
{
"name": "@electron-forge/maker-rpm",
"config": {}
}
]
}
}
}
I need help with the following questions:
npm prune
, deleting node_modules
and then creation of build as it had no effect)?Upvotes: 4
Views: 5077
Reputation: 1444
I had the same problem today, a simple app became a 1GB package.
Both electron-forge and electron-builder bundle all files inside your project directory by default. This is particularly much if some of your build tools generate temporary files in your project directories (e.g. caches). The difference you see is likely due to different default exclude rules.
Here's what you can do to get it smaller for both electron-forge and electron-builder:
In both cases, you can inspect the generated .asar file (under /resources
in your published, unpackaged directory) like this:
npx asar extract insert/path/here/resources/app.asar ./asar-extracted
You can then have a look at the individual files.
For example, you can run du -h ./asar-extracted
(under Linux/Unix) to find out what's taking so much space. For a better/graphical experience, I can recommend qdirstat (Linux) or windirstat (Windows). Or just use your file explorer.
You will probably see two things: a. node_modules is quite big. b. all the other files from your project directory are included
Both tools will automatically remove all dependencies that are not in the dependencies
section of package.json
(or depend on them). This means that you can put any dependency that isn't required in the electron app itself into devDependencies
.
If you are using a bundler like e.g. webpack, vite or parcel, then it's likely going to bundle all dependencies required from your HTML into the dist
directory, so that you won't need them in node_modules
in the published application. You can put all of those dependencies into devDependencies
. For example, react
is probably just required for the bundle, so you can put it into devDependencies
. Only the dependencies needed in your main process code need to stay. For my use case, I was able to move almost all the dependencies.
You can also decide to bundle your main process code as well, removing the need for any non-dev dependency.
To remove the other files that are in your project folder and thus included, you need to adjust the configuration. Let's assume that the (bundled/built) code that you want to bundle lies in a folder called dist-electron
for the following.
For electron-forge, this is done via regexes. For example, you can put something like this in your forge.config.js
:
module.exports = {
packagerConfig: {
ignore: [
// exclude everything but package.json, node_modules and dist-electron
/(?!package\.json|node_modules|dist-electron)/,
],
// ...
},
// ...
};
The docs are a bit hidden, you can't find them when searching in the forge docs, since they come from a different package. You can find them here (referenced here in the forge docs).
Once you've found the right docs, you'll see this note in bold:
Please note that glob patterns will not work
(Probably because that's the first thing that everyone tries.)
For electron-builder, you could e.g. put this into your package.json:
"build": {
"files": {
"filter": [
"dist-electron",
]
}
}
This has pretty much the same effect as the electron-forge configuration above. The required files from node_modules
as well as package.json
are included by default (docs).
You can also use glob patterns like *.bin
or !exclude-this
(docs).
Tbh after testing both for the first time today, I would not recommend electron-forge right now. The built-in scaffolding may be nice, but the docs are really, really limited. The docs for electron-builder are way better, and they also list quite a few third-party templates here to get started. The fact that the Electron docs frame Forge as the "official" solution is IMO not ideal when the project seems much less mature than electron-builder.
Upvotes: 2