Skip to content

Commit fe5d919

Browse files
authored
refactor(sfc-playground): upgrade @vue/repl (#10310)
1 parent 3199189 commit fe5d919

File tree

5 files changed

+67
-83
lines changed

5 files changed

+67
-83
lines changed

packages/sfc-playground/index.html

-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
<link rel="icon" type="image/svg" href="/logo.svg" />
88
<title>Vue SFC Playground</title>
99
<script>
10-
// process shim for old versions of @vue/compiler-sfc dependency
11-
window.process = { env: {} }
1210
const savedPreferDark = localStorage.getItem('vue-sfc-playground-prefer-dark')
1311
if (
1412
savedPreferDark === 'true' ||

packages/sfc-playground/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"vite": "^5.0.12"
1414
},
1515
"dependencies": {
16-
"@vue/repl": "^3.1.1",
16+
"@vue/repl": "^4.1.0",
1717
"file-saver": "^2.0.5",
1818
"jszip": "^3.10.1",
1919
"vue": "workspace:*"

packages/sfc-playground/src/App.vue

+51-62
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,8 @@
11
<script setup lang="ts">
22
import Header from './Header.vue'
3-
import { Repl, ReplStore, SFCOptions } from '@vue/repl'
4-
import type Monaco from '@vue/repl/monaco-editor'
5-
import type CodeMirror from '@vue/repl/codemirror-editor'
6-
import { ref, watchEffect, onMounted } from 'vue'
7-
import { shallowRef } from 'vue'
8-
9-
const EditorComponent = shallowRef<typeof Monaco | typeof CodeMirror>()
10-
11-
if (import.meta.env.DEV) {
12-
import('@vue/repl/codemirror-editor').then(
13-
mod => (EditorComponent.value = mod.default),
14-
)
15-
} else {
16-
import('@vue/repl/monaco-editor').then(
17-
mod => (EditorComponent.value = mod.default),
18-
)
19-
}
3+
import { Repl, useStore, SFCOptions, useVueImportMap } from '@vue/repl'
4+
import Monaco from '@vue/repl/monaco-editor'
5+
import { ref, watchEffect, onMounted, computed } from 'vue'
206
217
const replRef = ref<InstanceType<typeof Repl>>()
228
@@ -26,78 +12,80 @@ const setVH = () => {
2612
window.addEventListener('resize', setVH)
2713
setVH()
2814
29-
const useProdMode = ref(false)
3015
const useSSRMode = ref(false)
3116
17+
const { productionMode, vueVersion, importMap } = useVueImportMap({
18+
runtimeDev: import.meta.env.PROD
19+
? `${location.origin}/vue.runtime.esm-browser.js`
20+
: `${location.origin}/src/vue-dev-proxy`,
21+
runtimeProd: import.meta.env.PROD
22+
? `${location.origin}/vue.runtime.esm-browser.prod.js`
23+
: `${location.origin}/src/vue-dev-proxy-prod`,
24+
serverRenderer: import.meta.env.PROD
25+
? `${location.origin}/server-renderer.esm-browser.js`
26+
: `${location.origin}/src/vue-server-renderer-dev-proxy`,
27+
})
28+
3229
let hash = location.hash.slice(1)
3330
if (hash.startsWith('__DEV__')) {
3431
hash = hash.slice(7)
35-
useProdMode.value = false
32+
productionMode.value = false
3633
}
3734
if (hash.startsWith('__PROD__')) {
3835
hash = hash.slice(8)
39-
useProdMode.value = true
36+
productionMode.value = true
4037
}
4138
if (hash.startsWith('__SSR__')) {
4239
hash = hash.slice(7)
4340
useSSRMode.value = true
4441
}
4542
46-
const store = new ReplStore({
47-
serializedState: hash,
48-
productionMode: useProdMode.value,
49-
defaultVueRuntimeURL: import.meta.env.PROD
50-
? `${location.origin}/vue.runtime.esm-browser.js`
51-
: `${location.origin}/src/vue-dev-proxy`,
52-
defaultVueRuntimeProdURL: import.meta.env.PROD
53-
? `${location.origin}/vue.runtime.esm-browser.prod.js`
54-
: `${location.origin}/src/vue-dev-proxy-prod`,
55-
defaultVueServerRendererURL: import.meta.env.PROD
56-
? `${location.origin}/server-renderer.esm-browser.js`
57-
: `${location.origin}/src/vue-server-renderer-dev-proxy`,
58-
})
59-
6043
// enable experimental features
61-
const sfcOptions: SFCOptions = {
62-
script: {
63-
inlineTemplate: useProdMode.value,
64-
isProd: useProdMode.value,
65-
propsDestructure: true,
66-
},
67-
style: {
68-
isProd: useProdMode.value,
69-
},
70-
template: {
71-
isProd: useProdMode.value,
72-
compilerOptions: {
73-
isCustomElement: (tag: string) => tag === 'mjx-container',
44+
const sfcOptions = computed(
45+
(): SFCOptions => ({
46+
script: {
47+
inlineTemplate: productionMode.value,
48+
isProd: productionMode.value,
49+
propsDestructure: true,
50+
},
51+
style: {
52+
isProd: productionMode.value,
53+
},
54+
template: {
55+
isProd: productionMode.value,
56+
compilerOptions: {
57+
isCustomElement: (tag: string) => tag === 'mjx-container',
58+
},
7459
},
60+
}),
61+
)
62+
63+
const store = useStore(
64+
{
65+
builtinImportMap: importMap,
66+
vueVersion,
67+
sfcOptions,
7568
},
76-
}
69+
hash,
70+
)
71+
// @ts-expect-error
72+
globalThis.store = store
7773
7874
// persist state
7975
watchEffect(() => {
8076
const newHash = store
8177
.serialize()
8278
.replace(/^#/, useSSRMode.value ? `#__SSR__` : `#`)
83-
.replace(/^#/, useProdMode.value ? `#__PROD__` : `#`)
79+
.replace(/^#/, productionMode.value ? `#__PROD__` : `#`)
8480
history.replaceState({}, '', newHash)
8581
})
8682
8783
function toggleProdMode() {
88-
const isProd = (useProdMode.value = !useProdMode.value)
89-
sfcOptions.script!.inlineTemplate =
90-
sfcOptions.script!.isProd =
91-
sfcOptions.template!.isProd =
92-
sfcOptions.style!.isProd =
93-
isProd
94-
store.toggleProduction()
95-
store.setFiles(store.getFiles())
84+
productionMode.value = !productionMode.value
9685
}
9786
9887
function toggleSSR() {
9988
useSSRMode.value = !useSSRMode.value
100-
store.setFiles(store.getFiles())
10189
}
10290
10391
function reloadPage() {
@@ -111,31 +99,32 @@ function toggleTheme(isDark: boolean) {
11199
onMounted(() => {
112100
const cls = document.documentElement.classList
113101
toggleTheme(cls.contains('dark'))
102+
103+
// @ts-expect-error process shim for old versions of @vue/compiler-sfc dependency
104+
window.process = { env: {} }
114105
})
115106
</script>
116107

117108
<template>
118109
<Header
119110
:store="store"
120-
:prod="useProdMode"
111+
:prod="productionMode"
121112
:ssr="useSSRMode"
122113
@toggle-theme="toggleTheme"
123114
@toggle-prod="toggleProdMode"
124115
@toggle-ssr="toggleSSR"
125116
@reload-page="reloadPage"
126117
/>
127118
<Repl
128-
v-if="EditorComponent"
129119
ref="replRef"
130120
:theme="theme"
131-
:editor="EditorComponent"
121+
:editor="Monaco"
132122
@keydown.ctrl.s.prevent
133123
@keydown.meta.s.prevent
134124
:ssr="useSSRMode"
135125
:store="store"
136126
:showCompileOutput="true"
137127
:autoResize="true"
138-
:sfcOptions="sfcOptions"
139128
:clearConsole="false"
140129
:preview-options="{
141130
customCode: {

packages/sfc-playground/src/Header.vue

+11-14
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
<script setup lang="ts">
2+
import { computed } from 'vue'
3+
import type { ReplStore } from '@vue/repl'
24
import { downloadProject } from './download/download'
3-
import { ref } from 'vue'
45
import Sun from './icons/Sun.vue'
56
import Moon from './icons/Moon.vue'
67
import Share from './icons/Share.vue'
78
import Download from './icons/Download.vue'
89
import GitHub from './icons/GitHub.vue'
910
import Reload from './icons/Reload.vue'
10-
import type { ReplStore } from '@vue/repl'
1111
import VersionSelect from './VersionSelect.vue'
1212
1313
const props = defineProps<{
@@ -25,23 +25,20 @@ const emit = defineEmits([
2525
const { store } = props
2626
2727
const currentCommit = __COMMIT__
28-
const vueVersion = ref(`@${currentCommit}`)
2928
30-
const vueURL = store.getImportMap().imports.vue
31-
if (vueURL && !vueURL.startsWith(location.origin)) {
32-
const versionMatch = vueURL.match(/runtime-dom@([^/]+)/)
33-
if (versionMatch) vueVersion.value = versionMatch[1]
34-
}
29+
const vueVersion = computed(() => {
30+
if (store.loading) {
31+
return 'loading...'
32+
}
33+
return store.vueVersion || `@${__COMMIT__}`
34+
})
3535
3636
async function setVueVersion(v: string) {
37-
vueVersion.value = `loading...`
38-
await store.setVueVersion(v)
39-
vueVersion.value = v
37+
store.vueVersion = v
4038
}
4139
4240
function resetVueVersion() {
43-
store.resetVueVersion()
44-
vueVersion.value = `@${currentCommit}`
41+
store.vueVersion = null
4542
}
4643
4744
async function copyLink(e: MouseEvent) {
@@ -73,7 +70,7 @@ function toggleDark() {
7370
</h1>
7471
<div class="links">
7572
<VersionSelect
76-
v-model="store.state.typescriptVersion"
73+
v-model="store.typescriptVersion"
7774
pkg="typescript"
7875
label="TypeScript Version"
7976
/>

pnpm-lock.yaml

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)