refactor(electron): typescript check on build scripts (#4650)

This commit is contained in:
Alex Yang
2023-10-18 01:13:47 -05:00
committed by GitHub
parent 9b3e6bf1f5
commit 524e48c8e6
17 changed files with 226 additions and 311 deletions

View File

@@ -1,23 +1,24 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import cp from 'node:child_process';
import { rm, symlink } from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const path = require('node:path');
const { rm, symlink } = require('node:fs/promises');
import { utils } from '@electron-forge/core';
const {
utils: { fromBuildIdentifier },
} = require('@electron-forge/core');
const {
import {
arch,
buildType,
icnsPath,
icoPath,
iconPngPath,
iconUrl,
icoPath,
platform,
productName,
iconUrl,
} = require('./scripts/make-env');
} from './scripts/make-env.js';
const fromBuildIdentifier = utils.fromBuildIdentifier;
const __dirname = fileURLToPath(new URL('.', import.meta.url));
const makers = [
!process.env.SKIP_BUNDLE &&
platform === 'darwin' && {
@@ -90,7 +91,7 @@ const makers = [
/**
* @type {import('@electron-forge/shared-types').ForgeConfig}
*/
module.exports = {
export default {
buildIdentifier: buildType,
packagerConfig: {
name: productName,
@@ -147,8 +148,6 @@ module.exports = {
return;
}
const { $ } = await import('zx');
// TODO: right now we do not need the following
// it is for octobase-node, but we dont use it for now.
if (platform === 'darwin' && arch === 'arm64') {
@@ -157,13 +156,17 @@ module.exports = {
process.env.TARGET = 'aarch64-apple-darwin';
}
if (platform === 'win32') {
$.shell = 'powershell.exe';
$.prefix = '';
}
// run yarn generate-assets
await $`yarn generate-assets`;
cp.spawnSync('yarn', ['generate-assets'], {
stdio: 'inherit',
env: {
...process.env,
NODE_OPTIONS: (process.env.NODE_OPTIONS ?? '').replace(
'--loader ts-node/esm',
''
),
},
cwd: __dirname,
});
},
},
};

View File

@@ -2,23 +2,23 @@
"name": "@affine/electron",
"private": true,
"version": "0.10.0-canary.1",
"author": "affine",
"author": "toeverything",
"repository": {
"url": "https://github.com/toeverything/AFFiNE",
"type": "git"
},
"description": "AFFiNE App",
"description": "AFFiNE Desktop App",
"homepage": "https://github.com/toeverything/AFFiNE",
"scripts": {
"start": "electron .",
"dev": "yarn cross-env DEV_SERVER_URL=http://localhost:8080 node scripts/dev.mjs",
"dev:prod": "yarn node scripts/dev.mjs",
"build": "NODE_ENV=production zx scripts/build-layers.mjs",
"build:dev": "NODE_ENV=development zx scripts/build-layers.mjs",
"generate-assets": "zx scripts/generate-assets.mjs",
"dev": "DEV_SERVER_URL=http://localhost:8080 yarn ts-node ./scripts/dev.ts",
"dev:prod": "yarn ts-node scripts/dev.ts",
"build": "NODE_ENV=production ts-node scripts/build-layers.ts",
"build:dev": "NODE_ENV=development ts-node scripts/build-layers.ts",
"generate-assets": "ts-node scripts/generate-assets.ts",
"package": "electron-forge package",
"make": "electron-forge make",
"make-squirrel": "yarn ts-node-esm -T scripts/make-squirrel.mts"
"make": "NODE_OPTIONS=\"--loader ts-node/esm\" electron-forge make",
"make-squirrel": "yarn ts-node scripts/make-squirrel.ts"
},
"config": {
"forge": "./forge.config.js"
@@ -51,7 +51,6 @@
"@toeverything/infra": "workspace:*",
"@types/uuid": "^9.0.5",
"builder-util-runtime": "^9.2.1",
"cross-env": "7.0.3",
"electron": "^27.0.0",
"electron-log": "^5.0.0-rc.1",
"electron-squirrel-startup": "1.0.0",
@@ -69,8 +68,7 @@
"uuid": "^9.0.1",
"vitest": "0.34.6",
"which": "^4.0.0",
"zod": "^3.22.4",
"zx": "^7.2.3"
"zod": "^3.22.4"
},
"dependencies": {
"async-call-rpc": "^6.3.1",
@@ -89,7 +87,6 @@
}
]
},
"stableVersion": "0.5.3",
"peerDependencies": {
"ts-node": "*"
}

View File

@@ -1,23 +1,12 @@
#!/usr/bin/env zx
import 'zx/globals';
import * as esbuild from 'esbuild';
import { config } from './common.mjs';
const NODE_ENV =
process.env.NODE_ENV === 'development' ? 'development' : 'production';
if (process.platform === 'win32') {
$.shell = true;
$.prefix = '';
}
import { config, mode } from './common';
async function buildLayers() {
const common = config();
const define = {
'process.env.NODE_ENV': `"${NODE_ENV}"`,
const define: Record<string, string> = {
'process.env.NODE_ENV': `"${mode}"`,
'process.env.BUILD_TYPE': `"${process.env.BUILD_TYPE || 'stable'}"`,
};
@@ -28,10 +17,10 @@ async function buildLayers() {
}
await esbuild.build({
...common.layers,
...common,
define: define,
});
}
await buildLayers();
echo('Build layers done');
console.log('Build layers done');

View File

@@ -1,59 +0,0 @@
import { resolve } from 'node:path';
import { fileURLToPath } from 'url';
export const electronDir = fileURLToPath(new URL('..', import.meta.url));
export const rootDir = resolve(electronDir, '..', '..');
export const NODE_MAJOR_VERSION = 18;
// hard-coded for now:
// fixme(xp): report error if app is not running on DEV_SERVER_URL
const DEV_SERVER_URL = process.env.DEV_SERVER_URL;
/** @type 'production' | 'development'' */
const mode = (process.env.NODE_ENV = process.env.NODE_ENV || 'development');
/** @return {{layers: import('esbuild').BuildOptions}} */
export const config = () => {
const define = Object.fromEntries([
['process.env.NODE_ENV', `"${mode}"`],
['process.env.USE_WORKER', '"true"'],
]);
if (DEV_SERVER_URL) {
define['process.env.DEV_SERVER_URL'] = `"${DEV_SERVER_URL}"`;
}
return {
layers: {
entryPoints: [
resolve(electronDir, './src/main/index.ts'),
resolve(electronDir, './src/preload/index.ts'),
resolve(electronDir, './src/helper/index.ts'),
],
entryNames: '[dir]',
outdir: resolve(electronDir, './dist'),
bundle: true,
target: `node${NODE_MAJOR_VERSION}`,
platform: 'node',
external: [
'electron',
'electron-updater',
'@toeverything/plugin-infra',
'yjs',
'semver',
'tinykeys',
],
define: define,
format: 'cjs',
loader: {
'.node': 'copy',
},
assetNames: '[name]',
treeShaking: true,
sourcemap: 'linked',
},
};
};

View File

@@ -0,0 +1,57 @@
import { resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import type { BuildOptions } from 'esbuild';
export const electronDir = fileURLToPath(new URL('..', import.meta.url));
export const rootDir = resolve(electronDir, '..', '..');
export const NODE_MAJOR_VERSION = 18;
// hard-coded for now:
// fixme(xp): report error if app is not running on DEV_SERVER_URL
const DEV_SERVER_URL = process.env.DEV_SERVER_URL;
export const mode = (process.env.NODE_ENV =
process.env.NODE_ENV || 'development');
export const config = (): BuildOptions => {
const define = Object.fromEntries([
['process.env.NODE_ENV', `"${mode}"`],
['process.env.USE_WORKER', '"true"'],
]);
if (DEV_SERVER_URL) {
define['process.env.DEV_SERVER_URL'] = `"${DEV_SERVER_URL}"`;
}
return {
entryPoints: [
resolve(electronDir, './src/main/index.ts'),
resolve(electronDir, './src/preload/index.ts'),
resolve(electronDir, './src/helper/index.ts'),
],
entryNames: '[dir]',
outdir: resolve(electronDir, './dist'),
bundle: true,
target: `node${NODE_MAJOR_VERSION}`,
platform: 'node',
external: [
'electron',
'electron-updater',
'@toeverything/plugin-infra',
'yjs',
'semver',
'tinykeys',
],
define: define,
format: 'cjs',
loader: {
'.node': 'copy',
},
assetNames: '[name]',
treeShaking: true,
sourcemap: 'linked',
};
};

View File

@@ -1,10 +1,11 @@
/* eslint-disable no-async-promise-executor */
import { spawn } from 'node:child_process';
import type { ChildProcessWithoutNullStreams } from 'child_process';
import electronPath from 'electron';
import * as esbuild from 'esbuild';
import { config } from './common.mjs';
import { config } from './common';
// this means we don't spawn electron windows, mainly for testing
const watchMode = process.argv.includes('--watch');
@@ -17,8 +18,7 @@ const stderrFilterPatterns = [
/ExtensionLoadWarning/,
];
/** @type {ChildProcessWithoutNullStreams | null} */
let spawnProcess = null;
let spawnProcess: ChildProcessWithoutNullStreams | null = null;
function spawnOrReloadElectron() {
if (watchMode) {
@@ -33,7 +33,7 @@ function spawnOrReloadElectron() {
spawnProcess = spawn(String(electronPath), ['.']);
spawnProcess.stdout.on('data', d => {
let str = d.toString().trim();
const str = d.toString().trim();
if (str) {
console.log(str);
}
@@ -53,13 +53,13 @@ function spawnOrReloadElectron() {
const common = config();
async function watchLayers() {
return new Promise(async resolve => {
return new Promise<void>(async resolve => {
let initialBuild = false;
const buildContext = await esbuild.context({
...common.layers,
...common,
plugins: [
...(common.layers.plugins ?? []),
...(common.plugins ?? []),
{
name: 'electron-dev:reload-app-on-layers-change',
setup(build) {

View File

@@ -1,10 +1,13 @@
#!/usr/bin/env zx
import 'zx/globals';
import { spawnSync } from 'node:child_process';
import { createRequire } from 'node:module';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import fs from 'fs-extra';
import { glob } from 'glob';
const require = createRequire(import.meta.url);
const __dirname = fileURLToPath(new URL('.', import.meta.url));
const repoRootDir = path.join(__dirname, '..', '..', '..');
const electronRootDir = path.join(__dirname, '..');
@@ -32,24 +35,31 @@ if (releaseVersionEnv && electronPackageJson.version !== releaseVersionEnv) {
}
// copy web dist files to electron dist
if (process.platform === 'win32') {
$.shell = 'powershell.exe';
$.prefix = '';
}
process.env.DISTRIBUTION = 'desktop';
$.env.DISTRIBUTION = 'desktop';
cd(repoRootDir);
const cwd = repoRootDir;
if (!process.env.SKIP_PLUGIN_BUILD) {
await $`yarn -T run build:plugins`;
spawnSync('yarn', ['build:plugins'], {
stdio: 'inherit',
env: process.env,
cwd,
});
}
// step 1: build web (nextjs) dist
// step 1: build web dist
if (!process.env.SKIP_WEB_BUILD) {
await $`yarn nx build @affine/core`;
spawnSync('yarn', ['nx', 'build', '@affine/core'], {
stdio: 'inherit',
env: process.env,
cwd,
});
await $`yarn workspace @affine/electron build`;
spawnSync('yarn', ['workspace', '@affine/electron', 'build'], {
stdio: 'inherit',
env: process.env,
cwd,
});
// step 1.5: amend sourceMappingURL to allow debugging in devtools
await glob('**/*.{js,css}', { cwd: affineCoreOutDir }).then(files => {

View File

@@ -1,9 +1,6 @@
// do not run in your local machine
/* eslint-disable */
const fs = require('node:fs');
const path = require('node:path');
const crypto = require('node:crypto');
/* eslint-enable */
import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
const yml = {
version: process.env.RELEASE_VERSION ?? '0.0.0',
@@ -12,9 +9,9 @@ const yml = {
const generateYml = platform => {
const regex = new RegExp(`^affine-.*-${platform}-.*.(exe|zip|dmg|AppImage)$`);
const files = fs.readdirSync(__dirname).filter(file => regex.test(file));
const files = fs.readdirSync(process.cwd()).filter(file => regex.test(file));
files.forEach(fileName => {
const filePath = path.join(__dirname, './', fileName);
const filePath = path.join(process.cwd(), './', fileName);
try {
const fileData = fs.readFileSync(filePath);
const hash = crypto
@@ -54,5 +51,6 @@ const generateYml = platform => {
fs.writeFileSync(fileName, ymlStr);
};
generateYml('windows');
generateYml('macos');

View File

@@ -1,11 +1,12 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const { z } = require('zod');
const path = require('node:path');
import { z } from 'zod';
const ReleaseTypeSchema = z.enum(['stable', 'beta', 'canary', 'internal']);
const __dirname = fileURLToPath(new URL('.', import.meta.url));
const ROOT = path.resolve(__dirname, '..');
const envBuildType = (process.env.BUILD_TYPE || 'canary').trim().toLowerCase();
@@ -39,15 +40,15 @@ const platform =
? process.argv[process.argv.indexOf('--platform') + 1]
: process.platform;
module.exports = {
ROOT,
export {
arch,
buildType,
productName,
icoPath,
icnsPath,
iconPngPath,
iconUrl,
arch,
icoPath,
platform,
productName,
ROOT,
stableBuild,
};

View File

@@ -11,7 +11,7 @@ import {
platform,
productName,
ROOT,
} from './make-env';
} from './make-env.js';
async function ensureDirectory(dir: string) {
if (await fs.pathExists(dir)) {

View File

@@ -0,0 +1,3 @@
{
"type": "module"
}

View File

@@ -9,7 +9,16 @@
"allowSyntheticDefaultImports": true,
"noEmit": false,
"outDir": "./lib/scripts",
"types": ["node"],
"allowJs": true
},
"include": ["./scripts", "esbuild.main.config.ts", "esbuild.plugin.config.ts"]
"include": [
"./scripts",
"esbuild.main.config.ts",
"esbuild.plugin.config.ts"
],
"ts-node": {
"esm": true,
"experimentalSpecifierResolution": "node"
}
}