Skip to content

Commit

Permalink
feat(vue): add support for devtools (#10929)
Browse files Browse the repository at this point in the history
Co-authored-by: Sarah Rainsberger <sarah@rainsberger.ca>
  • Loading branch information
florian-lefebvre and sarah11918 committed May 6, 2024
1 parent 11c58a9 commit 082abb8
Show file tree
Hide file tree
Showing 4 changed files with 279 additions and 20 deletions.
18 changes: 18 additions & 0 deletions .changeset/thin-rabbits-wait.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
"@astrojs/vue": minor
---

Adds a `devtools` option

You can enable the [official Vue DevTools](https://devtools-next.vuejs.org/) while working in development mode by setting `devtools:true` in your `vue()` integration config:

```js
import { defineConfig } from "astro/config"
import vue from "@astrojs/vue"

export default defineConfig({
integrations: [
vue({ devtools: true })
]
})
```
3 changes: 2 additions & 1 deletion packages/integrations/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
"dependencies": {
"@vitejs/plugin-vue": "^5.0.4",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"@vue/compiler-sfc": "^3.4.26"
"@vue/compiler-sfc": "^3.4.26",
"vite-plugin-vue-devtools": "^7.1.3"
},
"devDependencies": {
"astro": "workspace:*",
Expand Down
35 changes: 24 additions & 11 deletions packages/integrations/vue/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,16 @@ import type { Options as VueOptions } from '@vitejs/plugin-vue';
import vue from '@vitejs/plugin-vue';
import type { Options as VueJsxOptions } from '@vitejs/plugin-vue-jsx';
import { MagicString } from '@vue/compiler-sfc';
import type { AstroIntegration, AstroRenderer } from 'astro';
import type { AstroIntegration, AstroRenderer, HookParameters } from 'astro';
import type { Plugin, UserConfig } from 'vite';

const VIRTUAL_MODULE_ID = 'virtual:@astrojs/vue/app';
const RESOLVED_VIRTUAL_MODULE_ID = `\0${VIRTUAL_MODULE_ID}`;

interface Options extends VueOptions {
jsx?: boolean | VueJsxOptions;
appEntrypoint?: string;
devtools?: boolean;
}

function getRenderer(): AstroRenderer {
Expand All @@ -28,9 +32,6 @@ function getJsxRenderer(): AstroRenderer {
}

function virtualAppEntrypoint(options?: Options): Plugin {
const virtualModuleId = 'virtual:@astrojs/vue/app';
const resolvedVirtualModuleId = '\0' + virtualModuleId;

let isBuild: boolean;
let root: string;
let appEntrypoint: string | undefined;
Expand All @@ -49,12 +50,12 @@ function virtualAppEntrypoint(options?: Options): Plugin {
}
},
resolveId(id: string) {
if (id == virtualModuleId) {
return resolvedVirtualModuleId;
if (id == VIRTUAL_MODULE_ID) {
return RESOLVED_VIRTUAL_MODULE_ID;
}
},
load(id: string) {
if (id === resolvedVirtualModuleId) {
if (id === RESOLVED_VIRTUAL_MODULE_ID) {
if (appEntrypoint) {
return `\
import * as mod from ${JSON.stringify(appEntrypoint)};
Expand Down Expand Up @@ -93,7 +94,10 @@ export const setup = async (app) => {
};
}

async function getViteConfiguration(options?: Options): Promise<UserConfig> {
async function getViteConfiguration(
command: HookParameters<'astro:config:setup'>['command'],
options?: Options
): Promise<UserConfig> {
let vueOptions = {
...options,
template: {
Expand All @@ -105,7 +109,7 @@ async function getViteConfiguration(options?: Options): Promise<UserConfig> {
const config: UserConfig = {
optimizeDeps: {
include: ['@astrojs/vue/client.js', 'vue'],
exclude: ['@astrojs/vue/server.js', 'virtual:@astrojs/vue/app'],
exclude: ['@astrojs/vue/server.js', VIRTUAL_MODULE_ID],
},
plugins: [vue(vueOptions), virtualAppEntrypoint(vueOptions)],
ssr: {
Expand All @@ -119,19 +123,28 @@ async function getViteConfiguration(options?: Options): Promise<UserConfig> {
config.plugins?.push(vueJsx(jsxOptions));
}

if (command === 'dev' && options?.devtools) {
const vueDevTools = (await import('vite-plugin-vue-devtools')).default;
config.plugins?.push(
vueDevTools({
appendTo: VIRTUAL_MODULE_ID,
})
);
}

return config;
}

export default function (options?: Options): AstroIntegration {
return {
name: '@astrojs/vue',
hooks: {
'astro:config:setup': async ({ addRenderer, updateConfig }) => {
'astro:config:setup': async ({ addRenderer, updateConfig, command }) => {
addRenderer(getRenderer());
if (options?.jsx) {
addRenderer(getJsxRenderer());
}
updateConfig({ vite: await getViteConfiguration(options) });
updateConfig({ vite: await getViteConfiguration(command, options) });
},
},
};
Expand Down

0 comments on commit 082abb8

Please sign in to comment.