1. Migrations
  2. Integrate ToDesktop into an electron-webpack project

Migrations

Integrate ToDesktop into an electron-webpack project

This is a guide for those looking to integrate ToDesktop CLI into an existing electron-webpack project.

INFO

This guide will cover the minimum code changes needed and some noteworthy configuration options. It won't cover all configuration options or features. It also assumes you've already signed up and have created an app in the ToDesktop web app.

Learn the basics

Typically, replacing electron-builder with ToDesktop means mostly deleting code. However, first, have a skim through our generic Electron guide: How to integrate ToDesktop into your Electron application.

Welcome back, let's look at some electron-builder specifics.

First, I should say nothing has to change for development. Don't worry, you'll still have your live-reloading, etc. We'll mostly be changing what happens after electron-webpack compiles your app, i.e. replacing electron-builder.

Let's assume you have scripts something like this in your package.json:

        ...
"scripts": {
  "dev": "electron-webpack dev",
  "compile": "electron-webpack",
  "dist": "yarn compile && electron-builder",
  "dist:dir": "yarn dist --dir -c.compression=store -c.mac.identity=null"
},
...

      

The truth about electron-webpack and electron-builder

No matter what setup you use, the golden rule is that if you have a valid Electron app structure, i.e. a directory which is compatible with the official Electron CLI (electron path/to/app), then ToDesktop will take over from there just fine. Unfortunately, electron-webpack doesn't output a valid Electron app.

To see it for yourself, try running yarn compile and then electron dist in your project (run yarn add -g electron to install it if you don't have it already). It will fail.

If you were to read electron-webpack's Building guide, you might be lead to believe it does output a valid app. Plus, that electron-webpack is "agnostic about the build tool you decide to use for creating your distributable electron application". That's actually not the case.

electron-builder actually contains code which checks if the project uses electron-webpack. Then it does some things differently to get the electron-webpack output into an Electron app shape, before packing it into binaries. As this is done in electron-builder and not electron-webpack, it makes it more difficult to use electron-webpack with other tools.

Making a valid Electron app

So the first thing we'll do is transform the electron-webpack output (the dist directory) into an Electron app structure. We'll do this in the dist:dir script you already have. After we implement these changes, the yarn dist:dir command will output the dist as it does now, but it will also include a unpacked sub-directory containing a valid unpacked Electron app. Later, this is the directory that will be uploaded to ToDesktop.

This will mostly involve copying files around. I recommend using the cpx package for this so it will work for any developer on any OS, now or in future. I.e. as opposed to using a built-in OS command.

  1. Run yarn add --dev cpx to install the cpx package.
  2. Update your dist:dir script to look like this:
        yarn compile && cpx package.json dist/unpacked && cpx yarn.lock dist/unpacked && cpx 'dist/main/*' dist/unpacked && cpx 'dist/renderer/*' dist/unpacked && cpx 'node_modules/*' dist/unpacked/node_modules

      

This copies the contents of the dist/main and dist/renderer directories (among other files) to dist/unpacked. If you have a renderer-dll directory, you should modify this line copy the contents of dist/renderer-dll in the same way.

To ensure Electron will run the correct main entry file when your app is opened, add "main": "main.js" to the package.json at the root of your project. When you run yarn dist:dir, this package.json will be copied to dist/unpacked and the main property will correctly point to dist/unpacked/main.js.

Test it

Try running yarn dist:dir. You should see a dist/unpacked directory containing a package.json, main.js, index.html, and so on.

Now run electron dist/unpacked. Your app will open, running your main.js.

You don't need to copy your node_modules

If we didn't copy them, then opening your app with the Electron CLI likely wouldn't have worked. It would've failed when your code tried to require a dependency that's missing.

In reality, you won't be using the electron command, you'll be using the yarn dev command for development. ToDesktop requires that dist/unpacked is a valid Electron app but it actually ignores node_modules; they're installed on the ToDesktop build servers instead. Why? See How are dependencies and native modules handled?

This means that you can remove && cpx 'node_modules/*' dist/unpacked/node_modulesfrom the end of the dist:dir script. It takes time and it's not needed.

What about static files or images?

Skip this if you don't have a static directory in your project or if you don't use the __static global variable injected by electron-webpack.

Nothing is unchanged about __static when using ToDesktop. We just need to make sure the static directory gets put into the final app binaries. To do this, we use the extraResources config option in our todesktop.json;

        ...
"extraResources": [{
  "from": "./static",
  "to": "static"
}],
...

      

This instructs ToDesktop to copy the contents of the static directory into a static directory in the final app's resources directory. This is exactly where __static will point at.

WARNING

This is completely unrelated to ToDesktop but heads up, there are a few gotchas with the __static variable. If you have already released your app to production, you will likely have found workarounds. If you haven't, please confirm everything is loading correctly in development and production before releasing to any users.

Releasing

OK, now we're ready to deploy using ToDesktop. What we want is these two scripts in our package.json:

  • yarn dist: This will release your app. Specifically, it first will clean the dist/unpacked directory and then run yarn just to be safe. Then it will run yarn dist:dir to create dist/unpacked and finally todesktop build && todesktop release --latest --force. This last command uploads your app to our servers and kicks off Linux, Mac, and Windows builds. It'll then release new downloads and an auto-update.
  • yarn dist:build : This is just like the above, except it won't release new downloads or an auto-update. This is helpful for testing before rolling out a release. After you do your testing, you can optionally go to app.todesktop.com and click a button to release this build (it only takes a few seconds). The contents of the script is the same, except todesktop build is the final step.
        ...
"scripts": {
  "dev": "electron-webpack dev",
  "compile": "electron-webpack",
  "dist": "del-cli dist/unpacked && yarn && yarn dist:dir && todesktop build && todesktop release --latest --force",
  "dist:build": "del-cli dist/unpacked && yarn && yarn dist:dir && todesktop build",
  "dist:dir": "yarn compile && cpx package.json dist/unpacked && cpx yarn.lock dist/unpacked && cpx 'dist/main/*' dist/unpacked && cpx 'dist/renderer/*' dist/unpacked"
},
...

      

For quicker development builds you can append --code-sign=false to the todesktop build command to disable code-signing and notarization. The only downside is that you lose the option to release this build to production. You'll need to trigger a new one.

When releasing your app, the ideal process would be to run dist:build / todesktop build, then download and test the app, then run todesktop release / use our web UI to release that build.

What's del-cli?

Again, instead of using a built-in OS command to delete, I've used a cross-platform friendly dependency. Run yarn add --dev del-cli to install it.

Do I need to remove electron-builder?

Technically, yes, you can always keep electron-builder for testing packed applications locally but it is strongly discouraged. It will be difficult to make sure your electron-builder and ToDesktop config are aligned. You don't want any surprises when you go to production.

What if I have a preload script?

Assuming you've followed the electron-webpack instructions, then you won't need to change anything.

Other common questions

More features

This is just the tip of the iceberg as far as features go. Check out the @todesktop/cli documentation, the @todesktop/runtime documentation, and app.todesktop.com for more.

Other migration guides

If you need any help, don't hesitate to contact us.