diff --git a/package-lock.json b/package-lock.json index 592c9500..cece9dc1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11835,6 +11835,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, "license": "ISC", "engines": { "node": ">=16" @@ -21007,6 +21008,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, "dependencies": { "isexe": "^3.1.1" }, @@ -21552,8 +21554,7 @@ "lodash.get": "^4.4.2", "set-value": "^4.1.0", "source-map-support": "0.5.19", - "supports-color": "9.2.1", - "which": "^4.0.0" + "supports-color": "9.2.1" }, "devDependencies": { "@babel/core": "^7.12.10", diff --git a/packages/build/build/commands.js b/packages/build/build/commands.js index f026487b..e6de9d5f 100644 --- a/packages/build/build/commands.js +++ b/packages/build/build/commands.js @@ -224,7 +224,7 @@ exports.commands = (program, flecks) => { } const webpackConfig = await flecks.resolveBuildConfig('fleckspack.config.js'); const cmd = [ - await binaryPath('webpack'), + await binaryPath('webpack', '@flecks/build'), ...((watch || hot) ? ['watch'] : []), '--config', webpackConfig, '--mode', (production && !hot) ? 'production' : 'development', @@ -310,7 +310,7 @@ exports.commands = (program, flecks) => { .map((pkg) => join(process.cwd(), pkg)) .map(async (cwd) => { const cmd = [ - await binaryPath('eslint'), + await binaryPath('eslint', '@flecks/build'), '--config', await flecks.resolveBuildConfig('eslint.config.js'), '.', ]; diff --git a/packages/core/package.json b/packages/core/package.json index 9554d5cc..94dcf075 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -30,8 +30,7 @@ "lodash.get": "^4.4.2", "set-value": "^4.1.0", "source-map-support": "0.5.19", - "supports-color": "9.2.1", - "which": "^4.0.0" + "supports-color": "9.2.1" }, "devDependencies": { "@babel/core": "^7.12.10", diff --git a/packages/core/src/server/process.js b/packages/core/src/server/process.js index ed496b2e..acf80354 100644 --- a/packages/core/src/server/process.js +++ b/packages/core/src/server/process.js @@ -1,21 +1,37 @@ -const {exec, fork, spawn} = require('child_process'); +const {fork, spawn} = require('child_process'); +const { + access, + constants: {X_OK}, + realpath, +} = require('fs/promises'); +const {dirname, join, sep} = require('path'); const D = require('../../build/debug'); const debug = D('@flecks/core/server'); const debugSilly = debug.extend('silly'); -exports.binaryPath = (binary) => ( - new Promise((resolve, reject) => { - exec(`npx which ${binary}`, (error, stdout) => { - if (error) { - reject(error); - return; - } - resolve(stdout.trim()); - }); - }) -); +const { + FLECKS_CORE_ROOT = process.cwd(), +} = process.env; + +exports.binaryPath = async (binary, root = FLECKS_CORE_ROOT) => { + // eslint-disable-next-line no-eval + const resolved = dirname(await realpath(eval('require').resolve(join(root, 'package.json')))); + const parts = resolved.split(sep); + while (parts.length > 0) { + const path = parts.concat(join('node_modules', '.bin', binary)).join(sep); + try { + // eslint-disable-next-line no-await-in-loop + await access(path, X_OK); + return path; + } + catch (error) { + parts.pop(); + } + } + throw new Error(`Binary '${binary}' not found! (root: ${root})`); +}; exports.processCode = (child) => new Promise((resolve, reject) => { child.on('error', reject); diff --git a/packages/electron/build/flecks.bootstrap.js b/packages/electron/build/flecks.bootstrap.js index 3490755d..5801571f 100644 --- a/packages/electron/build/flecks.bootstrap.js +++ b/packages/electron/build/flecks.bootstrap.js @@ -1,4 +1,12 @@ -const {join} = require('path'); +const { + basename, + dirname, + extname, + join, + relative, +} = require('path'); + +const {binaryPath} = require('@flecks/core/src/server'); exports.hooks = { '@flecks/core.config': () => ({ @@ -25,16 +33,24 @@ exports.hooks = { */ url: undefined, }), - '@flecks/build.config.alter': (configs) => { - const {server: config} = configs; - if (config) { - const plugin = config.plugins.find(({pluginName}) => pluginName === 'StartServerPlugin'); - // Extremely hackish, c'est la vie. + '@flecks/build.config.alter': async (configs) => { + const electronPath = await binaryPath('electron', '@flecks/electron'); + const {server} = configs; + if (server) { + const plugin = server.plugins.find(({pluginName}) => pluginName === 'StartServerPlugin'); if (plugin) { + const relativePath = relative(server.output.path, electronPath); const {exec} = plugin.options; plugin.options.exec = (compilation) => { - plugin.options.args = [join(config.output.path, compilation.getPath(exec))]; - return join('..', '..', 'node_modules', '.bin', 'electron'); + const assetPath = compilation.getPath(exec); + const trimmed = join(dirname(assetPath), basename(assetPath, extname(assetPath))); + plugin.options.args = [ + join( + server.output.path, + `${trimmed}.mjs`, + ), + ]; + return relativePath; }; } } diff --git a/packages/server/test/server/build/build.js b/packages/server/test/server/build/build.js index e74c8ae1..8785af46 100644 --- a/packages/server/test/server/build/build.js +++ b/packages/server/test/server/build/build.js @@ -30,7 +30,7 @@ export async function createApplication() { export async function buildChild(path, {args = [], opts = {}} = {}) { return spawnWith( - [await binaryPath('flecks'), 'build', ...args], + [await binaryPath('flecks', '@flecks/build'), 'build', ...args], { ...opts, env: { diff --git a/packages/web/build/flecks.bootstrap.js b/packages/web/build/flecks.bootstrap.js index 59a8e1ed..698ea3ff 100644 --- a/packages/web/build/flecks.bootstrap.js +++ b/packages/web/build/flecks.bootstrap.js @@ -3,7 +3,7 @@ const {join} = require('path'); const Build = require('@flecks/build/build/build'); const {regexFromExtensions} = require('@flecks/build/src/server'); -const {spawnWith} = require('@flecks/core/src/server'); +const {binaryPath, spawnWith} = require('@flecks/core/src/server'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const { @@ -161,14 +161,12 @@ exports.hooks = { return; } // Bail if the build isn't watching. - if (!process.argv.find((arg) => '--watch' === arg)) { + if (!process.argv.find((arg) => 'watch' === arg)) { return; } // Otherwise, spawn `webpack-dev-server` (WDS). const cmd = [ - // `npx` doesn't propagate signals! - // 'npx', 'webpack', - join(FLECKS_CORE_ROOT, 'node_modules', '.bin', 'webpack'), + await binaryPath('webpack', '@flecks/build'), 'serve', '--mode', 'development', '--hot',