Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions apps/desktop/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# For electron-builder
# https://github.com/electron-userland/electron-builder/issues/6289#issuecomment-1042620422
shamefully-hoist=true
163 changes: 78 additions & 85 deletions apps/desktop/electron-builder.ts
Original file line number Diff line number Diff line change
@@ -1,90 +1,83 @@
import { Configuration, TargetConfiguration } from 'electron-builder';

/**
* Electron Builder Configuration
* @see https://www.electron.build/configuration/configuration
* @see https://www.electron.build/#documentation
*/

import { join } from "node:path";
import type { Configuration } from "electron-builder";
import pkg from "./package.json";

const currentYear = new Date().getFullYear();
const author = pkg.author?.name ?? pkg.author;
const authorInKebabCase = author.replace(/\s+/g, "-");
const appId = `com.${authorInKebabCase}.${pkg.name}`.toLowerCase();

const config: Configuration = {
appId,
productName: pkg.displayName,
copyright: `Copyright © ${currentYear} — ${author}`,
electronVersion: pkg.devDependencies.electron.replace(/^\^/, ""),

// Directories
directories: {
output: "release",
buildResources: join(pkg.resources, "build"),
},

files: [
"dist/**/*",
"package.json",
{
from: pkg.resources,
to: "resources",
filter: ["**/*"],
},
"!node_modules/@superset/**/*",
],

// Build optimization
npmRebuild: false,
buildDependenciesFromSource: false,
nodeGypRebuild: false,

// macOS
mac: {
icon: join(pkg.resources, "build/icons/icon.icns"),
category: "public.app-category.utilities",
target: [
{
target: "default",
arch: ["universal"],
},
],
hardenedRuntime: true,
gatekeeperAssess: false,
notarize: false,
},

// Deep linking protocol
protocols: {
name: pkg.displayName,
schemes: ["superset"],
},

// Linux
linux: {
icon: join(pkg.resources, "build/icons"),
category: "Utility",
synopsis: pkg.description,
target: ["AppImage", "deb"],
},

// Windows
win: {
icon: join(pkg.resources, "build/icons/icon.ico"),
target: [
{
target: "nsis",
arch: ["x64"],
},
],
},

// NSIS installer (Windows)
nsis: {
oneClick: false,
allowToChangeInstallationDirectory: true,
},
appId: 'dev.onlook.studio',
asar: true,
directories: {
output: 'release/${version}',
},
files: ['dist-electron', 'dist'],
extraResources: [
{
from: 'resources/bun',
to: 'bun',
filter: ['**/*'],
},
],
mac: {
artifactName: '${productName}-${arch}.${ext}',
category: 'public.app-category.developer-tools',
hardenedRuntime: true,
gatekeeperAssess: false,
target: [
{
target: 'dmg',
arch: ['x64', 'arm64'],
} as TargetConfiguration,
{
target: 'zip',
arch: ['x64', 'arm64'],
} as TargetConfiguration,
],
},
win: {
target: [
{
target: 'nsis',
arch: ['x64'],
} as TargetConfiguration,
],
artifactName: '${productName}-setup.${ext}',
azureSignOptions: {
publisherName: 'On Off, Inc',
certificateProfileName: 'public-trust-onlook',
codeSigningAccountName: 'trusted-onlook',
endpoint: 'https://eus.codesigning.azure.net',
timestampDigest: 'SHA256',
timestampRfc3161: 'http://timestamp.acs.microsoft.com',
},
},
linux: {
target: [
{
target: 'AppImage',
arch: ['x64', 'arm64'],
} as TargetConfiguration,
{
target: 'deb',
arch: ['x64', 'arm64'],
} as TargetConfiguration,
],
artifactName: '${productName}-${arch}.${ext}',
category: 'Utility',
executableName: 'Onlook',
icon: 'build/icon.icns',
protocols: [
{
name: 'onlook',
schemes: ['onlook'],
},
],
},
nsis: {},
publish: {
provider: 'github',
owner: 'onlook-dev',
repo: 'onlook',
},
Comment thread
coderabbitai[bot] marked this conversation as resolved.
};

export default config;
export default config;
213 changes: 101 additions & 112 deletions apps/desktop/electron.vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,112 +1,101 @@
import { dirname, normalize, resolve } from "node:path";
import tailwindcss from "@tailwindcss/vite";
import reactPlugin from "@vitejs/plugin-react";
import { codeInspectorPlugin } from "code-inspector-plugin";
import { config } from "dotenv";
import { defineConfig, externalizeDepsPlugin } from "electron-vite";
import injectProcessEnvPlugin from "rollup-plugin-inject-process-env";
import tsconfigPathsPlugin from "vite-tsconfig-paths";
import { main, resources } from "./package.json";
import { getPortSync } from "./src/main/lib/port-manager";

// Load .env from monorepo root
// Use override: true to ensure .env values take precedence over inherited env vars
config({ path: resolve(__dirname, "../../.env"), override: true });

// Extract base output directory (dist/) from main path
const devPath = normalize(dirname(main)).split(/\/|\\/g)[0];

const tsconfigPaths = tsconfigPathsPlugin({
projects: [resolve("tsconfig.json")],
});

export default defineConfig({
main: {
plugins: [
tsconfigPaths,
externalizeDepsPlugin({
exclude: ["@superset/*", "electron-store"],
}),
],

build: {
rollupOptions: {
input: {
index: resolve("src/main/index.ts"),
},

output: {
dir: resolve(devPath, "main"),
},
},
},
resolve: {
alias: {},
},
},

preload: {
plugins: [
tsconfigPaths,
externalizeDepsPlugin({
exclude: ["trpc-electron"],
}),
],

build: {
outDir: resolve(devPath, "preload"),
rollupOptions: {
input: {
index: resolve("src/preload/index.ts"),
},
},
},
},

renderer: {
define: {
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV),
"process.platform": JSON.stringify(process.platform),
"import.meta.env.ENABLE_NEW_UI": JSON.stringify(
process.env.ENABLE_NEW_UI || "false",
),
"import.meta.env.DEV_SERVER_PORT": JSON.stringify(getPortSync()),
},

server: {
port: getPortSync(),
strictPort: false, // Allow fallback to next available port
},

plugins: [
tsconfigPaths,
tailwindcss(),
reactPlugin(),

codeInspectorPlugin({
bundler: "vite",
hotKeys: ["altKey"],
hideConsole: true,
}),
],

publicDir: resolve(resources, "public"),

build: {
outDir: resolve(devPath, "renderer"),

rollupOptions: {
plugins: [
injectProcessEnvPlugin({
NODE_ENV: "production",
platform: process.platform,
}),
],

input: {
index: resolve("src/renderer/index.html"),
},
},
},
},
});
import react from '@vitejs/plugin-react';
import { cpSync, rmSync } from 'node:fs';
import path from 'node:path';
import { defineConfig } from 'vite';
import electron from 'vite-plugin-electron/simple';
import pkg from './package.json';

// https://vitejs.dev/config/
export default defineConfig(({ command }) => {
rmSync('dist-electron', {
recursive: true,
force: true,
});
const isServe = command === 'serve';
const isBuild = command === 'build';
const sourcemap = isServe || !!process.env.VSCODE_DEBUG;

try {
cpSync('resources', 'dist-electron/main/resources', { recursive: true });
console.log('✓ Resources folder copied to dist-electron');
} catch (err) {
console.error('Failed to copy resources folder:', err);
}

return {
resolve: {
alias: {
'@': path.join(__dirname, 'src'),
common: path.join(__dirname, 'common'),
},
},
optimizeDeps: {
exclude: ['node_modules/.vite/deps'],
},
plugins: [
react(),
electron({
main: {
// Shortcut of `build.lib.entry`
entry: 'electron/main/index.ts',
onstart(args) {
if (process.env.VSCODE_DEBUG) {
console.log(
/* For `.vscode/.debug.script.mjs` */ '[startup] Electron App',
);
} else {
args.startup();
}
},
vite: {
build: {
sourcemap: sourcemap ? 'inline' : undefined,
minify: isBuild,
outDir: 'dist-electron/main',
rollupOptions: {
external: Object.keys(
'dependencies' in pkg ? pkg.dependencies : {},
),
},
},
},
},
preload: {
input: {
index: 'electron/preload/browserview/index.ts',
webview: 'electron/preload/webview/index.ts',
},
vite: {
build: {
sourcemap: sourcemap ? 'inline' : undefined,
minify: isBuild,
outDir: 'dist-electron/preload',
rollupOptions: {
external: Object.keys(pkg.dependencies ?? {}),
output: {
format: 'cjs',
entryFileNames: '[name].js',
inlineDynamicImports: false,
},
},
},
},
},
// Ployfill the Electron and Node.js API for Renderer process.
// If you want use Node.js in Renderer process, the `nodeIntegration` needs to be enabled in the Main process.
// See 👉 https://github.com/electron-vite/vite-plugin-electron-renderer
renderer: {},
}),
],
server: process.env.VSCODE_DEBUG
? (() => {
const url = new URL(pkg.debug.env.VITE_DEV_SERVER_URL);
return {
host: url.hostname,
port: +url.port,
};
})()
: undefined,
clearScreen: false,
};
});
Loading
Loading