workflow(sfc-playground): support selecting versions
This commit is contained in:
		
							parent
							
								
									ad6c124e6c
								
							
						
					
					
						commit
						9d39cd46e9
					
				| @ -18,7 +18,7 @@ | ||||
|     "@types/codemirror": "^0.0.108", | ||||
|     "@vitejs/plugin-vue": "^1.2.0", | ||||
|     "codemirror": "^5.60.0", | ||||
|     "vite": "^2.1.4" | ||||
|     "vite": "^2.1.5" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "file-saver": "^2.0.5", | ||||
|  | ||||
| @ -24,9 +24,10 @@ body { | ||||
|   font-size: 13px; | ||||
|   font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, | ||||
|     Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; | ||||
|   color: #444; | ||||
|   color:var(--base); | ||||
|   margin: 0; | ||||
|   background-color: #f8f8f8; | ||||
|   --base: #444; | ||||
|   --nav-height: 50px; | ||||
|   --font-code: 'Source Code Pro', monospace; | ||||
|   --color-branding: #3ca877; | ||||
|  | ||||
| @ -5,9 +5,21 @@ | ||||
|       <span>Vue SFC Playground</span> | ||||
|     </h1> | ||||
|     <div class="links"> | ||||
|       <a class="commit-link" href="https://app.netlify.com/sites/vue-sfc-playground/deploys" target="_blank"> | ||||
|         @{{ commit }} | ||||
|       </a> | ||||
|       <div class="version" @click.stop> | ||||
|         <span class="active-version" @click="toggle"> | ||||
|           Version: {{ activeVersion }} | ||||
|         </span> | ||||
|         <ul class="versions" :class="{ expanded }"> | ||||
|           <li v-if="!publishedVersions"><a>loading versions...</a></li> | ||||
|           <li v-for="version of publishedVersions"> | ||||
|             <a @click="setVueVersion(version)">v{{ version }}</a> | ||||
|           </li> | ||||
|           <li><a @click="resetVueVersion">This Commit ({{ commit }})</a></li> | ||||
|           <li> | ||||
|             <a href="https://app.netlify.com/sites/vue-sfc-playground/deploys" target="_blank">Commits History</a> | ||||
|           </li> | ||||
|         </ul> | ||||
|       </div> | ||||
|       <button class="share" @click="copyLink"> | ||||
|         <svg width="1.4em" height="1.4em" viewBox="0 0 24 24"> | ||||
|           <g fill="none" stroke="#626262" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> | ||||
| @ -36,13 +48,56 @@ | ||||
| 
 | ||||
| <script setup lang="ts"> | ||||
| import { downloadProject } from './download/download' | ||||
| import { setVersion, resetVersion } from './sfcCompiler' | ||||
| import { ref, onMounted } from 'vue' | ||||
| 
 | ||||
| const commit = __COMMIT__ | ||||
| const activeVersion = ref(`@${commit}`) | ||||
| const publishedVersions = ref<string[]>() | ||||
| const expanded = ref(false) | ||||
| 
 | ||||
| async function toggle() { | ||||
|   expanded.value = !expanded.value | ||||
|   if (!publishedVersions.value) { | ||||
|     publishedVersions.value = await fetchVersions() | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| async function setVueVersion(v: string) { | ||||
|   activeVersion.value = `loading...` | ||||
|   await setVersion(v) | ||||
|   activeVersion.value = `v${v}` | ||||
|   expanded.value = false | ||||
| } | ||||
| 
 | ||||
| function resetVueVersion() { | ||||
|   resetVersion() | ||||
|   activeVersion.value = `@${commit}` | ||||
|   expanded.value = false | ||||
| } | ||||
| 
 | ||||
| async function copyLink() { | ||||
|   await navigator.clipboard.writeText(location.href) | ||||
|   alert('Sharable URL has been copied to clipboard.') | ||||
| } | ||||
| 
 | ||||
| onMounted(async () => { | ||||
|   window.addEventListener('click', () => { | ||||
|     expanded.value = false | ||||
|   }) | ||||
| }) | ||||
| 
 | ||||
| async function fetchVersions(): Promise<string[]> { | ||||
|   const res = await fetch( | ||||
|     `https://api.github.com/repos/vuejs/vue-next/releases?per_page=100` | ||||
|   ) | ||||
|   const releases: any[] = await res.json() | ||||
|   const versions = releases.map( | ||||
|     r => (/^v/.test(r.tag_name) ? r.tag_name.substr(1) : r.tag_name) | ||||
|   ) | ||||
|   const minVersion = versions.findIndex(v => v === '3.0.10') | ||||
|   return versions.slice(0, minVersion + 1) | ||||
| } | ||||
| </script> | ||||
| 
 | ||||
| <style> | ||||
| @ -80,27 +135,75 @@ h1 img { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| .commit-link { | ||||
|   color: var(--color-branding); | ||||
|   text-decoration: none; | ||||
|   margin-left: 6px; | ||||
| .links { | ||||
|   display: flex; | ||||
| } | ||||
| 
 | ||||
| .version { | ||||
|   display: inline-block; | ||||
|   margin-right: 12px; | ||||
|   position: relative; | ||||
| } | ||||
| 
 | ||||
| .active-version { | ||||
|   cursor: pointer; | ||||
|   position: relative; | ||||
|   display: inline-block; | ||||
|   vertical-align: middle; | ||||
|   line-height: var(--nav-height); | ||||
|   padding-right: 15px; | ||||
| } | ||||
| 
 | ||||
| .share { | ||||
|   position: relative; | ||||
|   top: 6px; | ||||
|   margin: 0 2px; | ||||
| .active-version:after { | ||||
|   content: ''; | ||||
|   width: 0; | ||||
|   height: 0; | ||||
|   border-left: 4px solid transparent; | ||||
|   border-right: 4px solid transparent; | ||||
|   border-top: 6px solid #aaa; | ||||
|   position: absolute; | ||||
|   right: 0; | ||||
|   top: 22px; | ||||
| } | ||||
| 
 | ||||
| .version:hover .active-version:after { | ||||
|   border-top-color: var(--base); | ||||
| } | ||||
| 
 | ||||
| .versions { | ||||
|   display: none; | ||||
|   position: absolute; | ||||
|   left: 0; | ||||
|   top: 40px; | ||||
|   background-color: white; | ||||
|   border: 1px solid #ddd; | ||||
|   border-radius: 4px; | ||||
|   list-style-type: none; | ||||
|   padding: 8px; | ||||
|   margin: 0; | ||||
|   width: 200px; | ||||
|   max-height: calc(100vh - 70px); | ||||
|   overflow: scroll; | ||||
| } | ||||
| 
 | ||||
| .versions a { | ||||
|   display: block; | ||||
|   padding: 6px 12px; | ||||
|   text-decoration: none; | ||||
|   cursor: pointer; | ||||
|   color: var(--base); | ||||
| } | ||||
| 
 | ||||
| .versions a:hover { | ||||
|   color: var(--color-branding); | ||||
| } | ||||
| 
 | ||||
| .versions.expanded { | ||||
|   display: block; | ||||
| } | ||||
| 
 | ||||
| .share, | ||||
| .download { | ||||
|   position: relative; | ||||
|   top: 8px; | ||||
|   margin: 0 2px; | ||||
| } | ||||
| 
 | ||||
| .commit-link { | ||||
|   margin: 0 5px; | ||||
| } | ||||
| </style> | ||||
|  | ||||
| @ -1,22 +1,40 @@ | ||||
| import { store, File } from './store' | ||||
| import { | ||||
|   parse, | ||||
|   compileTemplate, | ||||
|   compileStyleAsync, | ||||
|   compileScript, | ||||
|   rewriteDefault, | ||||
|   SFCDescriptor, | ||||
|   BindingMetadata | ||||
| } from '@vue/compiler-sfc' | ||||
| import { SFCDescriptor, BindingMetadata } from '@vue/compiler-sfc' | ||||
| import * as defaultCompiler from '@vue/compiler-sfc' | ||||
| 
 | ||||
| export const MAIN_FILE = 'App.vue' | ||||
| export const COMP_IDENTIFIER = `__sfc__` | ||||
| 
 | ||||
| /** | ||||
|  * The default SFC compiler we are using is built from each commit | ||||
|  * but we may swap it out with a version fetched from CDNs | ||||
|  */ | ||||
| let SFCCompiler: typeof defaultCompiler = defaultCompiler | ||||
| 
 | ||||
| // @ts-ignore
 | ||||
| export const SANDBOX_VUE_URL = import.meta.env.PROD | ||||
| const defaultVueUrl = import.meta.env.PROD | ||||
|   ? '/vue.runtime.esm-browser.js' // to be copied on build
 | ||||
|   : '/src/vue-dev-proxy' | ||||
| 
 | ||||
| export let SANDBOX_VUE_URL = defaultVueUrl | ||||
| 
 | ||||
| export async function setVersion(version: string) { | ||||
|   const compilerUrl = `https://unpkg.com/@vue/compiler-sfc@${version}/dist/compiler-sfc.esm-browser.js` | ||||
|   const runtimeUrl = `https://cdn.skypack.dev/@vue/runtime-dom@${version}` | ||||
|   const [compiler] = await Promise.all([ | ||||
|     import(/* @vite-ignore */ compilerUrl), | ||||
|     import(/* @vite-ignore */ runtimeUrl) | ||||
|   ]) | ||||
|   SFCCompiler = compiler | ||||
|   SANDBOX_VUE_URL = runtimeUrl | ||||
|   console.info(`Now using Vue version: ${version}`) | ||||
| } | ||||
| 
 | ||||
| export function resetVersion() { | ||||
|   SFCCompiler = defaultCompiler | ||||
|   SANDBOX_VUE_URL = defaultVueUrl | ||||
| } | ||||
| 
 | ||||
| export async function compileFile({ filename, code, compiled }: File) { | ||||
|   if (!code.trim()) { | ||||
|     store.errors = [] | ||||
| @ -30,7 +48,10 @@ export async function compileFile({ filename, code, compiled }: File) { | ||||
|   } | ||||
| 
 | ||||
|   const id = await hashId(filename) | ||||
|   const { errors, descriptor } = parse(code, { filename, sourceMap: true }) | ||||
|   const { errors, descriptor } = SFCCompiler.parse(code, { | ||||
|     filename, | ||||
|     sourceMap: true | ||||
|   }) | ||||
|   if (errors.length) { | ||||
|     store.errors = errors | ||||
|     return | ||||
| @ -121,7 +142,7 @@ export async function compileFile({ filename, code, compiled }: File) { | ||||
|       return | ||||
|     } | ||||
| 
 | ||||
|     const styleResult = await compileStyleAsync({ | ||||
|     const styleResult = await SFCCompiler.compileStyleAsync({ | ||||
|       source: style.content, | ||||
|       filename, | ||||
|       id, | ||||
| @ -156,7 +177,7 @@ function doCompileScript( | ||||
| ): [string, BindingMetadata | undefined] | undefined { | ||||
|   if (descriptor.script || descriptor.scriptSetup) { | ||||
|     try { | ||||
|       const compiledScript = compileScript(descriptor, { | ||||
|       const compiledScript = SFCCompiler.compileScript(descriptor, { | ||||
|         id, | ||||
|         refSugar: true, | ||||
|         inlineTemplate: true, | ||||
| @ -173,7 +194,9 @@ function doCompileScript( | ||||
|           2 | ||||
|         )} */` | ||||
|       } | ||||
|       code += `\n` + rewriteDefault(compiledScript.content, COMP_IDENTIFIER) | ||||
|       code += | ||||
|         `\n` + | ||||
|         SFCCompiler.rewriteDefault(compiledScript.content, COMP_IDENTIFIER) | ||||
|       return [code, compiledScript.bindings] | ||||
|     } catch (e) { | ||||
|       store.errors = [e] | ||||
| @ -190,7 +213,7 @@ function doCompileTemplate( | ||||
|   bindingMetadata: BindingMetadata | undefined, | ||||
|   ssr: boolean | ||||
| ) { | ||||
|   const templateResult = compileTemplate({ | ||||
|   const templateResult = SFCCompiler.compileTemplate({ | ||||
|     source: descriptor.template!.content, | ||||
|     filename: descriptor.filename, | ||||
|     id, | ||||
|  | ||||
| @ -7223,10 +7223,10 @@ verror@1.10.0: | ||||
|     core-util-is "1.0.2" | ||||
|     extsprintf "^1.2.0" | ||||
| 
 | ||||
| vite@^2.1.4: | ||||
|   version "2.1.4" | ||||
|   resolved "https://registry.yarnpkg.com/vite/-/vite-2.1.4.tgz#66396823701e54cf3bfb9f73dbd386c9b4329c86" | ||||
|   integrity sha512-j/p0RZQvNY/auSPfazsDfo1PHtFp8ktwXPbzI6NqplzHcR3Cn/dfQWiMxL6zp8j9IWdcJP1Zfms7mxruBhStJw== | ||||
| vite@^2.1.5: | ||||
|   version "2.1.5" | ||||
|   resolved "https://registry.yarnpkg.com/vite/-/vite-2.1.5.tgz#4857da441c62f7982c83cbd5f42a00330f20c9c1" | ||||
|   integrity sha512-tYU5iaYeUgQYvK/CNNz3tiJ8vYqPWfCE9IQ7K0iuzYovWw7lzty7KRYGWwV3CQPh0NKxWjOczAqiJsCL0Xb+Og== | ||||
|   dependencies: | ||||
|     esbuild "^0.9.3" | ||||
|     postcss "^8.2.1" | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user