Fix debugging in Dev Tools

This commit is contained in:
Fedor Indutny 2026-04-17 08:10:08 -07:00 committed by GitHub
parent 92d6c38d07
commit 40a9c9387b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 77 additions and 20 deletions

View File

@ -0,0 +1,37 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { join } from 'node:path';
import { pathToFileURL } from 'node:url';
import { protocol, net } from 'electron';
import { isPathInside } from '../ts/util/isPathInside.node.ts';
import { getAppRootDir } from '../ts/util/appRootDir.main.ts';
type DevelopmentServiceOptions = Readonly<{
isDevelopment: boolean;
}>;
export function start({ isDevelopment }: DevelopmentServiceOptions): void {
if (!isDevelopment) {
protocol.handle('bundles', () => {
return new Response('Unavailable in production', {
status: 404,
});
});
return;
}
const BUNDLES_DIR = join(getAppRootDir(), 'bundles');
// Serve source maps
protocol.handle('bundles', req => {
const url = new URL(req.url);
const path = join(BUNDLES_DIR, url.pathname.slice(1));
if (!isPathInside(path, BUNDLES_DIR)) {
throw new Error(`Invalid source map request: ${path}`);
}
return net.fetch(pathToFileURL(path).toString());
});
}

View File

@ -86,6 +86,7 @@ import { SystemTraySettingCache } from './SystemTraySettingCache.node.ts';
import { OptionalResourceService } from './OptionalResourceService.main.ts';
import { EmojiService } from './EmojiService.main.ts';
import { AssetService } from './AssetService.main.ts';
import * as DevelopmentService from './DevelopmentService.main.ts';
import {
SystemTraySetting,
shouldMinimizeToSystemTray,
@ -2092,6 +2093,9 @@ app.on('ready', async () => {
);
await EmojiService.create(resourceService);
AssetService.create(resourceService);
DevelopmentService.start({
isDevelopment: development && !app.isPackaged,
});
if (!resolvedTranslationsLocale) {
preferredSystemLocales = resolveCanonicalLocales(

View File

@ -16,7 +16,7 @@
http-equiv="Content-Security-Policy"
content="default-src 'none';
child-src 'self';
connect-src 'self' https: wss: attachment:;
connect-src 'self' https: wss: attachment: bundles:;
font-src 'self' asset:;
form-action 'self';
frame-src 'none';

View File

@ -23,7 +23,7 @@ try {
}
}
const source = readFileSync(srcPath);
const source = readFileSync(srcPath, 'utf8');
window.preloadCompileStartTime = Date.now();
@ -38,27 +38,22 @@ window.preloadCompileStartTime = Date.now();
// path-independent value for reproducibility, and otherwise use full absolute
// path in the packaged app.
const filename = process.env.GENERATE_PRELOAD_CACHE
? 'preload.bundle.js'
? 'bundles/preload/main.js'
: srcPath;
const script = new Script(
`(function(require, __dirname, exports){${source.toString()}})`,
{
filename,
lineOffset: 0,
cachedData,
importModuleDynamically: constants.USE_MAIN_CONTEXT_DEFAULT_LOADER,
}
);
// Note: we wrap with (function(require, __dirname, exports){}) in
// `rolldown.config.ts` to preserve correct offsets in the sourcemap.
const script = new Script(source, {
filename,
lineOffset: 0,
cachedData,
importModuleDynamically: constants.USE_MAIN_CONTEXT_DEFAULT_LOADER,
});
const { cachedDataRejected } = script;
const fn = script.runInThisContext({
filename,
lineOffset: 0,
columnOffset: 0,
displayErrors: true,
importModuleDynamically: constants.USE_MAIN_CONTEXT_DEFAULT_LOADER,
});
// See `scripts/generate-preload-cache.mjs`

View File

@ -72,7 +72,7 @@ const defaults = {
plugins: [
{
name: 'NODE_ENV',
async transform(code, id) {
transform(code, id) {
if (id.endsWith('.json')) {
return;
}
@ -82,13 +82,12 @@ const defaults = {
return;
}
const { code: newCode } = await transform(id, code, {
return transform(id, code, {
define: {
'process.env.NODE_ENV': isProd ? '"production"' : '"development"',
},
sourcemap: !isProd,
});
return { code: newCode };
},
},
],
@ -101,6 +100,28 @@ const defaults = {
generatedCode: {
symbols: false,
},
sourcemap: !isProd,
sourcemapBaseUrl: 'bundles:///',
postBanner: ({ fileName }) => {
// See preload.wrapper.ts
if (fileName === 'preload/main.js') {
return '(function(require, __dirname, exports){';
}
return '';
},
postFooter: ({ fileName }) => {
const lines = new Array<string>();
// See preload.wrapper.ts
if (fileName === 'preload/main.js') {
lines.push('})');
}
lines.push(`//# sourceURL=bundles:///${fileName}`);
return lines.join('\n');
},
},
watch: {
clearScreen: false,