2023-12-16 01:19:43 +08:00
import path from 'node:path' ;
2022-09-29 11:25:45 +08:00
import type { Options as VueOptions } from '@vitejs/plugin-vue' ;
2023-12-06 04:07:28 +08:00
import vue from '@vitejs/plugin-vue' ;
2023-12-16 01:19:43 +08:00
import type { Options as VueJsxOptions } from '@vitejs/plugin-vue-jsx' ;
import type { AstroIntegration , AstroRenderer } from 'astro' ;
import type { Plugin , UserConfig } from 'vite' ;
2022-03-18 15:35:45 -07:00
2022-09-29 11:25:45 +08:00
interface Options extends VueOptions {
jsx? : boolean | VueJsxOptions ;
2022-10-13 14:15:57 -05:00
appEntrypoint? : string ;
2022-09-29 11:25:45 +08:00
}
2022-03-18 15:35:45 -07:00
function getRenderer ( ) : AstroRenderer {
return {
name : '@astrojs/vue' ,
clientEntrypoint : '@astrojs/vue/client.js' ,
serverEntrypoint : '@astrojs/vue/server.js' ,
} ;
}
2022-09-29 11:25:45 +08:00
function getJsxRenderer ( ) : AstroRenderer {
2022-03-18 15:35:45 -07:00
return {
2022-09-29 11:25:45 +08:00
name : '@astrojs/vue (jsx)' ,
clientEntrypoint : '@astrojs/vue/client.js' ,
serverEntrypoint : '@astrojs/vue/server.js' ,
jsxImportSource : 'vue' ,
jsxTransformOptions : async ( ) = > {
const jsxPlugin = ( await import ( '@vue/babel-plugin-jsx' ) ) . default ;
return {
plugins : [ jsxPlugin ] ,
} ;
} ,
} ;
}
2023-12-16 01:19:43 +08:00
function virtualAppEntrypoint ( options? : Options ) : Plugin {
2022-10-13 14:15:57 -05:00
const virtualModuleId = 'virtual:@astrojs/vue/app' ;
const resolvedVirtualModuleId = '\0' + virtualModuleId ;
2023-12-16 01:19:43 +08:00
let isBuild : boolean ;
let root : string ;
2022-10-13 14:15:57 -05:00
return {
name : '@astrojs/vue/virtual-app' ,
2023-12-16 01:19:43 +08:00
config ( _ , { command } ) {
isBuild = command === 'build' ;
2023-12-05 18:38:29 -06:00
} ,
2023-12-16 01:19:43 +08:00
configResolved ( config ) {
root = config . root ;
2023-12-05 18:38:29 -06:00
} ,
2022-10-13 14:15:57 -05:00
resolveId ( id : string ) {
if ( id == virtualModuleId ) {
return resolvedVirtualModuleId ;
}
} ,
2023-12-16 01:19:43 +08:00
load ( id : string ) {
2022-10-13 14:15:57 -05:00
if ( id === resolvedVirtualModuleId ) {
2023-12-16 01:19:43 +08:00
if ( options ? . appEntrypoint ) {
const appEntrypoint = options . appEntrypoint . startsWith ( '.' )
? path . resolve ( root , options . appEntrypoint )
: options . appEntrypoint ;
return ` \
import * as mod from $ { JSON . stringify ( appEntrypoint ) } ;
export const setup = ( app ) = > {
if ( 'default' in mod ) {
mod . default ( app ) ;
} else {
$ {
! isBuild
? ` console.warn("[@astrojs/vue] appEntrypoint \` " + ${ JSON . stringify ( appEntrypoint ) } + " \` does not export a default function. Check out https://docs.astro.build/en/guides/integrations-guide/vue/#appentrypoint."); `
: ''
}
}
} ` ;
2022-10-13 14:15:57 -05:00
}
2023-12-16 01:19:43 +08:00
return ` export const setup = () => {}; ` ;
2022-10-13 14:15:57 -05:00
}
2023-12-05 20:08:47 +00:00
} ,
2023-12-16 01:19:43 +08:00
} ;
2022-10-13 14:15:57 -05:00
}
2023-12-16 01:19:43 +08:00
async function getViteConfiguration ( options? : Options ) : Promise < UserConfig > {
2022-09-29 11:25:45 +08:00
const config : UserConfig = {
2022-03-18 15:35:45 -07:00
optimizeDeps : {
include : [ '@astrojs/vue/client.js' , 'vue' ] ,
2022-10-13 19:17:42 +00:00
exclude : [ '@astrojs/vue/server.js' , 'virtual:@astrojs/vue/app' ] ,
2022-03-18 15:35:45 -07:00
} ,
2022-10-13 14:15:57 -05:00
plugins : [ vue ( options ) , virtualAppEntrypoint ( options ) ] ,
2022-03-18 15:35:45 -07:00
ssr : {
external : [ '@vue/server-renderer' ] ,
2022-12-09 11:46:21 -05:00
noExternal : [ 'vuetify' , 'vueperslides' , 'primevue' ] ,
2022-03-18 15:35:45 -07:00
} ,
} ;
2022-09-29 11:25:45 +08:00
if ( options ? . jsx ) {
const vueJsx = ( await import ( '@vitejs/plugin-vue-jsx' ) ) . default ;
const jsxOptions = typeof options . jsx === 'object' ? options.jsx : undefined ;
config . plugins ? . push ( vueJsx ( jsxOptions ) ) ;
}
return config ;
2022-03-18 15:35:45 -07:00
}
2022-04-19 16:31:32 +00:00
export default function ( options? : Options ) : AstroIntegration {
2022-03-18 15:35:45 -07:00
return {
name : '@astrojs/vue' ,
hooks : {
2023-12-16 01:19:43 +08:00
'astro:config:setup' : async ( { addRenderer , updateConfig } ) = > {
2022-03-18 15:35:45 -07:00
addRenderer ( getRenderer ( ) ) ;
2022-09-29 11:25:45 +08:00
if ( options ? . jsx ) {
addRenderer ( getJsxRenderer ( ) ) ;
}
2023-12-16 01:19:43 +08:00
updateConfig ( { vite : await getViteConfiguration ( options ) } ) ;
2022-03-18 15:35:45 -07:00
} ,
} ,
} ;
}