Skip to content

Commit

Permalink
feat(generic): remove electron-compile, make forge less opinionated a…
Browse files Browse the repository at this point in the history
…nd quite vanilla

BREAKING CHANGE
  • Loading branch information
MarshallOfSound committed Mar 14, 2018
1 parent f2094ca commit d59695e
Show file tree
Hide file tree
Showing 28 changed files with 188 additions and 332 deletions.
7 changes: 2 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ npm start

With these goals in mind, under the hood this project uses, among others:

* [`electron-compile`](https://github.com/electron/electron-compile): a tool
that lets you use modern and futuristic languages inside Electron without
worrying about transpiling or build tooling.
* [`electron-rebuild`](https://github.com/electron/electron-rebuild):
Automatically recompiles native Node.js modules against the correct
Electron version.
Expand Down Expand Up @@ -197,15 +194,15 @@ You can set `electronPackagerConfig` with any of the options from
* `arch` (use the `--arch` Forge command line argument instead, so it's available to all of Forge)
* `asar.unpack` (use `asar.unpackDir` instead)
* `dir` (use the `cwd` Forge command line argument instead, so it's available to all of Forge)
* `electronVersion` (uses the exact version specified for `electron-prebuilt-compile` in your `devDependencies`)
* `electronVersion` (uses the exact version specified for `electron` in your `devDependencies`)
* `out`
* `platform` (use the `--platform` Forge command line argument instead, so it's available to all of Forge)
* `quiet`

You can set `electronRebuildConfig` with any of the options from
[Electron Rebuild](https://github.com/electron/electron-rebuild#how-can-i-integrate-this-into-grunt--gulp--whatever), except:

* `electronVersion`/`--version` (uses the exact version specified for `electron-prebuilt-compile` in your `devDependencies`)
* `electronVersion`/`--version` (uses the exact version specified for `electron` in your `devDependencies`)
* `arch`/`--arch` (use the `--arch` Forge command line argument instead, so it's available to all of Forge)
* `buildPath`/`--module-dir` (uses your project's `node_modules`)

Expand Down
1 change: 0 additions & 1 deletion SUPPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ running `electron-forge`. This will print debug information from the specified m
value of the environment variable is a comma-separated list of modules which support this logging
feature. Known modules include:

* `electron-compile:*`
* `electron-download`
* `electron-forge:*` (always use this one before filing an issue)
* `electron-installer-debian`
Expand Down
81 changes: 2 additions & 79 deletions src/api/import.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import debug from 'debug';
import fs from 'fs-extra';
import inquirer from 'inquirer';
import path from 'path';

import initGit from '../init/init-git';
Expand All @@ -12,7 +11,6 @@ import { info, warn } from '../util/messages';
import installDepList from '../util/install-dependencies';
import readPackageJSON from '../util/read-package-json';
import confirmIfInteractive from '../util/confirm-if-interactive';
import { yarnOrNpmSpawn, hasYarn } from '../util/yarn-or-npm';

const d = debug('electron-forge:import');

Expand All @@ -27,7 +25,6 @@ const d = debug('electron-forge:import');
/**
* Attempt to import a given module directory to the Electron Forge standard.
*
* - Replaces the prebuilt electron package with the one that integrates with `electron-compile`
* - Sets up `git` and the correct NPM dependencies
* - Adds a template forge config to `package.json`
*
Expand Down Expand Up @@ -68,18 +65,6 @@ export default async (providedOptions = {}) => {
}
}

// eslint-disable-next-line max-len
const shouldChangeMain = await confirmIfInteractive(interactive, 'Do you want us to change the "main" attribute of your package.json? If you are currently using babel and pointing to a "build" directory say yes.', false);
if (shouldChangeMain) {
const { newMain } = await inquirer.createPromptModule()({
type: 'input',
name: 'newMain',
default: packageJSON.main,
message: 'Enter the relative path to your uncompiled main file',
});
packageJSON.main = newMain;
}

packageJSON.dependencies = packageJSON.dependencies || {};
packageJSON.devDependencies = packageJSON.devDependencies || {};

Expand All @@ -96,13 +81,8 @@ export default async (providedOptions = {}) => {
'electron-winstaller': 'already uses this module as a transitive dependency',
};

let electronName;
for (const key of keys) {
if (key === 'electron' || key === 'electron-prebuilt') {
delete packageJSON.dependencies[key];
delete packageJSON.devDependencies[key];
electronName = key;
} else if (buildToolPackages[key]) {
if (buildToolPackages[key]) {
const explanation = buildToolPackages[key];
// eslint-disable-next-line max-len
const shouldRemoveDependency = await confirmIfInteractive(interactive, `Do you want us to remove the "${key}" dependency in package.json? Electron Forge ${explanation}.`);
Expand Down Expand Up @@ -139,48 +119,21 @@ export default async (providedOptions = {}) => {
});
};

let electronVersion;
if (electronName) {
const electronPackageJSON = await readPackageJSON(path.resolve(dir, 'node_modules', electronName));
electronVersion = electronPackageJSON.version;
packageJSON.devDependencies['electron-prebuilt-compile'] = electronVersion;
}

await writeChanges();

if (electronName) {
await asyncOra('Pruning deleted modules', async () => {
d('attempting to prune node_modules in:', dir);
await yarnOrNpmSpawn(hasYarn() ? [] : ['prune'], {
cwd: dir,
stdio: 'ignore',
});
});
}

await asyncOra('Installing dependencies', async () => {
d('deleting old dependencies forcefully');
await fs.remove(path.resolve(dir, 'node_modules/.bin/electron'));
await fs.remove(path.resolve(dir, 'node_modules/.bin/electron.cmd'));

if (electronName) {
await fs.remove(path.resolve(dir, 'node_modules', electronName));
}

d('installing dependencies');
await installDepList(dir, deps);

d('installing devDependencies');
await installDepList(dir, devDeps, true);

d('installing exactDevDependencies');
await installDepList(dir, exactDevDeps.map((dep) => {
if (dep === 'electron-prebuilt-compile') {
return `${dep}@${electronVersion || 'latest'}`;
}

return dep;
}), true, true);
await installDepList(dir, exactDevDeps, true, true);
});

packageJSON = await readPackageJSON(dir);
Expand All @@ -205,39 +158,9 @@ export default async (providedOptions = {}) => {
}
});

let babelConfig = packageJSON.babel;
const babelPath = path.resolve(dir, '.babelrc');
if (!babelConfig && await fs.pathExists(babelPath)) {
babelConfig = await fs.readJson(babelPath, 'utf8');
}

if (babelConfig) {
await asyncOra('Porting original babel config', async () => {
let compileConfig = {};
const compilePath = path.resolve(dir, '.compilerc');
if (await fs.pathExists(compilePath)) {
compileConfig = await fs.readJson(compilePath, 'utf8');
}

await fs.writeJson(compilePath, Object.assign(compileConfig, {
'application/javascript': babelConfig,
}), { spaces: 2 });
});

info(interactive, 'NOTE: You might be able to remove your `.compilerc` file completely if you are only using the `es2016` and `react` presets'.yellow);
}

info(interactive, `
We have ATTEMPTED to convert your app to be in a format that electron-forge understands.
Nothing much will have changed but we added the ${'"electron-prebuilt-compile"'.cyan} dependency. This is \
the dependency you must version bump to get newer versions of Electron.
We also tried to import any build tooling you already had but we can't get everything. You might need to convert any CLI/gulp/grunt tasks yourself.
Also please note if you are using \`preload\` scripts you need to follow the steps outlined \
at https://github.com/electron-userland/electron-forge/wiki/Using-%27preload%27-scripts
Thanks for using ${'"electron-forge"'.green}!!!`);
};
25 changes: 5 additions & 20 deletions src/api/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import initCustom from '../init/init-custom';
import initDirectory from '../init/init-directory';
import initGit from '../init/init-git';
import initNPM from '../init/init-npm';
import initStandardFix from '../init/init-standard-fix';
import initStarter from '../init/init-starter-files';

import asyncOra from '../util/ora-handler';
Expand All @@ -15,7 +14,6 @@ const d = debug('electron-forge:init');
* @typedef {Object} InitOptions
* @property {string} [dir=process.cwd()] The path to the app to be initialized
* @property {boolean} [interactive=false] Whether to use sensible defaults or prompt the user visually
* @property {string} [lintStyle=airbnb] The lintStyle to pass through to the template creator
* @property {boolean} [copyCIFiles=false] Whether to copy Travis and AppVeyor CI files
* @property {string} [template] The custom template to use. If left empty, the default template is used
*/
Expand All @@ -28,34 +26,21 @@ const d = debug('electron-forge:init');
*/
export default async (providedOptions = {}) => {
// eslint-disable-next-line prefer-const, no-unused-vars
let { dir, interactive, lintStyle, copyCIFiles, template } = Object.assign({
let { dir, interactive, copyCIFiles, template } = Object.assign({
dir: process.cwd(),
interactive: false,
lintStyle: 'airbnb',
copyCIFiles: false,
template: null,
}, providedOptions);
asyncOra.interactive = interactive;

d(`Initializing in: ${dir}`);

if (!template) {
lintStyle = lintStyle.toLowerCase();
if (!['airbnb', 'standard'].includes(lintStyle)) {
d(`Unrecognized lintStyle argument: '${lintStyle}' -- defaulting to 'airbnb'`);
lintStyle = 'airbnb';
}
}

await initDirectory(dir, interactive);
await initGit(dir);
await initStarter(dir, { lintStyle: template ? undefined : lintStyle, copyCIFiles });
await initNPM(dir, template ? undefined : lintStyle);
if (!template) {
if (lintStyle === 'standard') {
await initStandardFix(dir);
}
} else {
await initCustom(dir, template, lintStyle);
await initStarter(dir, { copyCIFiles });
await initNPM(dir);
if (template) {
await initCustom(dir, template);
}
};
3 changes: 2 additions & 1 deletion src/api/make.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import readPackageJSON from '../util/read-package-json';
import { requireSearchRaw } from '../util/require-search';
import resolveDir from '../util/resolve-dir';
import getCurrentOutDir from '../util/out-dir';
import getElectronVersion from '../util/electron-version';

import packager from './package';

Expand Down Expand Up @@ -129,7 +130,7 @@ export default async (providedOptions = {}) => {

await runHook(forgeConfig, 'preMake');

for (const targetArch of parseArchs(platform, arch, packageJSON.devDependencies['electron-prebuilt-compile'])) {
for (const targetArch of parseArchs(platform, arch, getElectronVersion(packageJSON))) {
const packageDir = path.resolve(outDir, `${appName}-${actualTargetPlatform}-${targetArch}`);
if (!(await fs.pathExists(packageDir))) {
throw new Error(`Couldn't find packaged app at: ${packageDir}`);
Expand Down
18 changes: 10 additions & 8 deletions src/api/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ import getForgeConfig from '../util/forge-config';
import runHook from '../util/hook';
import { warn } from '../util/messages';
import realOra, { fakeOra } from '../util/ora';
import packagerCompileHook from '../util/compile-hook';
import readPackageJSON from '../util/read-package-json';
import rebuildHook from '../util/rebuild';
import requireSearch from '../util/require-search';
import resolveDir from '../util/resolve-dir';
import getCurrentOutDir from '../util/out-dir';
import getElectronVersion from '../util/electron-version';

const d = debug('electron-forge:packager');

Expand Down Expand Up @@ -102,15 +102,15 @@ export default async (providedOptions = {}) => {
prepareCounter += 1;
prepareSpinner = ora(`Preparing to Package Application for arch: ${(prepareCounter === 2 ? 'armv7l' : 'x64').cyan}`).start();
}
await fs.remove(path.resolve(buildPath, 'node_modules/electron-compile/test'));
const bins = await pify(glob)(path.join(buildPath, '**/.bin/**/*'));
for (const bin of bins) {
await fs.remove(bin);
}
done();
}, async (...args) => {
}, async (buildPath, electronVersion, pPlatform, pArch, done) => {
prepareSpinner.succeed();
await packagerCompileHook(dir, ...args);
await runHook(forgeConfig, 'packageAfterCopy', buildPath, electronVersion, pPlatform, pArch);
done();
},
];

Expand All @@ -136,6 +136,11 @@ export default async (providedOptions = {}) => {
afterPruneHooks.push(...resolveHooks(forgeConfig.electronPackagerConfig.afterPrune, dir));
}

afterPruneHooks.push(async (buildPath, electronVersion, pPlatform, pArch, done) => {
await runHook(forgeConfig, 'packageAfterPrune', buildPath, electronVersion, pPlatform, pArch);
done();
});

const packageOpts = Object.assign({
asar: false,
overwrite: true,
Expand All @@ -147,12 +152,9 @@ export default async (providedOptions = {}) => {
arch,
platform,
out: outDir,
electronVersion: packageJSON.devDependencies['electron-prebuilt-compile'],
electronVersion: getElectronVersion(packageJSON),
});
packageOpts.quiet = true;
if (typeof packageOpts.asar === 'object' && packageOpts.asar.unpack) {
throw new Error('electron-compile does not support asar.unpack yet. Please use asar.unpackDir');
}

if (!packageJSON.version && !packageOpts.appVersion) {
// eslint-disable-next-line max-len
Expand Down
21 changes: 17 additions & 4 deletions src/api/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import rebuild from '../util/rebuild';
import resolveDir from '../util/resolve-dir';
import getForgeConfig from '../util/forge-config';
import runHook from '../util/hook';
import getElectronVersion from '../util/electron-version';

/**
* @typedef {Object} StartOptions
Expand Down Expand Up @@ -52,7 +53,21 @@ export default async (providedOptions = {}) => {

const forgeConfig = await getForgeConfig(dir);

await rebuild(dir, packageJSON.devDependencies['electron-prebuilt-compile'], process.platform, process.arch, forgeConfig.electronRebuildConfig);
await rebuild(dir, getElectronVersion(packageJSON), process.platform, process.arch, forgeConfig.electronRebuildConfig);

await runHook(forgeConfig, 'generateAssets');

// If a plugin has taken over the start command let's stop here
const spawnedPluginChild = await forgeConfig.pluginInterface.overrideStartLogic({
dir,
appPath,
interactive,
enableLogging,
args,
runAsNode,
inspect,
});
if (spawnedPluginChild) return spawnedPluginChild;

const spawnOpts = {
cwd: dir,
Expand All @@ -75,10 +90,8 @@ export default async (providedOptions = {}) => {

let spawned;

await runHook(forgeConfig, 'generateAssets');

await asyncOra('Launching Application', async () => {
spawned = spawn(process.execPath, [path.resolve(dir, 'node_modules/electron-prebuilt-compile/lib/cli'), appPath].concat(args), spawnOpts);
spawned = spawn(process.execPath, [path.resolve(dir, 'node_modules/electron/cli'), appPath].concat(args), spawnOpts);
});

return spawned;
Expand Down
2 changes: 0 additions & 2 deletions src/electron-forge-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { init } from './api';
.version(require('../package.json').version)
.arguments('[name]')
.option('-t, --template [name]', 'Name of the forge template to use')
.option('-l, --lintStyle [style]', 'Linting standard to follow. For the default template it can be "airbnb" or "standard"', 'airbnb')
.option('-c, --copy-ci-files', 'Whether to copy the templated CI files (defaults to false)', false)
.action((name) => {
if (!name) return;
Expand All @@ -25,7 +24,6 @@ import { init } from './api';
const initOpts = {
dir,
interactive: true,
lintStyle: program.lintStyle,
copyCIFiles: !!program.copyCiFiles,
};
if (program.template) initOpts.template = program.template;
Expand Down
4 changes: 2 additions & 2 deletions src/init/init-custom.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ora from '../util/ora';

const d = debug('electron-forge:init:custom');

export default async (dir, template, lintStyle) => {
export default async (dir, template) => {
let templateModulePath;
await asyncOra(`Locating custom template: "${template}"`, async () => {
try {
Expand Down Expand Up @@ -57,6 +57,6 @@ export default async (dir, template, lintStyle) => {
});

if (typeof templateModule.postCopy === 'function') {
await Promise.resolve(templateModule.postCopy(dir, ora, lintStyle));
await Promise.resolve(templateModule.postCopy(dir, ora));
}
};
Loading

0 comments on commit d59695e

Please sign in to comment.