Skip to content

Commit

Permalink
build: convert Forge and Webpack config to TypeScript (#1406)
Browse files Browse the repository at this point in the history
* build: convert Forge and Webpack config to TypeScript

* fix: yarn electron-releases on Windows
  • Loading branch information
dsanders11 authored Jul 18, 2023
1 parent 7cf08bf commit 7226571
Show file tree
Hide file tree
Showing 12 changed files with 202 additions and 95 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ jobs:
shell: bash.exe
steps:
- install
- run: export WINDOWS_CODESIGN_FILE=$(node ./tools/add-windows-cert.js)
- run: export WINDOWS_CODESIGN_FILE=$(ts-node ./tools/add-windows-cert.ts)
- run: npx yarn run publish --arch=<< parameters.arch >> --dry-run
- store_artifacts:
path: out
Expand Down
28 changes: 17 additions & 11 deletions forge.config.js → forge.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
const fs = require('fs');
const path = require('path');
import * as fs from 'node:fs';
import * as path from 'node:path';

const packageJson = require('./package.json');
const { maybeFetchContributors } = require('./tools/contributors');
const { populateReleases } = require('./tools/fetch-releases');
import type { ForgeConfig } from '@electron-forge/shared-types';

import packageJson from './package.json';
import { maybeFetchContributors } from './tools/contributors';
import { populateReleases } from './tools/fetch-releases';
import { mainConfig } from './tools/webpack/webpack.main.config';
import { rendererConfig } from './tools/webpack/webpack.renderer.config';

const { version } = packageJson;
const iconDir = path.resolve(__dirname, 'assets', 'icons');
Expand All @@ -27,7 +31,7 @@ const commonLinuxConfig = {
mimeType: ['x-scheme-handler/electron-fiddle'],
};

const config = {
const config: ForgeConfig = {
hooks: {
generateAssets: async () => {
await Promise.all([populateReleases(), maybeFetchContributors(true)]);
Expand All @@ -45,10 +49,10 @@ const config = {
liveReload: false,
hot: 'only',
},
mainConfig: path.join(root, 'tools/webpack/webpack.main.config.js'),
mainConfig: mainConfig,
renderer: {
nodeIntegration: true,
config: path.join(root, 'tools/webpack/webpack.renderer.config.js'),
config: rendererConfig,
entryPoints: [
{
html: path.join(root, './static/index.html'),
Expand Down Expand Up @@ -108,7 +112,7 @@ const config = {
{
name: '@electron-forge/maker-squirrel',
platforms: ['win32'],
config: (arch) => ({
config: (arch: string) => ({
name: 'electron-fiddle',
authors: 'Electron Community',
exe: 'electron-fiddle.exe',
Expand All @@ -125,6 +129,7 @@ const config = {
{
name: '@electron-forge/maker-zip',
platforms: ['darwin'],
config: {},
},
{
name: '@electron-forge/maker-deb',
Expand Down Expand Up @@ -178,7 +183,8 @@ function notarizeMaybe() {
return;
}

config.packagerConfig.osxNotarize = {
// TODO: appBundleId is not being accepted for typing
(config.packagerConfig!.osxNotarize as any) = {
appBundleId: 'com.electron.fiddle',
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_ID_PASSWORD,
Expand All @@ -189,4 +195,4 @@ function notarizeMaybe() {
notarizeMaybe();

// Finally, export it
module.exports = config;
export default config;
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"homepage": "https://electronjs.org/fiddle",
"main": "./.webpack/main",
"scripts": {
"contributors": "node ./tools/contributors.js",
"contributors": "ts-node ./tools/contributors.ts",
"lint:style": "stylelint \"./src/less/*.less\"",
"lint:ts": "eslint \"./**/*.{ts,tsx}\"",
"lint:js": "eslint \"./**/*.js\"",
Expand All @@ -24,7 +24,7 @@
"test:ci": "jest --ci --config=jest.json --coverage --runInBand --reporters=jest-junit",
"test:report": "jest --config=jest.json --json --bail=false --outputFile=report.json | true",
"tsc": "tsc --noEmit -p .",
"electron-releases": "node --unhandled-rejections=strict ./tools/fetch-releases.js",
"electron-releases": "node --unhandled-rejections=strict -r ts-node/register ./tools/fetch-releases.ts",
"postinstall": "husky install && npm run electron-releases"
},
"keywords": [
Expand All @@ -35,7 +35,7 @@
"author": "Felix Rieseberg <[email protected]>",
"license": "MIT",
"config": {
"forge": "./forge.config.js"
"forge": "./forge.config.ts"
},
"dependencies": {
"@blueprintjs/core": "^3.36.0",
Expand Down Expand Up @@ -144,6 +144,7 @@
"terser-webpack-plugin": "^5.3.3",
"ts-jest": "^29.1.1",
"ts-loader": "^9.4.4",
"ts-node": "^10.9.1",
"typescript": "^5.1.6",
"webpack": "^5.69.1"
},
Expand Down
4 changes: 2 additions & 2 deletions tools/add-windows-cert.js → tools/add-windows-cert.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as os from 'os';
import * as path from 'path';
import * as os from 'node:os';
import * as path from 'node:path';

import * as fs from 'fs-extra';

Expand Down
95 changes: 54 additions & 41 deletions tools/contributors.js → tools/contributors.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
const path = require('path');
const util = require('util');
import * as path from 'node:path';
import * as util from 'node:util';

const fetch = require('cross-fetch');
const fs = require('fs-extra');
const logSymbols = require('log-symbols');
import fetch from 'cross-fetch';
import fs from 'fs-extra';
import logSymbols from 'log-symbols';

const { GITHUB_TOKEN, GH_TOKEN } = process.env;
const CONTRIBUTORS_FILE_PATH = path.join(
Expand All @@ -12,14 +12,33 @@ const CONTRIBUTORS_FILE_PATH = path.join(
);
const CONTRIBUTORS_URL =
'https://api.github.com/repos/electron/fiddle/contributors?per_page=100';
const HEADERS =
const HEADERS: Record<string, string> =
GITHUB_TOKEN || GH_TOKEN
? {
Authorization: `Bearer ${GITHUB_TOKEN || GH_TOKEN}`,
}
: {};

async function maybeFetchContributors(silent) {
interface GitHubContributorInfo {
html_url: string;
url: string;
login: string;
avatar_url: string;
type: string;
contributions: number;
}

interface ContributorInfo {
url: string;
api: string;
login: string;
avatar: string;
name: string;
bio: string;
location: string;
}

export async function maybeFetchContributors(silent?: boolean): Promise<void> {
try {
const stats = fs.statSync(CONTRIBUTORS_FILE_PATH);
const mtime = new Date(util.inspect(stats.mtime));
Expand Down Expand Up @@ -66,9 +85,10 @@ async function maybeFetchContributors(silent) {
* Fetch the name for a contributor
*
* @param contributor - Contributor object
* @returns {Promise}
*/
function fetchDetailsContributor(contributor) {
function fetchDetailsContributor(contributor: {
api: string;
}): Promise<ContributorInfo> {
return fetch(contributor.api, { headers: HEADERS }).then((response) =>
response.json(),
);
Expand All @@ -78,41 +98,38 @@ function fetchDetailsContributor(contributor) {
* Fetch the names for an array of contributors
*
* @param contributors - Array of contributor
* @returns {Promise}
*/
function fetchDetailsContributors(contributors) {
return new Promise((resolve) => {
const withDetails = contributors;
const promises = [];

contributors.forEach((contributor, i) => {
const detailFetcher = fetchDetailsContributor(contributor).then(
({ name, bio, location }) => {
withDetails[i].name = name;
withDetails[i].bio = bio;
withDetails[i].location = location;
},
);

promises.push(detailFetcher);
});
async function fetchDetailsContributors(
contributors: Pick<ContributorInfo, 'api'>[],
) {
const withDetails = contributors as ContributorInfo[];
const promises: Promise<void>[] = [];

contributors.forEach((contributor, i) => {
const detailFetcher = fetchDetailsContributor(contributor).then(
({ name, bio, location }) => {
withDetails[i].name = name;
withDetails[i].bio = bio;
withDetails[i].location = location;
},
);

Promise.all(promises).then(() => resolve(withDetails));
promises.push(detailFetcher);
});

await Promise.all(promises);
return withDetails;
}

/**
* (description)
*
* @export
* @returns {Promise}
*/
function fetchContributors() {
const contributors = [];
const contributors: Pick<
ContributorInfo,
'url' | 'api' | 'login' | 'avatar'
>[] = [];

return fetch(CONTRIBUTORS_URL, { headers: HEADERS })
.then((response) => response.json())
.then(async (data) => {
.then(async (data: GitHubContributorInfo[]) => {
if (data && data.forEach) {
data.forEach(
({ html_url, url, login, avatar_url, type, contributions }) => {
Expand Down Expand Up @@ -140,7 +157,7 @@ function fetchContributors() {
* Fetch the contributors and write the result to disk
*/
async function fetchAndWriteContributorsFile() {
await new Promise((resolve) => {
await new Promise<void>((resolve) => {
fs.access(
CONTRIBUTORS_FILE_PATH,
fs.constants.F_OK | fs.constants.R_OK | fs.constants.W_OK,
Expand All @@ -151,7 +168,7 @@ async function fetchAndWriteContributorsFile() {
}

console.log(logSymbols.info, 'Fetching contributors');
let data;
let data: ContributorInfo[];

try {
data = await fetchContributors();
Expand All @@ -178,10 +195,6 @@ async function fetchAndWriteContributorsFile() {
});
}

module.exports = {
maybeFetchContributors,
};

if (require.main === module) {
(async () => {
await maybeFetchContributors();
Expand Down
12 changes: 4 additions & 8 deletions tools/fetch-releases.js → tools/fetch-releases.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const path = require('path');
import * as path from 'node:path';

const { ElectronVersions } = require('@electron/fiddle-core');
const fs = require('fs-extra');
import { ElectronVersions } from '@electron/fiddle-core';
import fs from 'fs-extra';

const file = path.join(__dirname, '..', 'static', 'releases.json');

async function populateReleases() {
export async function populateReleases() {
const elves = await ElectronVersions.create(undefined, { ignoreCache: true });
const releases = elves.versions.map(({ version }) =>
elves.getReleaseInfo(version),
Expand All @@ -26,10 +26,6 @@ async function populateReleases() {
}
}

module.exports = {
populateReleases,
};

if (require.main === module) {
(async () => {
await populateReleases();
Expand Down
11 changes: 0 additions & 11 deletions tools/webpack/common/webpack.plugins.js

This file was deleted.

14 changes: 14 additions & 0 deletions tools/webpack/common/webpack.plugins.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type IForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
import { ProvidePlugin } from 'webpack';

// eslint-disable-next-line @typescript-eslint/no-var-requires
const ForkTsCheckerWebpackPlugin: typeof IForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

export const plugins = [
new ForkTsCheckerWebpackPlugin({
logger: 'webpack-infrastructure',
}),
new ProvidePlugin({
__importStar: ['tslib', '__importStar'],
}),
];
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
module.exports = [
import type { ModuleOptions } from 'webpack';

export const rules: Required<ModuleOptions>['rules'] = [
// Add support for native node modules
{
// We're specifying native_modules in the test because the asset relocator loader generates a
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
const CopyPlugin = require('copy-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
import CopyPlugin from 'copy-webpack-plugin';
import TerserPlugin from 'terser-webpack-plugin';
import type { Configuration } from 'webpack';

const plugins = require('./common/webpack.plugins');
const rules = require('./common/webpack.rules');
import { plugins } from './common/webpack.plugins';
import { rules } from './common/webpack.rules';

module.exports = {
export const mainConfig: Configuration = {
/**
* This is the main entry point for your application, it's the first file
* that runs in the main process.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import MonacoWebpackPlugin from 'monaco-editor-webpack-plugin';
import type { Configuration } from 'webpack';

const plugins = require('./common/webpack.plugins');
const rules = require('./common/webpack.rules');
import { plugins } from './common/webpack.plugins';
import { rules } from './common/webpack.rules';

module.exports = {
export const rendererConfig: Configuration = {
module: {
rules: [
...rules,
Expand Down
Loading

0 comments on commit 7226571

Please sign in to comment.