Skip to content

Commit cd49ec0

Browse files
authored
feat(extension): Include workspace bundled deps sourcemaps on dev build (#583)
Closes #576 This PR fixes sourcemap generation for local workspace packages during development, enabling effective debugging in browser DevTools. The issue was that Vite resolved workspace dependencies to their pre-compiled `dist` folders, breaking the sourcemap chain back to the original TypeScript source. This is resolved by adding a conditional `resolve.alias` to the `extension`'s Vite configuration. In development mode, all `@metamask/*` workspace imports are aliased to their src directories. This allows Vite to build the extension from a single, unified source tree, resulting in a complete and accurate sourcemap. Sourcemaps are in-lined because security restrictions on the `chrome-extension://` in web workers prevent the loading of sourcemap files. For production builds, this aliasing is disabled to ensure builds remain fast and optimized. ### Development Workflow Two primary development workflows are now fully supported with sourcemaps: 1. Automatic Browser Launch: - Run `yarn start` from within the packages/extension directory. - This command triggers a development build (build:dev --watch) and launches a Chromium instance with the extension loaded, providing a complete debugging experience with sourcemaps out-of-the-box. 2. Manual Extension Loading: - Run `yarn build:dev` from the root of the monorepo. - This will build all necessary packages in development mode. You can then manually load the extension's dist folder into chrome and still have full sourcemap support. <img width="1673" height="1127" alt="Screenshot 2025-07-24 at 16 08 18" src="https://github.com/user-attachments/assets/0892351f-a985-41c7-bb55-53e1e35a9d9f" /> <img width="1560" height="1282" alt="Screenshot 2025-07-24 at 16 12 29" src="https://github.com/user-attachments/assets/467d4ff8-8830-4603-8a41-d4ddca4c9a3e" />
1 parent 5b49e7e commit cd49ec0

3 files changed

Lines changed: 59 additions & 30 deletions

File tree

README.md

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,16 @@ For detailed information on how to use the OCAP Kernel, please refer to the [OCA
1010

1111
You can launch a browser-based Kernel Control Panel to interact with and manage vats:
1212

13-
1. Navigate to the extension package:
14-
1513
```bash
16-
cd packages/extension
14+
yarn workspace @ocap/extension run start
1715
```
1816

19-
2. Start the development server:
20-
21-
```bash
22-
yarn start
23-
```
17+
This will:
2418

25-
3. This will:
26-
- Launch a development server serving the extension
27-
- Set up a default cluster configuration
28-
- Serve sample vat bundles
29-
- Provide a UI for managing and interacting with the kernel and vats
19+
- Launch a development server serving the extension
20+
- Set up a default cluster configuration
21+
- Serve sample vat bundles
22+
- Provide a UI for managing and interacting with the kernel and vats
3023

3124
The control panel allows you to:
3225

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
],
1414
"scripts": {
1515
"build": "yarn build:source && yarn build:special",
16+
"build:dev": "yarn build:source && yarn build:special:dev",
1617
"build:clean": "yarn clean && yarn build",
1718
"build:docs": "yarn workspaces foreach --all --exclude @ocap/monorepo --exclude @ocap/extension --parallel --interlaced --verbose run build:docs",
1819
"build:source": "ts-bridge --project tsconfig.build.json --verbose",
1920
"build:special": "yarn workspace @ocap/vite-plugins run build && yarn workspace @metamask/kernel-shims run build && yarn workspace @metamask/kernel-browser-runtime run build:vite && yarn workspace @metamask/kernel-ui run build && yarn workspace @ocap/extension run build && yarn workspace @ocap/kernel-test run build",
21+
"build:special:dev": "yarn workspace @ocap/vite-plugins run build && yarn workspace @metamask/kernel-shims run build && yarn workspace @metamask/kernel-browser-runtime run build:vite && yarn workspace @metamask/kernel-ui run build && yarn workspace @ocap/extension run build:dev && yarn workspace @ocap/kernel-test run build",
2022
"bundle": "node ./scripts/bundle-vat.js",
2123
"changelog:update": "yarn workspaces foreach --all --no-private --parallel --interlaced --verbose run changelog:update",
2224
"changelog:validate": "yarn workspaces foreach --all --no-private --parallel --interlaced --verbose run changelog:validate",

packages/extension/vite.config.ts

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,29 @@ import {
99
} from '@ocap/vite-plugins';
1010
import react from '@vitejs/plugin-react';
1111
import path from 'path';
12+
import { fileURLToPath } from 'url';
1213
import { defineConfig } from 'vite';
1314
import { checker as viteChecker } from 'vite-plugin-checker';
1415
import { viteStaticCopy } from 'vite-plugin-static-copy';
1516
import type { Target } from 'vite-plugin-static-copy';
1617

18+
import * as pkg from './package.json';
1719
import {
18-
rootDir,
1920
kernelBrowserRuntimeSrcDir,
2021
outDir,
2122
sourceDir,
2223
trustedPreludes,
2324
} from './scripts/build-constants.mjs';
2425

25-
/**
26-
* Files that need to be statically copied to the destination directory.
27-
* Paths are relative from the project root directory.
28-
*/
26+
const dirname = path.dirname(fileURLToPath(import.meta.url));
27+
const rootDir = path.resolve(dirname, '..', '..');
2928
const staticCopyTargets: readonly (string | Target)[] = [
3029
// The extension manifest
31-
path.resolve(sourceDir, 'manifest.json'),
30+
'packages/extension/src/manifest.json',
3231
// Trusted prelude-related
33-
path.resolve(sourceDir, 'env/dev-console.js'),
34-
path.resolve(sourceDir, 'env/background-trusted-prelude.js'),
35-
path.resolve(rootDir, 'kernel-shims/dist/endoify.js'),
32+
'packages/extension/src/env/dev-console.js',
33+
'packages/extension/src/env/background-trusted-prelude.js',
34+
'packages/kernel-shims/dist/endoify.js',
3635
];
3736

3837
// https://vitejs.dev/config/
@@ -45,13 +44,17 @@ export default defineConfig(({ mode }) => {
4544

4645
return {
4746
root: rootDir,
48-
47+
resolve: {
48+
alias: isDev ? getPackageDevAliases(pkg.dependencies) : [],
49+
},
4950
build: {
5051
assetsDir: '',
5152
emptyOutDir: true,
5253
// Disable Vite's module preload, which may cause SES-dependent code to run before lockdown.
5354
modulePreload: false,
5455
outDir,
56+
minify: !isDev,
57+
sourcemap: isDev ? 'inline' : false,
5558
rollupOptions: {
5659
input: {
5760
background: path.resolve(sourceDir, 'background.ts'),
@@ -71,14 +74,7 @@ export default defineConfig(({ mode }) => {
7174
assetFileNames: '[name].[ext]',
7275
},
7376
},
74-
...(isDev
75-
? {
76-
minify: false,
77-
sourcemap: 'inline',
78-
}
79-
: {}),
8077
},
81-
8278
plugins: [
8379
react(),
8480
htmlTrustedPrelude(),
@@ -118,3 +114,41 @@ export default defineConfig(({ mode }) => {
118114
],
119115
};
120116
});
117+
118+
/**
119+
* Generates Vite aliases for workspace packages to enable proper sourcemap handling in development.
120+
*
121+
* By default, Vite resolves workspace packages to their `dist` folders, which breaks the
122+
* sourcemap chain. These aliases force Vite to use the original TypeScript source from the
123+
* `src` directories instead, ensuring a complete and accurate sourcemap for debugging.
124+
*
125+
* A special alias for `@metamask/kernel-ui/styles.css` is included to resolve the
126+
* built stylesheet correctly from its `dist` folder.
127+
*
128+
* @param deps - The dependencies object from the `package.json` file.
129+
* @returns An array of Vite alias objects for development mode.
130+
*/
131+
function getPackageDevAliases(
132+
deps: Record<string, string> = {},
133+
): { find: string; replacement: string }[] {
134+
const workspacePackages = Object.keys(deps)
135+
.filter(
136+
(name) => name.startsWith('@metamask/') && deps[name] === 'workspace:^',
137+
)
138+
.map((pkgName) => ({
139+
find: pkgName,
140+
replacement: path.resolve(
141+
rootDir,
142+
`packages/${pkgName.replace('@metamask/', '')}/src`,
143+
),
144+
}));
145+
146+
return [
147+
// Special alias for kernel-ui styles, which are in dist
148+
{
149+
find: '@metamask/kernel-ui/styles.css',
150+
replacement: path.resolve(rootDir, 'packages/kernel-ui/dist/styles.css'),
151+
},
152+
...workspacePackages,
153+
];
154+
}

0 commit comments

Comments
 (0)