npm workspaces support for electron-forge
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// based on https://github.com/electron-userland/electron-forge/issues/2306#issuecomment-1034882039 | |
'use strict'; | |
/** | |
* @typedef {{ | |
* new (options: { path: string }): { | |
* loadActual(): Promise<Node> | |
* } | |
* }} Arborist | |
*/ | |
const fs = require('fs/promises'); | |
const path = require('path'); | |
/** @type {Arborist} */ | |
// @ts-ignore missing types for @npmcli/arborist | |
const arborist = require('@npmcli/arborist'); | |
const { findRoot } = require('@manypkg/find-root'); | |
/** | |
* @typedef {{ | |
* workspace: boolean; | |
* type: 'prod' | 'dev' | 'peer' | 'optional' | |
* to: Node; | |
* }} Edge | |
*/ | |
/** | |
* @typedef {{ | |
* isLink: boolean; | |
* location: string; | |
* realpath: string; | |
* target: Node; | |
* edgesOut: Map<string, Edge>; | |
* }} Node | |
*/ | |
/** @type {(node: Node) => Node} */ | |
const resolveLink = (node) => (node.isLink ? resolveLink(node.target) : node); | |
/** @type {(node: Node, realPath: string) => Node | undefined} */ | |
const getWorkspaceByPath = (node, realPath) => | |
[...node.edgesOut.values()] | |
.filter((depEdge) => depEdge.workspace) | |
.map((depEdge) => resolveLink(depEdge.to)) | |
.find((depNode) => depNode.realpath === realPath); | |
/** @type {(node: Node) => Node[]} */ | |
const collectProdDeps = (node) => | |
[...node.edgesOut.values()] | |
.filter((depEdge) => depEdge.type === 'prod') | |
.map((depEdge) => resolveLink(depEdge.to)) | |
.flatMap((depNode) => [depNode, ...collectProdDeps(depNode)]); | |
/** @type {(source: string, destination: string) => Promise<void>} */ | |
const bundle = async (source, destination) => { | |
const root = await findRoot(source); | |
const rootNode = await new arborist({ path: root.rootDir }).loadActual(); | |
const sourceNode = getWorkspaceByPath(rootNode, source); | |
if (!sourceNode) { | |
throw new Error("couldn't find source node"); | |
} | |
const prodDeps = collectProdDeps(sourceNode); | |
for (const dep of prodDeps) { | |
const dest = path.join(destination, dep.location); | |
await fs.cp(dep.realpath, dest, { | |
recursive: true, | |
errorOnExist: false, | |
}); | |
} | |
}; | |
module.exports = { bundle }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
const { bundle } = require('./bundler'); | |
module.exports = { | |
packagerConfig: { | |
prune: false, // required for the workaround below to work | |
}, | |
hooks: { | |
packageAfterCopy: async ( | |
/** @type {any} */ forgeConfig, | |
/** @type {string} */ buildPath, | |
/** @type {string} */ electronVersion, | |
/** @type {string} */ platform, | |
/** @type {string} */ arch, | |
) => { | |
// this is a workaround until we find a proper solution | |
// for running electron-forge in a mono repository | |
await bundle(__dirname, buildPath); | |
}, | |
}, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you @robin-hartmann !
I needed to add
recursive: true
tofs.cp
.Also, in order to copy modules from workspaces I wrote: