+
Skip to content

Commit 777197e

Browse files
authored
feat!: prefer forge.config.js over package.json config (#2991)
BREAKING CHANGE: templates that mutated the Forge config within `package.json` will need to instantiate their own `forge.config.js`
1 parent 25a0a63 commit 777197e

File tree

11 files changed

+172
-117
lines changed

11 files changed

+172
-117
lines changed

packages/api/core/src/api/import.ts

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,20 @@ export default async ({
8383
let importExactDevDeps = ([] as string[]).concat(exactDevDeps);
8484

8585
let packageJSON = await readRawPackageJson(dir);
86+
if (!packageJSON.version) {
87+
warn(interactive, chalk.yellow(`Please set the ${chalk.green('"version"')} in your application's package.json`));
88+
}
8689
if (packageJSON.config && packageJSON.config.forge) {
8790
if (packageJSON.config.forge.makers) {
88-
warn(interactive, chalk.green('It looks like this project is already configured for Electron Forge'));
91+
warn(interactive, chalk.green('Existing Electron Forge configuration detected'));
8992
if (typeof shouldContinueOnExisting === 'function') {
9093
if (!(await shouldContinueOnExisting())) {
9194
// TODO: figure out if we can just return early here
9295
// eslint-disable-next-line no-process-exit
9396
process.exit(0);
9497
}
9598
}
96-
} else if (typeof packageJSON.config.forge === 'string') {
99+
} else if (!(typeof packageJSON.config.forge === 'object')) {
97100
warn(
98101
interactive,
99102
chalk.yellow(
@@ -187,23 +190,23 @@ export default async ({
187190
await installDepList(dir, importExactDevDeps, DepType.DEV, DepVersionRestriction.EXACT);
188191
});
189192

190-
packageJSON = await readRawPackageJson(dir);
191-
192-
if (!packageJSON.version) {
193-
warn(interactive, chalk.yellow('Please set the "version" in your application\'s package.json'));
194-
}
195-
196-
packageJSON.config = packageJSON.config || {};
197-
const templatePackageJSON = await readRawPackageJson(baseTemplate.templateDir);
198-
if (packageJSON.config.forge) {
199-
if (typeof packageJSON.config.forge !== 'string') {
200-
packageJSON.config.forge = merge(templatePackageJSON.config.forge, packageJSON.config.forge);
193+
await asyncOra('Copying base template Forge configuration', async () => {
194+
const pathToTemplateConfig = path.resolve(baseTemplate.templateDir, 'forge.config.js');
195+
196+
// if there's an existing config.forge object in package.json
197+
if (packageJSON?.config?.forge && typeof packageJSON.config.forge === 'object') {
198+
d('detected existing Forge config in package.json, merging with base template Forge config');
199+
// eslint-disable-next-line @typescript-eslint/no-var-requires
200+
const templateConfig = require(path.resolve(baseTemplate.templateDir, 'forge.config.js'));
201+
packageJSON = await readRawPackageJson(dir);
202+
merge(templateConfig, packageJSON.config.forge); // mutates the templateConfig object
203+
await writeChanges();
204+
// otherwise, write to forge.config.js
205+
} else {
206+
d('writing new forge.config.js');
207+
await fs.copyFile(pathToTemplateConfig, path.resolve(dir, 'forge.config.js'));
201208
}
202-
} else {
203-
packageJSON.config.forge = templatePackageJSON.config.forge;
204-
}
205-
206-
await writeChanges();
209+
});
207210

208211
await asyncOra('Fixing .gitignore', async () => {
209212
if (await fs.pathExists(path.resolve(dir, '.gitignore'))) {
@@ -218,8 +221,8 @@ export default async ({
218221
interactive,
219222
`
220223
221-
We have ATTEMPTED to convert your app to be in a format that electron-forge understands.
224+
We have attempted to convert your app to be in a format that Electron Forge understands.
222225
223-
Thanks for using ${chalk.green('Electron Forge')}!!!`
226+
Thanks for using ${chalk.green('Electron Forge')}!`
224227
);
225228
};

packages/api/core/src/api/init-scripts/init-git.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import debug from 'debug';
66
const d = debug('electron-forge:init:git');
77

88
export default async (dir: string): Promise<void> => {
9-
await asyncOra('Initializing Git Repository', async () => {
9+
await asyncOra('Initializing Git repository', async () => {
1010
await new Promise<void>((resolve, reject) => {
1111
exec(
1212
'git rev-parse --show-toplevel',

packages/api/core/src/util/forge-config.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import path from 'path';
22

3-
import { ForgeConfig, IForgeResolvableMaker, ResolvedForgeConfig } from '@electron-forge/shared-types';
3+
import { ForgeConfig, ResolvedForgeConfig } from '@electron-forge/shared-types';
44
import fs from 'fs-extra';
55
import * as interpret from 'interpret';
66
import { template } from 'lodash';
@@ -16,15 +16,6 @@ const underscoreCase = (str: string) =>
1616
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
1717
.toUpperCase();
1818

19-
export type PackageJSONForInitialForgeConfig = {
20-
name?: string;
21-
config: {
22-
forge: {
23-
makers: Pick<IForgeResolvableMaker, 'name' | 'config'>[];
24-
};
25-
};
26-
};
27-
2819
// Why: needs access to Object methods and also needs to be able to match any interface.
2920
// eslint-disable-next-line @typescript-eslint/ban-types
3021
type ProxiedObject = object;

packages/api/core/test/slow/api_spec_slow.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ for (const nodeInstaller of ['npm', 'yarn']) {
7979
expect(await fs.pathExists(path.resolve(dir, 'node_modules/@electron-forge/cli')), '@electron-forge/cli should exist').to.equal(true);
8080
});
8181

82+
it('should create a forge.config.js', async () => {
83+
await expectProjectPathExists(dir, 'forge.config.js', 'file');
84+
});
85+
8286
describe('lint', () => {
8387
it('should initially pass the linting process', () => expectLintToPass(dir));
8488
});
@@ -230,13 +234,21 @@ describe('Electron Forge API', () => {
230234
packageJSON.name = 'testapp';
231235
packageJSON.version = '1.0.0-beta.1';
232236
packageJSON.productName = 'Test-App';
233-
assert(packageJSON.config.forge.packagerConfig);
234-
packageJSON.config.forge.packagerConfig.asar = false;
237+
packageJSON.config = packageJSON.config || {};
238+
packageJSON.config.forge = {
239+
...packageJSON.config.forge,
240+
packagerConfig: {
241+
asar: false,
242+
},
243+
};
235244
if (process.platform === 'win32') {
236245
await fs.copy(path.join(__dirname, '..', 'fixture', 'bogus-private-key.pvk'), path.join(dir, 'default.pvk'));
237246
devCert = await createDefaultCertificate('CN=Test Author', { certFilePath: dir });
238247
} else if (process.platform === 'linux') {
239-
packageJSON.config.forge.packagerConfig.executableName = 'testapp';
248+
packageJSON.config.forge.packagerConfig = {
249+
...packageJSON.config.forge.packagerConfig,
250+
executableName: 'testapp',
251+
};
240252
}
241253
packageJSON.homepage = 'http://www.example.com/';
242254
packageJSON.author = 'Test Author';

packages/template/base/src/BaseTemplate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export class BaseTemplate implements ForgeTemplate {
3939
await asyncOra('Copying Starter Files', async () => {
4040
d('creating directory:', path.resolve(directory, 'src'));
4141
await fs.mkdirs(path.resolve(directory, 'src'));
42-
const rootFiles = ['_gitignore'];
42+
const rootFiles = ['_gitignore', 'forge.config.js'];
4343
if (copyCIFiles) rootFiles.push(...['_travis.yml', '_appveyor.yml']);
4444
const srcFiles = ['index.css', 'index.js', 'index.html', 'preload.js'];
4545

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
module.exports = {
2+
packagerConfig: {},
3+
rebuildConfig: {},
4+
makers: [
5+
{
6+
name: '@electron-forge/maker-squirrel',
7+
config: {},
8+
},
9+
{
10+
name: '@electron-forge/maker-zip',
11+
platforms: ['darwin'],
12+
},
13+
{
14+
name: '@electron-forge/maker-deb',
15+
config: {},
16+
},
17+
{
18+
name: '@electron-forge/maker-rpm',
19+
config: {},
20+
},
21+
],
22+
};

packages/template/base/tmpl/package.json

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,5 @@
1212
},
1313
"keywords": [],
1414
"author": "",
15-
"license": "MIT",
16-
"config": {
17-
"forge": {
18-
"packagerConfig": {},
19-
"makers": [
20-
{
21-
"name": "@electron-forge/maker-squirrel",
22-
"config": {}
23-
},
24-
{
25-
"name": "@electron-forge/maker-zip",
26-
"platforms": [
27-
"darwin"
28-
]
29-
},
30-
{
31-
"name": "@electron-forge/maker-deb",
32-
"config": {}
33-
},
34-
{
35-
"name": "@electron-forge/maker-rpm",
36-
"config": {}
37-
}
38-
]
39-
}
40-
}
15+
"license": "MIT"
4116
}

packages/template/typescript-webpack/src/TypeScriptWebpackTemplate.ts

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,37 +11,8 @@ class TypeScriptWebpackTemplate extends BaseTemplate {
1111
async initializeTemplate(directory: string, options: InitTemplateOptions) {
1212
await super.initializeTemplate(directory, options);
1313
await asyncOra('Setting up Forge configuration', async () => {
14-
const packageJSONPath = path.resolve(directory, 'package.json');
15-
const packageJSON = await fs.readJson(packageJSONPath);
16-
17-
packageJSON.main = '.webpack/main';
18-
packageJSON.config.forge.plugins = packageJSON.config.forge.plugins || [];
19-
packageJSON.config.forge.plugins.push({
20-
name: '@electron-forge/plugin-webpack',
21-
config: {
22-
mainConfig: './webpack.main.config.js',
23-
renderer: {
24-
config: './webpack.renderer.config.js',
25-
entryPoints: [
26-
{
27-
html: './src/index.html',
28-
js: './src/renderer.ts',
29-
name: 'main_window',
30-
preload: {
31-
js: './src/preload.ts',
32-
},
33-
},
34-
],
35-
},
36-
},
37-
});
38-
39-
// Configure scripts for TS template
40-
packageJSON.scripts.lint = 'eslint --ext .ts,.tsx .';
41-
42-
await fs.writeJson(packageJSONPath, packageJSON, { spaces: 2 });
14+
await this.copyTemplateFile(directory, 'forge.config.ts');
4315
});
44-
4516
await asyncOra('Setting up TypeScript configuration', async () => {
4617
const filePath = (fileName: string) => path.join(directory, 'src', fileName);
4718

@@ -71,6 +42,18 @@ class TypeScriptWebpackTemplate extends BaseTemplate {
7142
// Remove preload.js and replace with preload.ts
7243
await fs.remove(filePath('preload.js'));
7344
await this.copyTemplateFile(path.join(directory, 'src'), 'preload.ts');
45+
46+
// update package.json
47+
const packageJSONPath = path.resolve(directory, 'package.json');
48+
const packageJSON = await fs.readJson(packageJSONPath);
49+
packageJSON.main = '.webpack/main';
50+
// Configure scripts for TS template
51+
packageJSON.scripts.lint = 'eslint --ext .ts,.tsx .';
52+
await fs.writeJson(packageJSONPath, packageJSON, {
53+
spaces: 2,
54+
});
55+
56+
await fs.writeJson(packageJSONPath, packageJSON, { spaces: 2 });
7457
});
7558
}
7659
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
module.exports = {
2+
packagerConfig: {},
3+
rebuildConfig: {},
4+
makers: [
5+
{
6+
name: '@electron-forge/maker-squirrel',
7+
config: {},
8+
},
9+
{
10+
name: '@electron-forge/maker-zip',
11+
platforms: ['darwin'],
12+
},
13+
{
14+
name: '@electron-forge/maker-deb',
15+
config: {},
16+
},
17+
{
18+
name: '@electron-forge/maker-rpm',
19+
config: {},
20+
},
21+
],
22+
plugins: [
23+
{
24+
name: '@electron-forge/plugin-webpack',
25+
config: {
26+
mainConfig: './webpack.main.config.js',
27+
renderer: {
28+
config: './webpack.renderer.config.js',
29+
entryPoints: [
30+
{
31+
html: './src/index.html',
32+
js: './src/renderer.js',
33+
name: 'main_window',
34+
preload: {
35+
js: './src/preload.js',
36+
},
37+
},
38+
],
39+
},
40+
},
41+
},
42+
],
43+
};

packages/template/webpack/src/WebpackTemplate.ts

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,7 @@ class WebpackTemplate extends BaseTemplate {
1111
public async initializeTemplate(directory: string, options: InitTemplateOptions) {
1212
await super.initializeTemplate(directory, options);
1313
await asyncOra('Setting up Forge configuration', async () => {
14-
const pjPath = path.resolve(directory, 'package.json');
15-
const currentPJ = await fs.readJson(pjPath);
16-
currentPJ.main = '.webpack/main';
17-
currentPJ.config.forge.plugins = currentPJ.config.forge.plugins || [];
18-
currentPJ.config.forge.plugins.push({
19-
name: '@electron-forge/plugin-webpack',
20-
config: {
21-
mainConfig: './webpack.main.config.js',
22-
renderer: {
23-
config: './webpack.renderer.config.js',
24-
entryPoints: [
25-
{
26-
html: './src/index.html',
27-
js: './src/renderer.js',
28-
name: 'main_window',
29-
preload: {
30-
js: './src/preload.js',
31-
},
32-
},
33-
],
34-
},
35-
},
36-
});
37-
await fs.writeJson(pjPath, currentPJ, {
38-
spaces: 2,
39-
});
14+
await this.copyTemplateFile(directory, 'forge.config.js');
4015
});
4116
await asyncOra('Setting up webpack configuration', async () => {
4217
await this.copyTemplateFile(directory, 'webpack.main.config.js');
@@ -59,6 +34,14 @@ class WebpackTemplate extends BaseTemplate {
5934
if (line.includes('link rel="stylesheet"')) return '';
6035
return line;
6136
});
37+
38+
// update package.json entry point
39+
const pjPath = path.resolve(directory, 'package.json');
40+
const currentPJ = await fs.readJson(pjPath);
41+
currentPJ.main = '.webpack/main';
42+
await fs.writeJson(pjPath, currentPJ, {
43+
spaces: 2,
44+
});
6245
});
6346
}
6447
}

0 commit comments

Comments
 (0)
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载