Search code examples
circlecielectron-builderwineelectron-packagerelectron-forge

How to re-use platform parameter when building an electron application using `electron-forge make --platform=win32`?


We are building an electron desktop application for macos, linux, and windows.
Here is our electron-forge config:

// forge.config.js
const os = require('os')

const package = require('./package.json')

function getExtraResource() {
  const p = os.platform()
  switch (p) {
    case 'darwin':
      return ['./static/bin/pasteld-mac']
    case 'linux':
      return ['./static/bin/pasteld-linux']
    case 'win32':
      return ['./static/bin/pasteld-win.exe']
    default:
      throw new Error(
        'forge.config.js error: your OS is not supported. Supported OS are: darwin, linux, win32',
      )
  }
}

function getIcon() {
  const p = os.platform()
  switch (p) {
    case 'darwin':
      return './static/icons/icon.icns'
    case 'linux':
      return './static/icons/icon.png'
    case 'win32':
      return './static/icons/icon.ico'
    default:
      throw new Error(
        'forge.config.js error: your OS is not supported. Supported OS are: darwin, linux, win32',
      )
  }
}

module.exports = {
  packagerConfig: {
    name: package.productName,
    executableName: package.name,
    icon: getIcon(),
    asar: true,
    extraResource: getExtraResource(),
    protocols: [
      {
        protocol: package.name,
        name: package.name,
        schemes: [package.protocolSchemes.native],
      },
    ],
  },
  makers: [
    {
      name: '@electron-forge/maker-squirrel',
      config: {
        exe: `${package.name}.exe`,
        setupIcon: './static/icons/icon.ico',
        loadingGif: './static/icons/icon.gif',
        iconUrl:
          'https://raw.githubusercontent.com/pastelnetwork/pastel-electron-wallet/master/static/icons/icon.ico',
        title: package.productName,
        setupExe: `${package.productName} Setup - v${package.version}.exe`,
        skipUpdateIcon: true,
      },
    },
    {
      name: '@electron-forge/maker-dmg',
      config: {
        icon: './static/icons/icon.icns',
        name: package.productName,
      },
    },
    {
      name: '@electron-forge/maker-deb',
      config: {
        options: {
          icon: './static/icons/icon.png',
        },
      },
    },
  ],
  plugins: [
    [
      '@electron-forge/plugin-webpack',
      {
        mainConfig: './webpack.main.config.js',
        renderer: {
          config: './webpack.renderer.config.js',
          entryPoints: [
            {
              html: './src/index.html',
              js: './src/renderer.tsx',
              name: 'main_window',
            },
          ],
        },
      },
    ],
  ],
}

As you can see in the above file, getExtraResource() detects the os type and pick the right executable file based on it. In other words, running run make on a proper platform is all we need to build the application.
However, we are now going to build the windows installer on linux wine image, more specifically using electronuserland/builder:wine-mono image. Everything is working as expected so far, except one thing - we still need to add a step to the switch clause in the getExtraResource() to pick the windows executable in the builder image instead of linux executable(note that the builder image is still a linux image!).
It will be something like this:

# forge.config.js
//...

function getExtraResource() {
  const p = os.platform()
  switch (p) {
    case 'darwin':
      return ['./static/bin/pasteld-mac']
    case 'linux':
      if (build_arg === 'win32') {
        return ['./static/bin/pasteld-win.exe']
      }
      return ['./static/bin/pasteld-linux']
    case 'win32':
      return ['./static/bin/pasteld-win.exe']
    default:
      throw new Error(
        'forge.config.js error: your OS is not supported. Supported OS are: darwin, linux, win32',
      )
  }
}

//...

How can I get the build_arg in the above file?
Build command is yarn make --platform=win32 in the wine builder image.
Thanks in advance!


Solution

  • We could resolve this by using process.argv.
    More specifically, we run this command to build windows installer in linux container:

    yarn make --platform=win32
    

    And the string win32 could be caught by process.argv[3] anywhere.
    See the detailed implementation here.
    Please advice if you have a better solution!