Skip to content

Commit

Permalink
feat(@lexical/devtools): Added basic extension scaffolding
Browse files Browse the repository at this point in the history
Includes:
- Extension with TS/React support
- HMR for extension panels and fast reload for other configs
- Dev mode with browser auto-start with dedicated profile
  • Loading branch information
StyleT committed Mar 20, 2024
1 parent e3615cd commit b0105b1
Show file tree
Hide file tree
Showing 20 changed files with 9,890 additions and 25,704 deletions.
35,263 changes: 9,559 additions & 25,704 deletions package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
26 changes: 26 additions & 0 deletions packages/lexical-devtools/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
.output
stats.html
stats-*.json
.wxt
web-ext.config.ts

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
22 changes: 22 additions & 0 deletions packages/lexical-devtools/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Lexical DevTools browser extension

This is the source code for the Lexical DevTools browser extension.

## Local development

Lexical DevTools extension uses [WXT](https://wxt.dev/) framework to simplify development. Please refer to [WXT Development Guide](https://wxt.dev/guide/development.html) for comprehensive documentation.

**TLDR:**
```bash
$ npm run dev
# In browser: Alt+R to force reload extension
```

## Design

This extension follows typical [Browser DevTools architecture](https://developer.chrome.com/docs/extensions/how-to/devtools/extend-devtools) that includes sereral independent contexts that communicate via events or extension APIs.

<figure align="center">
<img src="./docs/architecture-diagram.png" alt="DevTools extension architecture" width="526">
<figcaption>DevTools extension architecture.</figcaption>
</figure>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions packages/lexical-devtools/entrypoints/background.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
export default defineBackground(() => {
// eslint-disable-next-line no-console
console.log('Hello from Lexical DevTools extension content script.', {
id: browser.runtime.id,
});
});
14 changes: 14 additions & 0 deletions packages/lexical-devtools/entrypoints/content.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
export default defineContentScript({
main() {
// eslint-disable-next-line no-console
console.log('Hello from Lexical DevTools extension content script.');
},
matches: ['*://*.lexical.dev/*'],
});
20 changes: 20 additions & 0 deletions packages/lexical-devtools/entrypoints/popup/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}

.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}

.card {
padding: 2em;
}
35 changes: 35 additions & 0 deletions packages/lexical-devtools/entrypoints/popup/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import './App.css';

import {useState} from 'react';
import * as React from 'react';

import lexicalLogo from '/lexical.svg';

function App() {
const [count, setCount] = useState(0);

return (
<>
<div>
<a href="https://lexical.dev" target="_blank">
<img src={lexicalLogo} className="logo" alt="Lexical logo" />
</a>
</div>
<div className="card">
<button onClick={() => setCount((c) => c + 1)}>count is {count}</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
</>
);
}

export default App;
13 changes: 13 additions & 0 deletions packages/lexical-devtools/entrypoints/popup/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Lexical DevTools</title>
<meta name="manifest.type" content="browser_action" />
</head>
<body>
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
</body>
</html>
19 changes: 19 additions & 0 deletions packages/lexical-devtools/entrypoints/popup/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import './style.css';

import React from 'react';
import ReactDOM from 'react-dom/client';

import App from './App.tsx';

ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
69 changes: 69 additions & 0 deletions packages/lexical-devtools/entrypoints/popup/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;

color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;

font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}

a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}

body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}

h1 {
font-size: 3.2em;
line-height: 1.1;
}

button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}

@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}
29 changes: 29 additions & 0 deletions packages/lexical-devtools/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@lexical/devtools",
"description": "Lexical DevTools browser extension",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "wxt",
"dev:firefox": "wxt -b firefox",
"build": "wxt build",
"build:firefox": "wxt build -b firefox",
"zip": "wxt zip",
"zip:firefox": "wxt zip -b firefox",
"compile": "tsc --noEmit",
"postinstall": "wxt prepare"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.2.46",
"@types/react-dom": "^18.2.18",
"@vitejs/plugin-react": "^4.2.1",
"typescript": "^5.3.3",
"wxt": "^0.17.0",
"vite": "^5.2.2"
}
}
Binary file added packages/lexical-devtools/public/icon/128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/lexical-devtools/public/icon/16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/lexical-devtools/public/icon/32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/lexical-devtools/public/icon/48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/lexical-devtools/public/lexical.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions packages/lexical-devtools/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "./.wxt/tsconfig.json",
"compilerOptions": {
"allowImportingTsExtensions": true,
"jsx": "react-jsx"
}
}
61 changes: 61 additions & 0 deletions packages/lexical-devtools/wxt.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import react from '@vitejs/plugin-react';
import * as path from 'path';
import {defineConfig} from 'wxt';

// See https://wxt.dev/api/config.html
export default defineConfig({
manifest: (configEnv) => {
const manifestConf = {
icons: {
128: '/icon/128.png',
16: '/icon/16.png',
32: '/icon/32.png',
48: '/icon/48.png',
},
};

if (configEnv.mode === 'development') {
// When building the local development version of the
// extension we want to be able to have a stable extension ID
// for the local build (in order to be able to reliably detect
// duplicate installations of DevTools).
// By specifying a key in the built manifest.json file,
// we can make it so the generated extension ID is stable.
// For more details see the docs here: https://developer.chrome.com/docs/extensions/reference/manifest/key
// Generated via:
// $ openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -out key.pem # private key
// $ openssl rsa -in key.pem -pubout -outform DER | openssl base64 -A # this key below (strip % at the end)
// $ openssl rsa -in key.pem -pubout -outform DER | shasum -a 256 | head -c32 | tr 0-9a-f a-p # extension ID
// @ts-expect-error https://github.com/wxt-dev/wxt/issues/521#issuecomment-1978147707
manifestConf.key =
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAve7nOT9MtnECslFqKw5x0a/OvR/ZzsDBvcR3SIpQg446O7tKwFZTOQWgmceKZJAPT03Ztwdj7qJfAteSwaW4Aeoo6gK5BU7lAAAXeZNhzmuLSJhE4eu8KVDwck16iEx1C/IBKCypM+7H1wjwSVsjGpij2EDiH4Pw/aJ9LLRia7LO3xXTQTYzaJCzx1A+5JiFo5Y9tTtORdyFV/5bfaxibentXNxm52sj3spBe3wC7BuNoYmto9YdKhYk8Xsvs0u8tC7lRae9h57flLCmqPTi9ho4PkJXs4v/okxtGN2Lhwf3Az3ws1LAUqzGJrNK598IRU70a5ONtqXUc3vdGVJxtwIDAQAB';
}

return manifestConf;
},
runner: {
chromiumArgs: [
'--auto-open-devtools-for-tabs',
// Open chrome://version to validate it works
// We use this instead of chromiumProfile because of https://github.com/wxt-dev/wxt/issues/366
`--user-data-dir=${path.join(__dirname, '.browser-profiles/chromium')}`,
'--hide-crash-restore-bubble',
],
startUrls: [
'https://playground.lexical.dev/',
// Doesn't work due to https://github.com/mozilla/web-ext/pull/2774
// 'chrome://inspect/#service-workers',
// 'chrome://serviceworker-internals/?devtools',
],
},
vite: () => ({
plugins: [react()],
}),
});

0 comments on commit b0105b1

Please sign in to comment.