2019-09-13 13:49:11 +02:00
|
|
|
import {resolveLibs} from "./RollupConfig.js"
|
|
|
|
|
import {nativeDepWorkaroundPlugin} from "./Builder.js"
|
|
|
|
|
import nodeResolve from "@rollup/plugin-node-resolve"
|
|
|
|
|
import Promise from "bluebird"
|
|
|
|
|
import fs from "fs"
|
|
|
|
|
import path from "path"
|
|
|
|
|
import {rollup} from "rollup"
|
|
|
|
|
import {terser} from "rollup-plugin-terser"
|
|
|
|
|
import pluginBabel from "@rollup/plugin-babel"
|
|
|
|
|
import commonjs from "@rollup/plugin-commonjs"
|
|
|
|
|
import electronBuilder from "electron-builder"
|
|
|
|
|
import generatePackgeJson from "./electron-package-json-template.js"
|
|
|
|
|
import {create as createEnv, preludeEnvPlugin} from "./env.js"
|
2018-09-24 11:56:41 +02:00
|
|
|
|
2019-09-13 13:49:11 +02:00
|
|
|
const {babel} = pluginBabel
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function buildDesktop({
|
|
|
|
|
dirname, // directory this was called from
|
|
|
|
|
version, // application version that gets built
|
|
|
|
|
targets, // which desktop targets to build and how to package them
|
|
|
|
|
updateUrl, // where the client should pull its updates from, if any
|
|
|
|
|
nameSuffix, // suffix used to distinguish test-, prod- or snapshot builds on the same machine
|
|
|
|
|
notarize, // for the MacOs notarization feature
|
|
|
|
|
outDir, // where copy the finished artifacts
|
|
|
|
|
unpacked // output desktop client without packing it into an installer
|
2021-01-29 13:56:41 +01:00
|
|
|
}) {
|
2019-09-13 13:49:11 +02:00
|
|
|
// The idea is that we
|
|
|
|
|
// - build desktop code into build/dist/desktop
|
|
|
|
|
// - package the whole dist directory into the app
|
|
|
|
|
// - move installers out of the dist into build/desktop-whatever
|
|
|
|
|
// - cleanup dist directory
|
|
|
|
|
// It's messy
|
2018-10-02 16:19:03 +02:00
|
|
|
const targetString = Object.keys(targets)
|
|
|
|
|
.filter(k => typeof targets[k] !== "undefined")
|
|
|
|
|
.join(" ")
|
|
|
|
|
console.log("Building desktop client for v" + version + " (" + targetString + ")...")
|
2019-09-13 13:49:11 +02:00
|
|
|
const updateSubDir = "desktop" + nameSuffix
|
|
|
|
|
const distDir = path.join(dirname, "build", "dist")
|
|
|
|
|
outDir = path.join(outDir || path.join(distDir, ".."), updateSubDir)
|
|
|
|
|
await fs.promises.mkdir(outDir, {recursive: true})
|
|
|
|
|
|
2019-11-07 16:08:49 +01:00
|
|
|
|
2019-09-13 13:49:11 +02:00
|
|
|
// We need to get the right build of native dependencies. There's a tool called node-gyp which can build for different architectures
|
|
|
|
|
// and downloads everything it needs. Usually dependencies build themselves in post-install script.
|
|
|
|
|
// Currently we have keytar which avoids building itself if possible and only build
|
2018-12-13 17:59:47 +01:00
|
|
|
console.log("Updating electron-builder config...")
|
2019-09-13 13:49:11 +02:00
|
|
|
const content = generatePackgeJson({
|
|
|
|
|
nameSuffix,
|
|
|
|
|
version,
|
|
|
|
|
updateUrl,
|
2020-04-07 10:32:03 +02:00
|
|
|
iconPath: path.join(dirname, "/resources/desktop-icons/logo-solo-red.png"),
|
2019-09-13 13:49:11 +02:00
|
|
|
notarize,
|
|
|
|
|
unpacked,
|
2021-01-28 14:03:50 +01:00
|
|
|
sign: nameSuffix !== '-snapshot' && updateUrl !== "",
|
2020-04-07 10:32:03 +02:00
|
|
|
})
|
2019-09-13 13:49:11 +02:00
|
|
|
console.log("updateUrl is", updateUrl)
|
|
|
|
|
await fs.promises.writeFile("./build/dist/package.json", JSON.stringify(content), 'utf-8')
|
|
|
|
|
// prepare files
|
|
|
|
|
try {
|
|
|
|
|
await fs.promises.rmdir(path.join(distDir, "..", updateSubDir), {recursive: true})
|
|
|
|
|
} catch (e) {
|
|
|
|
|
if (e.code !== 'ENOENT') {
|
|
|
|
|
throw e
|
2018-12-13 17:59:47 +01:00
|
|
|
}
|
|
|
|
|
}
|
2019-09-13 13:49:11 +02:00
|
|
|
console.log("Bundling desktop client")
|
2021-01-29 13:56:41 +01:00
|
|
|
await rollupDesktop(dirname, path.join(distDir, "desktop"), version)
|
2018-12-13 17:59:47 +01:00
|
|
|
|
2019-09-13 13:49:11 +02:00
|
|
|
console.log("Starting installer build...")
|
|
|
|
|
// package for linux, win, mac
|
|
|
|
|
await electronBuilder.build({
|
|
|
|
|
_: ['build'],
|
|
|
|
|
win: targets.win,
|
|
|
|
|
mac: targets.mac,
|
|
|
|
|
linux: targets.linux,
|
|
|
|
|
p: 'always',
|
|
|
|
|
project: distDir
|
|
|
|
|
})
|
|
|
|
|
console.log("Move output to ", outDir)
|
|
|
|
|
await fs.promises.mkdir(outDir, {recursive: true})
|
|
|
|
|
await Promise.all(
|
|
|
|
|
fs.readdirSync(path.join(distDir, '/installers'))
|
2021-01-22 14:55:40 +01:00
|
|
|
// TODO: find out why it was needed. Check if unpacked is done correctly.
|
|
|
|
|
// .filter((file => file.startsWith(content.name) || file.endsWith('.yml')))
|
|
|
|
|
.map(file => fs.promises.rename(
|
|
|
|
|
path.join(distDir, '/installers/', file),
|
|
|
|
|
path.join(outDir, file)
|
|
|
|
|
)
|
|
|
|
|
)
|
2019-09-13 13:49:11 +02:00
|
|
|
)
|
|
|
|
|
await Promise.all([
|
|
|
|
|
fs.promises.rmdir(path.join(distDir, '/installers/'), {recursive: true}),
|
|
|
|
|
fs.promises.rmdir(path.join(distDir, '/node_modules/'), {recursive: true}),
|
|
|
|
|
fs.promises.unlink(path.join(distDir, '/package.json')),
|
|
|
|
|
fs.promises.unlink(path.join(distDir, '/package-lock.json'),),
|
|
|
|
|
])
|
|
|
|
|
}
|
2018-12-13 17:59:47 +01:00
|
|
|
|
2021-01-29 13:56:41 +01:00
|
|
|
async function rollupDesktop(dirname, outDir, version) {
|
2019-09-13 13:49:11 +02:00
|
|
|
function babelPreset() {
|
|
|
|
|
return babel({
|
|
|
|
|
plugins: [
|
|
|
|
|
// Using Flow plugin and not preset to run before class-properties and avoid generating strange property code
|
|
|
|
|
"@babel/plugin-transform-flow-strip-types",
|
|
|
|
|
"@babel/plugin-proposal-class-properties",
|
|
|
|
|
"@babel/plugin-syntax-dynamic-import",
|
|
|
|
|
],
|
|
|
|
|
babelHelpers: "bundled",
|
|
|
|
|
})
|
2018-12-13 17:59:47 +01:00
|
|
|
}
|
|
|
|
|
|
2019-09-13 13:49:11 +02:00
|
|
|
const mainBundle = await rollup({
|
|
|
|
|
input: path.join(dirname, "src/desktop/DesktopMain.js"),
|
|
|
|
|
plugins: [
|
|
|
|
|
babelPreset(),
|
|
|
|
|
resolveLibs(),
|
|
|
|
|
nativeDepWorkaroundPlugin(),
|
|
|
|
|
resolveKeytarPlugin(),
|
|
|
|
|
nodeResolve({preferBuiltins: true}),
|
|
|
|
|
commonjs({exclude: "src/**"}),
|
2021-01-29 13:56:41 +01:00
|
|
|
terser(),
|
2019-09-13 13:49:11 +02:00
|
|
|
preludeEnvPlugin(createEnv(null, version, "Desktop", true))
|
|
|
|
|
]
|
|
|
|
|
})
|
|
|
|
|
await mainBundle.write({sourcemap: true, format: "commonjs", dir: outDir})
|
2018-12-13 17:59:47 +01:00
|
|
|
|
2019-09-13 13:49:11 +02:00
|
|
|
const preloadBundle = await rollup({
|
|
|
|
|
input: path.join(dirname, "src/desktop/preload.js"),
|
|
|
|
|
plugins: [
|
|
|
|
|
babelPreset(),
|
|
|
|
|
{
|
|
|
|
|
name: "dynamicRequire",
|
|
|
|
|
banner() {
|
|
|
|
|
// see preload.js for explanation
|
|
|
|
|
return "const dynamicRequire = require"
|
|
|
|
|
},
|
|
|
|
|
}
|
2018-12-13 17:59:47 +01:00
|
|
|
],
|
|
|
|
|
})
|
2019-09-13 13:49:11 +02:00
|
|
|
await preloadBundle.write({sourcemap: true, format: "commonjs", dir: outDir})
|
2018-12-13 17:59:47 +01:00
|
|
|
}
|
|
|
|
|
|
2019-09-13 13:49:11 +02:00
|
|
|
function resolveKeytarPlugin() {
|
|
|
|
|
return {
|
|
|
|
|
name: "resolve-keytar",
|
|
|
|
|
resolveId(id) {
|
|
|
|
|
// These are packaged as-is in node_modules
|
|
|
|
|
if (id === "keytar") {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|