]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
refactor(sfc-playground): upgrade `@vue/repl` (#10310)
author三咲智子 Kevin Deng <sxzz@sxzz.moe>
Tue, 20 Feb 2024 13:47:09 +0000 (21:47 +0800)
committerGitHub <noreply@github.com>
Tue, 20 Feb 2024 13:47:09 +0000 (21:47 +0800)
packages/sfc-playground/index.html
packages/sfc-playground/package.json
packages/sfc-playground/src/App.vue
packages/sfc-playground/src/Header.vue
pnpm-lock.yaml

index 29e8d6e9729ff041ac836871a37bac78fa0fa8c4..2319a91876790f617371f5f31fcb1556d256e380 100644 (file)
@@ -7,8 +7,6 @@
     <link rel="icon" type="image/svg" href="/logo.svg" />
     <title>Vue SFC Playground</title>
     <script>
-      // process shim for old versions of @vue/compiler-sfc dependency
-       window.process = { env: {} }
        const savedPreferDark = localStorage.getItem('vue-sfc-playground-prefer-dark')
        if (
          savedPreferDark === 'true' ||
index bad87f75b12a80608cf9c4fe5dd9e5baf19a02c4..cc61da2f7a218c39199bf4fc773829e65bba2ecf 100644 (file)
@@ -13,7 +13,7 @@
     "vite": "^5.0.12"
   },
   "dependencies": {
-    "@vue/repl": "^3.1.1",
+    "@vue/repl": "^4.1.0",
     "file-saver": "^2.0.5",
     "jszip": "^3.10.1",
     "vue": "workspace:*"
index cadd39f4baa6a322bfe96c46ed31c1bc3dcf96ac..4b62519ce6ecf1cb9d06dc37302155ed44129409 100644 (file)
@@ -1,22 +1,8 @@
 <script setup lang="ts">
 import Header from './Header.vue'
-import { Repl, ReplStore, SFCOptions } from '@vue/repl'
-import type Monaco from '@vue/repl/monaco-editor'
-import type CodeMirror from '@vue/repl/codemirror-editor'
-import { ref, watchEffect, onMounted } from 'vue'
-import { shallowRef } from 'vue'
-
-const EditorComponent = shallowRef<typeof Monaco | typeof CodeMirror>()
-
-if (import.meta.env.DEV) {
-  import('@vue/repl/codemirror-editor').then(
-    mod => (EditorComponent.value = mod.default),
-  )
-} else {
-  import('@vue/repl/monaco-editor').then(
-    mod => (EditorComponent.value = mod.default),
-  )
-}
+import { Repl, useStore, SFCOptions, useVueImportMap } from '@vue/repl'
+import Monaco from '@vue/repl/monaco-editor'
+import { ref, watchEffect, onMounted, computed } from 'vue'
 
 const replRef = ref<InstanceType<typeof Repl>>()
 
@@ -26,78 +12,80 @@ const setVH = () => {
 window.addEventListener('resize', setVH)
 setVH()
 
-const useProdMode = ref(false)
 const useSSRMode = ref(false)
 
+const { productionMode, vueVersion, importMap } = useVueImportMap({
+  runtimeDev: import.meta.env.PROD
+    ? `${location.origin}/vue.runtime.esm-browser.js`
+    : `${location.origin}/src/vue-dev-proxy`,
+  runtimeProd: import.meta.env.PROD
+    ? `${location.origin}/vue.runtime.esm-browser.prod.js`
+    : `${location.origin}/src/vue-dev-proxy-prod`,
+  serverRenderer: import.meta.env.PROD
+    ? `${location.origin}/server-renderer.esm-browser.js`
+    : `${location.origin}/src/vue-server-renderer-dev-proxy`,
+})
+
 let hash = location.hash.slice(1)
 if (hash.startsWith('__DEV__')) {
   hash = hash.slice(7)
-  useProdMode.value = false
+  productionMode.value = false
 }
 if (hash.startsWith('__PROD__')) {
   hash = hash.slice(8)
-  useProdMode.value = true
+  productionMode.value = true
 }
 if (hash.startsWith('__SSR__')) {
   hash = hash.slice(7)
   useSSRMode.value = true
 }
 
-const store = new ReplStore({
-  serializedState: hash,
-  productionMode: useProdMode.value,
-  defaultVueRuntimeURL: import.meta.env.PROD
-    ? `${location.origin}/vue.runtime.esm-browser.js`
-    : `${location.origin}/src/vue-dev-proxy`,
-  defaultVueRuntimeProdURL: import.meta.env.PROD
-    ? `${location.origin}/vue.runtime.esm-browser.prod.js`
-    : `${location.origin}/src/vue-dev-proxy-prod`,
-  defaultVueServerRendererURL: import.meta.env.PROD
-    ? `${location.origin}/server-renderer.esm-browser.js`
-    : `${location.origin}/src/vue-server-renderer-dev-proxy`,
-})
-
 // enable experimental features
-const sfcOptions: SFCOptions = {
-  script: {
-    inlineTemplate: useProdMode.value,
-    isProd: useProdMode.value,
-    propsDestructure: true,
-  },
-  style: {
-    isProd: useProdMode.value,
-  },
-  template: {
-    isProd: useProdMode.value,
-    compilerOptions: {
-      isCustomElement: (tag: string) => tag === 'mjx-container',
+const sfcOptions = computed(
+  (): SFCOptions => ({
+    script: {
+      inlineTemplate: productionMode.value,
+      isProd: productionMode.value,
+      propsDestructure: true,
+    },
+    style: {
+      isProd: productionMode.value,
+    },
+    template: {
+      isProd: productionMode.value,
+      compilerOptions: {
+        isCustomElement: (tag: string) => tag === 'mjx-container',
+      },
     },
+  }),
+)
+
+const store = useStore(
+  {
+    builtinImportMap: importMap,
+    vueVersion,
+    sfcOptions,
   },
-}
+  hash,
+)
+// @ts-expect-error
+globalThis.store = store
 
 // persist state
 watchEffect(() => {
   const newHash = store
     .serialize()
     .replace(/^#/, useSSRMode.value ? `#__SSR__` : `#`)
-    .replace(/^#/, useProdMode.value ? `#__PROD__` : `#`)
+    .replace(/^#/, productionMode.value ? `#__PROD__` : `#`)
   history.replaceState({}, '', newHash)
 })
 
 function toggleProdMode() {
-  const isProd = (useProdMode.value = !useProdMode.value)
-  sfcOptions.script!.inlineTemplate =
-    sfcOptions.script!.isProd =
-    sfcOptions.template!.isProd =
-    sfcOptions.style!.isProd =
-      isProd
-  store.toggleProduction()
-  store.setFiles(store.getFiles())
+  productionMode.value = !productionMode.value
 }
 
 function toggleSSR() {
   useSSRMode.value = !useSSRMode.value
-  store.setFiles(store.getFiles())
 }
 
 function reloadPage() {
@@ -111,13 +99,16 @@ function toggleTheme(isDark: boolean) {
 onMounted(() => {
   const cls = document.documentElement.classList
   toggleTheme(cls.contains('dark'))
+
+  // @ts-expect-error process shim for old versions of @vue/compiler-sfc dependency
+  window.process = { env: {} }
 })
 </script>
 
 <template>
   <Header
     :store="store"
-    :prod="useProdMode"
+    :prod="productionMode"
     :ssr="useSSRMode"
     @toggle-theme="toggleTheme"
     @toggle-prod="toggleProdMode"
@@ -125,17 +116,15 @@ onMounted(() => {
     @reload-page="reloadPage"
   />
   <Repl
-    v-if="EditorComponent"
     ref="replRef"
     :theme="theme"
-    :editor="EditorComponent"
+    :editor="Monaco"
     @keydown.ctrl.s.prevent
     @keydown.meta.s.prevent
     :ssr="useSSRMode"
     :store="store"
     :showCompileOutput="true"
     :autoResize="true"
-    :sfcOptions="sfcOptions"
     :clearConsole="false"
     :preview-options="{
       customCode: {
index 48585a8e646a0a7437c8df1af450f26a8b51dcf7..6506ad7bab290419054ca28e8f20b0f5bcd83225 100644 (file)
@@ -1,13 +1,13 @@
 <script setup lang="ts">
+import { computed } from 'vue'
+import type { ReplStore } from '@vue/repl'
 import { downloadProject } from './download/download'
-import { ref } from 'vue'
 import Sun from './icons/Sun.vue'
 import Moon from './icons/Moon.vue'
 import Share from './icons/Share.vue'
 import Download from './icons/Download.vue'
 import GitHub from './icons/GitHub.vue'
 import Reload from './icons/Reload.vue'
-import type { ReplStore } from '@vue/repl'
 import VersionSelect from './VersionSelect.vue'
 
 const props = defineProps<{
@@ -25,23 +25,20 @@ const emit = defineEmits([
 const { store } = props
 
 const currentCommit = __COMMIT__
-const vueVersion = ref(`@${currentCommit}`)
 
-const vueURL = store.getImportMap().imports.vue
-if (vueURL && !vueURL.startsWith(location.origin)) {
-  const versionMatch = vueURL.match(/runtime-dom@([^/]+)/)
-  if (versionMatch) vueVersion.value = versionMatch[1]
-}
+const vueVersion = computed(() => {
+  if (store.loading) {
+    return 'loading...'
+  }
+  return store.vueVersion || `@${__COMMIT__}`
+})
 
 async function setVueVersion(v: string) {
-  vueVersion.value = `loading...`
-  await store.setVueVersion(v)
-  vueVersion.value = v
+  store.vueVersion = v
 }
 
 function resetVueVersion() {
-  store.resetVueVersion()
-  vueVersion.value = `@${currentCommit}`
+  store.vueVersion = null
 }
 
 async function copyLink(e: MouseEvent) {
@@ -73,7 +70,7 @@ function toggleDark() {
     </h1>
     <div class="links">
       <VersionSelect
-        v-model="store.state.typescriptVersion"
+        v-model="store.typescriptVersion"
         pkg="typescript"
         label="TypeScript Version"
       />
index 011ffb2664a0ad14b229159da6f5cfa7ea6a92ea..a12747fb08e0d42485a1a034c298138e1c33c620 100644 (file)
@@ -347,8 +347,8 @@ importers:
   packages/sfc-playground:
     dependencies:
       '@vue/repl':
-        specifier: ^3.1.1
-        version: 3.1.1
+        specifier: ^4.1.0
+        version: 4.1.0
       file-saver:
         specifier: ^2.0.5
         version: 2.0.5
@@ -1774,8 +1774,8 @@ packages:
     engines: {node: '>= 0.12.0'}
     dev: true
 
-  /@vue/repl@3.1.1:
-    resolution: {integrity: sha512-9nJImsUeywU2MTqvzf4ueqWC49UC3LVXVPk1HmoNnLVumfWXv+w5ytuSA//fxb/N/O5vCqE0UV63/dYvnCZpwQ==}
+  /@vue/repl@4.1.0:
+    resolution: {integrity: sha512-4ZNEQWlLjl1Sq+WFiACm5siMdwUAmmqOES4XDgZRRFYeeW/BfabO9I6fpU+Y0zO9HFzKb8dwUUH0e0LK7mIYeg==}
     dev: false
 
   /@zeit/schemas@2.29.0: