This extension can run in a web browser (eg: vscode.dev), but with limited functionality compared to the desktop version.
You can run the Web mode implementation of the extension in the following ways.
See the CONTRIBUTING document.
- To see logs, using the Command Palette search:
Toggle Developer Tools
. Then go to theConsole
tab. In web mode VS Code seems to duplicate log messages, idk how to fix this. - The difference between web mode and Node.js/desktop is that in web mode everything runs in browser environment so certain things like Node.js modules will not be available.
The following steps will result in a Chrome window running with VS Code and the web version of the AWS Toolkit extension installed:
-
(Recommended) To have the Chrome window save your VS Code state after closing it, you need to modify the node module which executes the playwright method that opens it. In
node_modules/@vscode/test-web/out/index.js#openBrowser()
make the following change:Before:
const browser = await browserType.launch({ headless, args, devtools: options.devTools }) const context = await browser.newContext({ viewport: null })
After:
const tempContextDir = path.join(process.cwd(), '.vscode-test-web/aws-toolkit-user-dir') const browser = await browserType.launchPersistentContext(tempContextDir, { headless, args, devtools: options.devTools, viewport: null, }) const context = browser
-
In the
Run & Debug
menu select theExtension (Chrome)
option
Note: To stop the debug session, you need to click the read
Disconnect
button multiple times
Note: Setting breakpoints in VS Code works
By default, we disable CORS in web mode since certain endpoints such as telemetry or auth do not support CORS (at the moment of writing) for the VSCode origin.
In the case you want to enable CORS in the browser to test CORS compatibility do the following:
- In
package.json
find thewebRun
script - Temporarily remove
--browserOption=--disable-web-security
Now when you run the extension in the browser it will do CORS checks.
Running in vscode.dev
The following will explain how to get your latest local development changes running in the actual vscode.dev
. Use this if you want to test on an actual VS Code Web instance.
- Build the extension. We need the Web mode entrypoint file to exist.
- OPTIONAL: Start up your browser with security disabled. Certain functionalities do not support CORS and will fail otherwise.
- On MacOS from the CLI is similar to
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-web-security
- On MacOS from the CLI is similar to
cd
to the extension you want to test inpackages/
. Eg:packages/amazonq/
.- We need to do this since the following command hosts your build from the
cwd
.
- We need to do this since the following command hosts your build from the
- Follow the VS Code documentation for setting up certs, serving your the latest changes, and installing the extension to
vscode.dev
.
The following steps will result in a VSCode Extension window running with the AWS Toolkit extension installed. While it looks the same as a typical VS Code window, in the background it is running in a Browser context.
- In the
Run & Debug
menu run:Extension Tests (web)
NOTE: Tests do not spin up an actual browser window, but if we find a good reason to switch it will require some additional work. The current way does not require dowloading a separate browser like Chromium.
If you need to manage npm modules required for Web mode, such as a browserfied module, see the documentation here.
For example, if I have a Typescript module, myFile.ts
, that imports a module which imports another module (transitive dependency) such as fs-extra
,
when I execute myFile.ts
in the browser it will break due to fs-extra
not being browser compatible.
INFO: A common error is
Cannot read properties of undefined (reading 'native')
caused byfs-extra
It may be difficult to determine which module imported fs-extra
due to a nested chain of transitive dependencies.
As a solution, we can use dependency-cruiser
to generate a dependency diagram
to help us visualize the imports and determine which module is importing a certain module.
- Install the
graphviz
cli, this provides thedot
cli command- Mac:
brew install graphviz
- Others: See documentation
- Mac:
- Temporarily install
dependency-cruiser
- IMPORTANT: You will want to revert this install when done
npm i dependency-cruiser
- Run
npx depcruise {RELATIVE_PATH_TO_FILE} --reaches "{YOUR_MODULE}" --output-type dot | dot -T svg > dependency-graph.svg
- In Web mode, state is not shared between the actual extension code and the unit test code. I.e you cannot modify an exported module variable in the extension code and see that change from the tests.
- However, state stored in
globalThis
is observable from the tests.
When running web tests, the context between the extension code and test code is not shared. Though it is shared in the Node version of the extension.
- Does NOT work in Web mode tests:
- Module code:
export let myGlobal = 'A' function activate() { // Change the exported module variable. myGlobal = 'B' }
- Test code:
// Web unit test import { myGlobal } from '../src/extension.ts' describe('test', function () { it('test', function () { assert.strictEqual(myGlobal, 'B') // Fails in Web (but not Node.js). The value is 'A'. }) })
- Module code:
- DOES work in Web mode tests:
- Module code:
;(globalThis as any).myGlobal = 'A' function activate() { ;(globalThis as any).myGlobal = 'B' }
- Test code:
// Web unit test describe('test', function () { it('test', function () { assert.strictEqual((globalThis as any).myGlobal, 'B') // Passes in Web and Node.js. }) })
- Module code:
The assumption for the behavior is due to how Web Workers work. We (VS Code) use them to run our extension and test code in the browser. The scripts share module exports differently compared to a different environment such as Node.js.
WorkerGlobalScope
- The context of the executing code is contained within itself and is not accessible to other scripts (tests).
- VS Code uses Dedicated Workers since
globalThis
is indicated as aDedicatedWorkerGlobalScope
when debugging globalThis
is one object (that I could find so far) which is shared between our extension and test scripts. A guess to why is that the main script spawns another web worker (for unit tests) and passes on theDedicatedWorkerGlobalScope
. See"Workers can also spawn other workers"
.globalThis
returnsglobal
in Node.js, or aWorkerGlobalScope
in the browser- NOTE:
globalThis
is shared across all of VS Code, including all extensions.