Skip to content

Commit

Permalink
feat(main-app): change main app to esbuild (#1678)
Browse files Browse the repository at this point in the history
* feat(main-app): change main app to esbuild

Co-authored-by: hyrious <hyrious@outlook.com>

* feat(main-app): add replace import meta plugin

* Update desktop/main-app/scripts/esbuild/paths.ts

Co-authored-by: Black-Hole <158blackhole@gmail.com>

* update lockfile

* rebase main

Co-authored-by: Cyberhan123 <255542417@qq.com>
Co-authored-by: Black-Hole <158blackhole@gmail.com>
  • Loading branch information
3 people committed Sep 20, 2022
1 parent a4882b6 commit 66b2a04
Show file tree
Hide file tree
Showing 11 changed files with 261 additions and 42 deletions.
4 changes: 4 additions & 0 deletions cspell.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ module.exports = {
"submenu",
"unhide",
"nsis",
"respawn",

// file type
"avif",
Expand Down Expand Up @@ -162,6 +163,9 @@ module.exports = {
// vscode
"dbaeumer",
"keystyle",

// esbuild config
"metafile",
],
flagWords: ["fuck", "bitch", "asshole", "bullshit", "crap", "suck", "wtf"],
dictionaries: [
Expand Down
10 changes: 8 additions & 2 deletions desktop/main-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@
"url": "https://github.com/netless-io/flat"
},
"scripts": {
"start": "cross-env NODE_ENV=development webpack --config webpack/webpack.dev.js",
"_start": "cross-env NODE_ENV=development webpack --config webpack/webpack.dev.js",
"start:cn": "cross-env FLAT_REGION=CN pnpm start",
"start:us": "cross-env FLAT_REGION=US pnpm start",
"build": "cross-env NODE_ENV=production webpack --config webpack/webpack.prod.js",
"_start:esbuild": "esbuild-dev --cjs scripts/esbuild/esbuild.dev.ts",
"start": "cross-env NODE_ENV=development pnpm run _start:esbuild",
"_build": "cross-env NODE_ENV=production webpack --config webpack/webpack.prod.js",
"build:cn": "cross-env FLAT_REGION=CN pnpm build",
"build:us": "cross-env FLAT_REGION=US pnpm build",
"_build:esbuild": "esbuild-dev --cjs scripts/esbuild/esbuild.prod.ts",
"build": "cross-env NODE_ENV=production pnpm run _build:esbuild",
"build:debug": "cross-env FLAT_DEBUG=debug webpack --config webpack/webpack.debug.js",
"pack:win": "node ./scripts/pack win",
"pack:mac": "node ./scripts/pack mac",
Expand All @@ -28,7 +32,9 @@
"_launch:electron": "node --trace-uncaught ./scripts/launch/electron.js"
},
"devDependencies": {
"@types/dotenv-flow": "^3.2.0",
"@types/webpack-env": "^1.16.3",
"dotenv-flow": "^3.2.0",
"dotenv-flow-webpack": "^1.1.0",
"electron": "12.0.15",
"electron-builder": "^23.0.3",
Expand Down
15 changes: 15 additions & 0 deletions desktop/main-app/scripts/esbuild/esbuild.common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { autoChooseConfig } from "../../../../scripts/utils/auto-choose-config";
import pkg from "../../package.json";
import dotEnvFlowPlugin from "./plugin/dotEnvFlowPlugin";
import { replaceImportMeta } from "./plugin/replaceImportMeta";

export const external = Object.keys(pkg.dependencies);

export const dotenvPlugin = dotEnvFlowPlugin({
path: autoChooseConfig(),
system_vars: true,
default_node_env: "development",
silent: true,
});

export const replaceMetaPlugin = replaceImportMeta();
52 changes: 52 additions & 0 deletions desktop/main-app/scripts/esbuild/esbuild.dev.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { ChildProcess, spawn } from "child_process";
import esbuild from "esbuild";
import { dotenvPlugin, external, replaceMetaPlugin } from "./esbuild.common";
import * as paths from "./paths";

let child: ChildProcess | undefined;
const respawn = () => {
if (child) {
child.kill("SIGTERM");
}
child = spawn("pnpm", ["electron", paths.dist], { stdio: "inherit" });
};

const buildPreload = esbuild.build({
entryPoints: [paths.preloadPath],
bundle: true,
platform: "browser",
target: "chrome89",
external: [...external, "electron", "os", "path"],
outfile: paths.preloadDist,
watch: true,
});

const buildMain = esbuild.build({
entryPoints: [paths.entryFile],
bundle: true,
platform: "node",
target: "node14",
external: [...external, "electron", "electron-devtools-vendor"],
sourcemap: true,
outfile: paths.dist,
watch: {
onRebuild(error) {
if (error) {
console.error("watch build failed:", error);
} else {
respawn();
}
},
},
plugins: [dotenvPlugin, replaceMetaPlugin],
});

const allDone = Promise.all([buildPreload, buildMain]);

const stop = () =>
allDone.then(rs => rs.forEach(r => r.stop && r.stop())).catch(() => process.exit(1));

process.on("SIGINT", stop);
process.on("SIGTERM", stop);

allDone.then(respawn);
26 changes: 26 additions & 0 deletions desktop/main-app/scripts/esbuild/esbuild.prod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import esbuild from "esbuild";
import { dotenvPlugin, external } from "./esbuild.common";
import * as paths from "./paths";

const buildPreload = esbuild.build({
entryPoints: [paths.preloadPath],
bundle: true,
platform: "browser",
target: "chrome89",
external: [...external, "electron", "os", "path"],
outfile: paths.preloadDist,
plugins: [dotenvPlugin],
});

const buildMain = esbuild.build({
entryPoints: [paths.entryFile],
bundle: true,
platform: "node",
target: "node14",
external: [...external, "electron", "electron-devtools-vendor"],
sourcemap: true,
outfile: paths.dist,
plugins: [dotenvPlugin],
});

Promise.all([buildPreload, buildMain]).catch(() => process.exit(1));
9 changes: 9 additions & 0 deletions desktop/main-app/scripts/esbuild/paths.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import path from "path";

const resolvePath = (...relativePath: string[]): string =>
path.resolve(__dirname, "..", "..", ...relativePath);

export const dist = resolvePath("dist", "main.js");
export const preloadDist = resolvePath("dist", "preload.js");
export const entryFile = resolvePath("src", "index.ts");
export const preloadPath = resolvePath("src", "preload.ts");
58 changes: 58 additions & 0 deletions desktop/main-app/scripts/esbuild/plugin/dotEnvFlowPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Plugin, PluginBuild } from "esbuild";
import dotenvFlow, { DotenvConfigOptions } from "dotenv-flow";

function parseWithEnvObject(orgEnv: Record<string, string | undefined>): Record<string, string> {
return Reflect.ownKeys(orgEnv)
?.map(item => {
const result: Record<string, any> = {};
if (typeof item === "string" && orgEnv?.[item]) {
result[`process.env.${item}`] = JSON.stringify(orgEnv?.[item]);
}
return result;
})
?.reduce((prev, cur) => {
return {
...prev,
...cur,
};
}, {});
}

// Configuration define refer to https://github.com/kerimdzhanov/dotenv-flow-webpack
type DotEnvPluginOptionsType = Omit<DotenvConfigOptions, "purge_dotenv"> & {
system_vars?: boolean;
};

type DotEnvPluginType = (options: DotEnvPluginOptionsType) => Plugin;

const dotEnvFlowPlugin: DotEnvPluginType = options => {
return {
name: "DotEnvFlow",
setup(build: PluginBuild) {
let sysEnvList = {};

const esbuildOptions = build.initialOptions;

const result = dotenvFlow.config(options);

if (result.error) {
console.warn("esbuild dotenvFlow throw error:", result.error);
return;
}

if (options?.system_vars) {
sysEnvList = parseWithEnvObject(process.env);
}

const configEnvList = parseWithEnvObject(result?.parsed || {});

esbuildOptions.define = {
...esbuildOptions?.define,
...sysEnvList,
...configEnvList,
};
},
};
};

export default dotEnvFlowPlugin;
37 changes: 37 additions & 0 deletions desktop/main-app/scripts/esbuild/plugin/replaceImportMeta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Plugin } from "esbuild";
import { readFile } from "fs-extra";
import { dirname } from "path";
import { pathToFileURL } from "url";

export interface ReplaceImportMetaOptions {
/**
* Passed to `onLoad()`.
* @default /\.[jt]s$/
*/
filter?: RegExp;
}

/**
* Replace `import.meta.url` and `__dirname`, `__filename` with absolute path.
* Taken from https://github.com/vitejs/vite/blob/main/packages/vite/src/node/config.ts
*/
export function replaceImportMeta(options: ReplaceImportMetaOptions = {}): Plugin {
const filter = options.filter ?? /\.[jt]s$/;

return {
name: "replace-import-meta",
setup({ onLoad }) {
onLoad({ filter }, async args => {
const contents = await readFile(args.path, "utf8");
const import_meta_url = JSON.stringify(pathToFileURL(args.path).href);
return {
loader: "default",
contents: contents
.replace(/\bimport\.meta\.url\b/g, import_meta_url)
.replace(/\b__dirname\b/g, JSON.stringify(dirname(args.path)))
.replace(/\b__filename\b/g, JSON.stringify(args.path)),
};
});
},
};
}
4 changes: 2 additions & 2 deletions desktop/main-app/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"compilerOptions": {
"target": "es2017",
"module": "CommonJS",
"lib": ["es2017", "DOM"]
"lib": ["es2017", "DOM"],
},
"include": ["src/**/*.ts", "typings/*.ts"]
"include": ["src/**/*.ts", "typings/*.ts", "scripts/**/*.ts"]
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"devDependencies": {
"@commitlint/cli": "^17.0.0",
"@commitlint/config-angular": "^17.0.0",
"@hyrious/esbuild-dev": "^0.7.6",
"@hyrious/esbuild-dev": "^0.8.3",
"@netless/eslint-plugin": "^2.0.0",
"@types/fs-extra": "^9.0.13",
"@types/lodash-es": "^4.17.6",
Expand Down

0 comments on commit 66b2a04

Please sign in to comment.