Skip to content

Commit

Permalink
feat(extension): support open-in-editor (#543)
Browse files Browse the repository at this point in the history
  • Loading branch information
webfansplz authored Aug 3, 2024
1 parent 5e60d64 commit 05833b6
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 7 deletions.
1 change: 1 addition & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const GETTING_STARTED: DefaultTheme.NavItemWithLink[] = [
{ text: 'Introduction', link: '/getting-started/introduction' },
{ text: 'Installation', link: '/getting-started/installation' },
{ text: 'Features', link: '/getting-started/features' },
{ text: 'Open in editor', link: '/getting-started/open-in-editor' },
]

const GUIDES: DefaultTheme.NavItemWithLink[] = [
Expand Down
75 changes: 75 additions & 0 deletions docs/getting-started/open-in-editor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Open component in editor

When you select a component, you have the option to open the corresponding source file in your code editor.

## Used in devtools vite plugin

Vite plugin supports this feature out-of-the-box.

The feature is based on the [vite-plugin-vue-inspector](https://github.com/webfansplz/vite-plugin-vue-inspector) plugin and requires configuration, which you can do by looking at the [configuration documentation](https://github.com/webfansplz/vite-plugin-vue-inspector?tab=readme-ov-file#--configuration-ide--editor).

Starting from **v7.2.0**, you can specify the editor by `launchEditor` option:

This is a list of [supported editors](https://github.com/yyx990803/launch-editor?tab=readme-ov-file#supported-editors), please ensure that the editor's environment variables are correctly configured beforehand.

```ts
import VueDevTools from 'vite-plugin-vue-devtools'
export default defineConfig({
plugins: [
VueDevTools({
launchEditor: 'webstorm',
}),
Unocss(),
],
})
```

## Used in devtools browser extension

### Vite & Nuxt & Quasar CLI

Vite & Nuxt & Quasar CLI supports this feature out-of-the-box. Make sure to be in debug mode.

### Webpack

In your Vue project, install the [launch-editor-middleware](https://github.com/yyx990803/launch-editor#middleware) package and modify your webpack configuration:

1. Import the package:

```ts
const openInEditor = require('launch-editor-middleware')
```

2. In the `devServer` option, register the `/__open-in-editor` HTTP route:

```js
devServer: {
before: (app) => {
app.use('/__open-in-editor', openInEditor())
}
}
```

3. The editor to launch is guessed. You can also specify the editor app with the editor option. See the [supported editors list.](https://github.com/yyx990803/launch-editor?tab=readme-ov-file#supported-editors)

```js
openInEditor('code')
```

4. You can now click on the name of the component in the Component inspector pane (if the devtools knows about its file source, a tooltip will appear).

### Node.js

You can use the [launch-editor](https://github.com/yyx990803/launch-editor) package to setup an HTTP route with the `/__open-in-editor` path. It will receive file as an URL variable.

### Customize request

You can change the request host (default `/`) with the following code in your frontend app, e.g.

```ts
if (process.env.NODE_ENV !== 'production') {
window.VUE_DEVTOOLS_CONFIG = {
openInEditorHost: 'http://localhost:3000/'
}
}
```
2 changes: 1 addition & 1 deletion packages/applet/src/modules/components/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ function closeComponentRenderCode() {
<i v-tooltip.bottom="'Scroll to component'" class="i-material-symbols-light:eye-tracking-outline h-4 w-4 cursor-pointer hover:(op-70)" @click="scrollToComponent" />
<i v-tooltip.bottom="'Show render code'" class="i-material-symbols-light:code h-5 w-5 cursor-pointer hover:(op-70)" @click="getComponentRenderCode" />
<i v-if="isInChromePanel" v-tooltip.bottom="'Inspect DOM'" class="i-material-symbols-light:menu-open h-5 w-5 cursor-pointer hover:(op-70)" @click="inspectDOM" />
<i v-if="activeTreeNodeFilePath && !isInChromePanel" v-tooltip.bottom="'Open in Editor'" class="i-carbon-launch h-4 w-4 cursor-pointer hover:(op-70)" @click="openInEditor" />
<i v-if="activeTreeNodeFilePath" v-tooltip.bottom="'Open in Editor'" class="i-carbon-launch h-4 w-4 cursor-pointer hover:(op-70)" @click="openInEditor" />
</div>
</div>
<RootStateViewer class="no-scrollbar flex-1 select-none overflow-scroll" :data="filteredState" :node-id="activeComponentId" :inspector-id="inspectorId" expanded-state-id="component-state" />
Expand Down
7 changes: 6 additions & 1 deletion packages/client/src/composables/open-in-editor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { rpc } from '@vue/devtools-core'
import { isInChromePanel } from '@vue/devtools-shared'

export const vueInspectorDetected = ref(false)

export const openInEditor = async (file: string) => {
return rpc.value.openInEditor({ file })
const opts: { file: string, host?: string } = { file }
if (isInChromePanel) {
opts.host = 'chrome-extension'
}
return rpc.value.openInEditor(opts)
}
19 changes: 14 additions & 5 deletions packages/devtools-kit/src/core/open-in-editor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,30 @@ export interface OpenInEditorOptions {
file?: string
line?: number
column?: number
host?: string
}

export function setOpenInEditorBaseUrl(url: string) {
target.__VUE_DEVTOOLS_OPEN_IN_EDITOR_BASE_URL__ = url
}

export function openInEditor(options: OpenInEditorOptions = {}) {
const { file, baseUrl = window.location.origin, line = 0, column = 0 } = options
const { file, host, baseUrl = window.location.origin, line = 0, column = 0 } = options
if (file) {
if (devtoolsState.vitePluginDetected) {
if (host === 'chrome-extension') {
const fileName = file.replace(/\\/g, '\\\\')
// @ts-expect-error skip type check
const _baseUrl = window.VUE_DEVTOOLS_CONFIG?.openInEditorHost ?? '/'
fetch(`${_baseUrl}__open-in-editor?file=${encodeURI(file)}`).then((response) => {
if (!response.ok) {
const msg = `Opening component ${fileName} failed`
console.log(`%c${msg}`, 'color:red')
}
})
}
else if (devtoolsState.vitePluginDetected) {
const _baseUrl = target.__VUE_DEVTOOLS_OPEN_IN_EDITOR_BASE_URL__ ?? baseUrl
target.__VUE_INSPECTOR__.openInEditor(_baseUrl, file, line, column)
}
else {
// @TODO: support other
}
}
}
5 changes: 5 additions & 0 deletions packages/playground/basic/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ app.use(ElementPlus)

// devtools.connect()

// // @ts-expect-error skip type check
// window.VUE_DEVTOOLS_CONFIG = {
// openInEditorHost: 'http://localhost:3000',
// }

const routes: RouteRecordRaw[] = [
{
path: '/',
Expand Down

0 comments on commit 05833b6

Please sign in to comment.