Skip to content

Commit

Permalink
wip(vapor): per-file vapor support in sfc playground
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Feb 3, 2025
1 parent c2a91a8 commit aa84afc
Show file tree
Hide file tree
Showing 8 changed files with 26 additions and 74 deletions.
2 changes: 1 addition & 1 deletion packages-private/sfc-playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"vite": "catalog:"
},
"dependencies": {
"@vue/repl": "^4.4.3",
"@vue/repl": "^4.5.0",
"file-saver": "^2.0.5",
"jszip": "^3.10.1",
"vue": "workspace:*"
Expand Down
60 changes: 9 additions & 51 deletions packages-private/sfc-playground/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import {
type SFCOptions,
useStore,
useVueImportMap,
File,
StoreState,
} from '@vue/repl'
import Monaco from '@vue/repl/monaco-editor'
import { ref, watchEffect, onMounted, computed, watch } from 'vue'
import { ref, watchEffect, onMounted, computed } from 'vue'
const replRef = ref<InstanceType<typeof Repl>>()
Expand All @@ -20,7 +19,6 @@ window.addEventListener('resize', setVH)
setVH()
const useSSRMode = ref(false)
const useVaporMode = ref(true)
const AUTO_SAVE_STORAGE_KEY = 'vue-sfc-playground-auto-save'
const initAutoSave: boolean = JSON.parse(
Expand All @@ -31,16 +29,12 @@ const autoSave = ref(initAutoSave)
const { vueVersion, productionMode, importMap } = useVueImportMap({
runtimeDev: () => {
return import.meta.env.PROD
? useVaporMode.value
? `${location.origin}/vue.runtime-with-vapor.esm-browser.js`
: `${location.origin}/vue.runtime.esm-browser.js`
? `${location.origin}/vue.runtime-with-vapor.esm-browser.js`
: `${location.origin}/src/vue-dev-proxy`
},
runtimeProd: () => {
return import.meta.env.PROD
? useVaporMode.value
? `${location.origin}/vue.runtime-with-vapor.esm-browser.prod.js`
: `${location.origin}/vue.runtime.esm-browser.prod.js`
? `${location.origin}/vue.runtime-with-vapor.esm-browser.prod.js`
: `${location.origin}/src/vue-dev-proxy-prod`
},
serverRenderer: import.meta.env.PROD
Expand All @@ -61,10 +55,6 @@ if (hash.startsWith('__SSR__')) {
hash = hash.slice(7)
useSSRMode.value = true
}
if (hash.startsWith('__VAPOR__')) {
hash = hash.slice(9)
useVaporMode.value = true
}
const files: StoreState['files'] = ref(Object.create(null))
Expand All @@ -75,13 +65,13 @@ const sfcOptions = computed(
inlineTemplate: productionMode.value,
isProd: productionMode.value,
propsDestructure: true,
vapor: useVaporMode.value,
// vapor: useVaporMode.value,
},
style: {
isProd: productionMode.value,
},
template: {
vapor: useVaporMode.value,
// vapor: useVaporMode.value,
isProd: productionMode.value,
compilerOptions: {
isCustomElement: (tag: string) =>
Expand All @@ -103,38 +93,10 @@ const store = useStore(
// @ts-expect-error
globalThis.store = store
watch(
useVaporMode,
() => {
if (useVaporMode.value) {
files.value['src/index.html'] = new File(
'src/index.html',
`<script type="module">
import { createVaporApp } from 'vue'
import App from './App.vue'
createVaporApp(App).mount('#app')` +
'<' +
'/script>' +
`<div id="app"></div>`,
true,
)
store.mainFile = 'src/index.html'
} else if (files.value['src/index.html']?.hidden) {
delete files.value['src/index.html']
store.mainFile = 'src/App.vue'
if (store.activeFile.filename === 'src/index.html') {
store.activeFile = files.value['src/App.vue']
}
}
},
{ immediate: true },
)
// persist state
watchEffect(() => {
const newHash = store
.serialize()
.replace(/^#/, useVaporMode.value ? `#__VAPOR__` : `#`)
.replace(/^#/, useSSRMode.value ? `#__SSR__` : `#`)
.replace(/^#/, productionMode.value ? `#__PROD__` : `#`)
history.replaceState({}, '', newHash)
Expand All @@ -148,10 +110,6 @@ function toggleSSR() {
useSSRMode.value = !useSSRMode.value
}
function toggleVapor() {
useVaporMode.value = !useVaporMode.value
}
function toggleAutoSave() {
autoSave.value = !autoSave.value
localStorage.setItem(AUTO_SAVE_STORAGE_KEY, String(autoSave.value))
Expand Down Expand Up @@ -179,14 +137,12 @@ onMounted(() => {
:store="store"
:prod="productionMode"
:ssr="useSSRMode"
:vapor="useVaporMode"
:autoSave="autoSave"
:theme="theme"
@toggle-theme="toggleTheme"
@toggle-prod="toggleProdMode"
@toggle-ssr="toggleSSR"
@toggle-autosave="toggleAutoSave"
@toggle-vapor="toggleVapor"
@reload-page="reloadPage"
/>
<Repl
Expand All @@ -204,8 +160,10 @@ onMounted(() => {
:clearConsole="false"
:preview-options="{
customCode: {
importCode: `import { initCustomFormatter } from 'vue'`,
useCode: `if (window.devtoolsFormatters) {
importCode: `import { initCustomFormatter, vaporInteropPlugin } from 'vue'`,
useCode: `
app.use(vaporInteropPlugin)
if (window.devtoolsFormatters) {
const index = window.devtoolsFormatters.findIndex((v) => v.__vue_custom_formatter)
window.devtoolsFormatters.splice(index, 1)
initCustomFormatter()
Expand Down
9 changes: 0 additions & 9 deletions packages-private/sfc-playground/src/Header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const props = defineProps<{
store: ReplStore
prod: boolean
ssr: boolean
vapor: boolean
autoSave: boolean
theme: 'dark' | 'light'
}>()
Expand Down Expand Up @@ -105,14 +104,6 @@ function toggleDark() {
>
<span>{{ prod ? 'PROD' : 'DEV' }}</span>
</button>
<button
title="Toggle vapor mode"
class="toggle-vapor"
:class="{ enabled: vapor }"
@click="$emit('toggle-vapor')"
>
<span>{{ vapor ? 'VAPOR ON' : 'VAPOR OFF' }}</span>
</button>
<button
title="Toggle server rendering mode"
class="toggle-ssr"
Expand Down
8 changes: 5 additions & 3 deletions packages/compiler-sfc/src/compileScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,7 @@ export function compileScript(
scoped: sfc.styles.some(s => s.scoped),
isProd: options.isProd,
ssrCssVars: sfc.cssVars,
vapor,
compilerOptions: {
...(options.templateOptions &&
options.templateOptions.compilerOptions),
Expand Down Expand Up @@ -942,9 +943,6 @@ export function compileScript(
: `export default`

let runtimeOptions = ``
if (vapor) {
runtimeOptions += `\n __vapor: true,`
}
if (!ctx.hasDefaultExportName && filename && filename !== DEFAULT_FILENAME) {
const match = filename.match(/([^/\\]+)\.\w+$/)
if (match) {
Expand Down Expand Up @@ -992,6 +990,10 @@ export function compileScript(
)
ctx.s.appendRight(endOffset, `})`)
} else {
// in TS, defineVaporComponent adds the option already
if (vapor) {
runtimeOptions += `\n __vapor: true,`
}
if (defaultExport || definedOptions) {
// without TS, can't rely on rest spread, so we use Object.assign
// export default Object.assign(__default__, { ... })
Expand Down
9 changes: 4 additions & 5 deletions packages/compiler-sfc/src/compileTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,10 @@ function doCompileTemplate({
const shortId = id.replace(/^data-v-/, '')
const longId = `data-v-${shortId}`

const defaultCompiler = vapor
? // TODO ssr
(CompilerVapor as TemplateCompiler)
: ssr
? (CompilerSSR as TemplateCompiler)
const defaultCompiler = ssr
? (CompilerSSR as TemplateCompiler)
: vapor
? (CompilerVapor as TemplateCompiler)
: CompilerDOM
compiler = compiler || defaultCompiler

Expand Down
1 change: 1 addition & 0 deletions packages/runtime-vapor/src/apiDefineComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ import type { VaporComponent } from './component'
/*! #__NO_SIDE_EFFECTS__ */
export function defineVaporComponent(comp: VaporComponent): VaporComponent {
// TODO type inference
comp.__vapor = true
return comp
}
1 change: 1 addition & 0 deletions packages/runtime-vapor/src/vdomInterop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const vaporInVDOMInterface: VaporInVDOMInterface = {

update(n1: VNode, n2: VNode) {
n2.component = n1.component
// TODO if has patchFlag, do simple diff to skip unnecessary updates
;(n2.component as any as VaporComponentInstance).rawPropsRef!.value =
n2.props
},
Expand Down
10 changes: 5 additions & 5 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit aa84afc

Please sign in to comment.