Skip to content

Commit b3d5a30

Browse files
committed
feat(chrome): initial package and build script
1 parent 0018df0 commit b3d5a30

File tree

11 files changed

+338
-112
lines changed

11 files changed

+338
-112
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"@iconify-json/simple-icons": "catalog:icons",
2727
"@nuxt/devtools": "catalog:devtools",
2828
"@nuxt/eslint": "catalog:devtools",
29+
"@types/chrome": "catalog:types",
2930
"@types/connect": "catalog:types",
3031
"@types/d3": "catalog:types",
3132
"@types/d3-hierarchy": "catalog:types",
@@ -42,6 +43,7 @@
4243
"nuxt-mcp": "catalog:build",
4344
"p-limit": "catalog:deps",
4445
"simple-git-hooks": "catalog:devtools",
46+
"tsx": "catalog:build",
4547
"typescript": "catalog:devtools",
4648
"unstorage": "catalog:deps",
4749
"vite": "catalog:build",

packages/devtools-chrome/manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
"permissions": [
3030
"scripting"
3131
],
32-
"version": "0.0.0-alpha.0",
33-
"version_name": "0.0.0-alpha.0",
32+
"version": "0.0.0",
33+
"version_name": "0.0.0",
3434
"web_accessible_resources": [
3535
{
3636
"extension_ids": [],

packages/devtools-chrome/package.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@
1919
],
2020
"sideEffects": false,
2121
"scripts": {
22-
"build": "tsdown",
22+
"build:extension": "tsx scripts/build-app.ts && tsdown",
2323
"dev": "tsdown --watch",
24-
"prepack": "pnpm build"
24+
"prepack": "pnpm build:extension"
25+
},
26+
"devDependencies": {
27+
"tsdown": "catalog:build",
28+
"tsx": "catalog:build"
2529
}
2630
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<link rel="stylesheet" href="../dist/app/devtools-app.css" />
5+
</head>
6+
<body>
7+
<div id="__nuxt"></div>
8+
<div id="teleports"></div>
9+
<script type="module" src="../dist/devtools-panel.js"></script>
10+
</body>
11+
</html>
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import fs from 'node:fs'
2+
import path from 'node:path'
3+
import { fileURLToPath } from 'node:url'
4+
import { buildNuxt, loadNuxt, useNuxt, writeTypes } from '@nuxt/kit'
5+
6+
const __dirname = fileURLToPath(new URL('.', import.meta.url))
7+
const root = path.resolve(__dirname, '../../devtools/src')
8+
const buildDir = path.resolve(__dirname, '../dist/nuxt')
9+
const distDir = path.resolve(__dirname, '../dist')
10+
11+
async function prepareTypes() {
12+
const nuxt = await loadNuxt({
13+
cwd: root,
14+
dev: false,
15+
overrides: {
16+
_prepare: true,
17+
},
18+
})
19+
20+
await writeTypes(nuxt)
21+
}
22+
23+
export async function buildDevToolsApp(buildDir: string) {
24+
fs.rmSync(distDir, { recursive: true, force: true })
25+
await prepareTypes()
26+
27+
const nuxt = await loadNuxt({
28+
cwd: root,
29+
dev: false,
30+
overrides: {
31+
buildDir,
32+
ssr: false,
33+
router: {
34+
options: { hashMode: true },
35+
},
36+
experimental: {
37+
appManifest: false,
38+
},
39+
vite: {
40+
plugins: [
41+
{
42+
name: 'mount-app-dynamically',
43+
enforce: 'pre',
44+
transform(code, id) {
45+
if (id.match(/nuxt(3|-nightly)?\/.*\/entry\./)) {
46+
return `${code
47+
.replace(/vueAppPromise = entry\(\)\.catch\(\(error\) => \{[\s\S]*?\}\);/g, '')
48+
.replace(/export default \(ssrContext\) => entry\(ssrContext\)/g, '')
49+
}export const mountApp = entry;`
50+
}
51+
},
52+
},
53+
],
54+
},
55+
nitro: {
56+
preset: '',
57+
},
58+
hooks: {
59+
// skip build nitro server
60+
'vite:compiled': function () {
61+
const nuxt = useNuxt()
62+
nuxt.hooks.removeAllHooks()
63+
},
64+
},
65+
},
66+
})
67+
68+
return new Promise<void>((resolve, reject) => {
69+
nuxt.hooks.hook('vite:extendConfig', (config) => {
70+
config.build = {
71+
...config.build,
72+
lib: {
73+
// @ts-expect-error skip type check
74+
entry: config.build.rollupOptions.input.entry,
75+
name: 'devtools-app',
76+
fileName: () => `devtools-app.js`,
77+
formats: ['es'],
78+
},
79+
rollupOptions: {
80+
...config.build?.rollupOptions,
81+
output: {
82+
assetFileNames: 'devtools-app.[ext]',
83+
},
84+
},
85+
}
86+
})
87+
88+
buildNuxt(nuxt).then(() => {
89+
resolve()
90+
fs.renameSync(path.resolve(buildDir, 'dist/client'), path.resolve(buildDir, '..', 'app'))
91+
fs.rmSync(path.resolve(distDir, 'nuxt'), { recursive: true, force: true })
92+
}).catch((err) => {
93+
console.error('build devtools app failed:', err)
94+
if (!err.toString().includes('_stop_')) {
95+
reject(err)
96+
}
97+
})
98+
}).finally(() => nuxt.close())
99+
}
100+
101+
buildDevToolsApp(buildDir)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
const checkInfo = {
2+
viteDetected: false,
3+
checkCount: 0,
4+
}
5+
const checkViteInterval = window.setInterval(() => {
6+
if (checkInfo.viteDetected || checkInfo.checkCount > 10) {
7+
clearInterval(checkViteInterval)
8+
return
9+
}
10+
11+
createDevToolsPanel()
12+
checkInfo.checkCount++
13+
}, 1000)
14+
15+
function createDevToolsPanel() {
16+
// TODO: detect vite env
17+
chrome.devtools.inspectedWindow.eval('true', (detected) => {
18+
if (!detected || checkInfo.viteDetected) {
19+
return
20+
}
21+
22+
checkInfo.viteDetected = true
23+
clearInterval(checkViteInterval)
24+
25+
chrome.devtools.panels.create('Vite', 'icons/128.png', 'pages/devtools-panel.html', (panel) => {
26+
panel.onShown.addListener(() => {
27+
// update devtools panel state here
28+
})
29+
panel.onHidden.addListener(() => {
30+
// update devtools panel state here
31+
})
32+
})
33+
})
34+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function init() {
2+
window.__NUXT__ = {}
3+
window.__NUXT__.config = { public: {}, app: { baseURL: '/', buildAssetsDir: '/_nuxt/', cdnURL: '' } }
4+
// @ts-expect-error skip type check
5+
import('./app/devtools-app.js').then((module) => {
6+
module.mountApp()
7+
})
8+
}
9+
10+
init()

packages/devtools-chrome/tsdown.config.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { defineConfig } from 'tsdown'
33
export default defineConfig({
44
entry: [
55
'src/*.ts',
6+
'!src/app/*.ts',
67
],
7-
clean: true,
8-
fixedExtension: true,
8+
clean: false,
9+
external: ['./app/devtools-app.js'],
910
})

0 commit comments

Comments
 (0)