@vue/repl Documentation

repository·main·Indexed 22 days ago

https://github.com/vuejs/repl

A Vue 3 component that provides a fully functional Single File Component (SFC) REPL environment. It allows developers to embed an interactive code editor and previewer into applications, supporting both CodeMirror for lightweight use and Monaco Editor for a full IDE experience with Volar support, autocomplete, and type inference. Includes utilities for managing Vue import maps, virtual NPM file systems via CDNs, and sandboxed execution environments.

Tokens
9K
Snippets
35
Records
40
Agent score
78%

What's inside @vue/repl

  1. Configure Vite to exclude @vue/repl

    main

    When using @vue/repl in a Vite project, you must exclude it from dependency optimization to ensure it works correctly. Add @vue/repl to the optimizeDeps.exclude array in your vite.config.ts.

    // vite.config.ts
    import { defineConfig } from 'vite'
    export default defineConfig({
      optimizeDeps: {
        exclude: ['@vue/repl'],
      },
      // ...
    })
  2. Customize REPL behavior with useStore and useVueImportMap

    main

    For advanced customization, you can manually initialize the REPL state by using useStore and useVueImportMap. This allows you to control the Vue version, production mode, import maps, and UI state (like showOutput or outputMode) via URL parameters or custom logic. You can also persist the REPL state to the URL hash using store.serialize().

    <script setup>
    import { watchEffect, ref } from 'vue'
    import { Repl, useStore, useVueImportMap } from '@vue/repl'
    import Monaco from '@vue/repl/monaco-editor'
    
    const query = new URLSearchParams(location.search)
    
    const { 
      importMap: builtinImportMap, 
      vueVersion, 
      productionMode 
    } = useVueImportMap({
      runtimeDev: 'cdn link to vue.runtime.esm-browser.js',
      runtimeProd: 'cdn link to vue.runtime.esm-browser.prod.js',
      serverRenderer: 'cdn link to server-renderer.esm-browser.js',
    })
    
    const store = useStore(
      {
        builtinImportMap,
        vueVersion,
        showOutput: ref(query.has('showOutput')),
        outputMode: ref(query.get('outputMode') || 'preview'),
      },
      location.hash,
    )
    
    watchEffect(() => history.replaceState({}, '', store.serialize()))
    
    vueVersion.value = '3.2.8'
    productionMode.value = true
    </script>
    
    <template>
      <Repl :store="store" :editor="Monaco" :showCompileOutput="true" />
    </template>
  3. Configure Monaco worker environment

    main

    The environment is configured via loadMonacoEnv(store), which sets the global MonacoEnvironment.getWorker function. This allows the editor to spawn a specialized vueWorker when the language label is 'vue'.

    When the Vue worker is initialized, it receives a WorkerMessage containing:

    • tsVersion: The current TypeScript version.
    • tsLocale: The locale for TypeScript.
    • pkgDirUrl, pkgFileTextUrl, pkgLatestVersionUrl: Resource links for package management.
    • typescriptLib: Path to the TypeScript library.
  4. Configure Vue version and Compiler

    main

    The REPL allows switching between different Vue versions. When vueVersion is updated, the store automatically fetches the corresponding @vue/compiler-sfc from a CDN (defaulting to jsDelivr) and recompiles all .vue files to ensure compatibility (e.g., for Vapor mode support).

    You can also provide resourceLinks to customize how the compiler or TypeScript libraries are fetched.

    store.vueVersion = ref('3.5.0');
    
    // Customizing resource resolution
    store.resourceLinks = {
      vueCompilerUrl: (version) => `https://my-cdn.com/compiler-sfc@${version}/dist/compiler-sfc.esm-browser.js`
    };
  5. Understand OutputModes

    main

    The REPL supports different output modes for rendering or processing code. The available modes are:

    • 'preview': Standard browser preview.
    • 'ssr output': Output specifically for Server-Side Rendering.
    • EditorMode values: 'js', 'css', or 'ssr'.
  6. Use only the Sandbox Preview without an editor

    main

    If you only need to display the output (the preview) without providing an editing interface, use the Sandbox component instead of Repl. You still need to initialize a store using useStore to manage the state.

    <script setup>
    import { ref } from 'vue'
    import { Sandbox, useStore } from '@vue/repl'
    
    const query = new URLSearchParams(location.search)
    
    const store = useStore(
      {
        vueVersion: ref(query.get('vue')),
      },
      location.hash,
    )
    </script>
    
    <template>
      <Sandbox :store="store" />
    </template>
  7. Use @vue/repl with Monaco Editor

    main

    For a full-featured IDE experience, use the Monaco editor. This provides Volar support, autocomplete, type inference, and semantic highlighting. This option results in a heavier bundle as it loads .dts files from a CDN and is better suited for standalone applications.

    <script setup>
    import { Repl } from '@vue/repl'
    import Monaco from '@vue/repl/monaco-editor'
    // import '@vue/repl/style.css' // no longer needed after 3.0
    </script>
    
    <template>
      <Repl :editor="Monaco" />
    </template>
  8. Use @vue/repl with CodeMirror Editor

    main

    For a lightweight editing experience suitable for embedding, use the CodeMirror editor. This version has no intellisense and results in fewer network requests and a smaller bundle size. Note that since version 3.0, importing @vue/repl/style.css is no longer required.

    <script setup>
    import { Repl } from '@vue/repl'
    import CodeMirror from '@vue/repl/codemirror-editor'
    // import '@vue/repl/style.css' // no longer needed after 3.0
    </script>
    
    <template>
      <Repl :editor="CodeMirror" />
    </template>
  9. Configure SFC compilation via Store options

    main

    The compileFile function relies on the Store object to access compiler configurations. You can influence the compilation process by providing options through store.sfcOptions:

    • store.sfcOptions.template: Passes options to the Vue template compiler (e.g., compilerOptions).
    • store.sfcOptions.script: Passes options to the Vue script compiler (e.g., customElement).
    • store.sfcOptions.style: Passes options to the Vue style compiler.

    Custom Element Detection: Custom elements can be identified via store.sfcOptions.script.customElement, which accepts:

    • A boolean
    • A RegExp (to test the filename)
    • A function (to test the filename)

    If a file is identified as a custom element, styles are compiled into the component object rather than being extracted as a separate CSS string.

  10. Configure NPM file system URL resolution

    main

    You can customize how the virtual file system resolves package metadata and files by providing a CreateNpmFileSystemOptions object to createNpmFileSystem. By default, it uses unpkg.com patterns.

    Options

    • getPackageLatestVersionUrl: Function to fetch the package.json of the latest version of a package.
      • Signature: (pkgName: string) => string
    • getPackageDirectoryUrl: Function to fetch directory metadata (file lists) for a package version.
      • Signature: (pkgName: string, pkgVersion: string, pkgPath: string) => string
    • getPackageFileTextUrl: Function to fetch the actual text content of a file.
      • Signature: (pkgName: string, pkgVersion: string | undefined, pkgPath: string) => string
    const options: CreateNpmFileSystemOptions = {
      getPackageLatestVersionUrl: (pkgName) => `https://cdn.example.com/${pkgName}@latest/package.json`,
      getPackageDirectoryUrl: (pkgName, pkgVersion, pkgPath) => 
        `https://cdn.example.com/${pkgName}@${pkgVersion}/${pkgPath}/?meta`,
      getPackageFileTextUrl: (pkgName, pkgVersion, pkgPath) => 
        `https://cdn.example.com/${pkgName}@${pkgVersion || 'latest'}/${pkgPath}`
    };
  11. Configure resource links for custom CDNs

    main

    You can override the default CDN resources used by the REPL (like ES module shims, the Vue compiler, or TypeScript libraries) by providing a resourceLinks object to useStore. This is useful for using alternative registries like unpkg or npmmirror.

    export type ResourceLinkConfigs = {
      /** URL for ES Module Shims. */
      esModuleShims?: string
      /** Function that generates the Vue compiler URL based on the version. */
      vueCompilerUrl?: (version: string) => string
      /** Function that generates the TypeScript library URL based on the version. */
      typescriptLib?: (version: string) => string
    
      /** [monaco] Function that generates a URL to fetch the latest version of a package. */
      pkgLatestVersionUrl?: (pkgName: string) => string
      /** [monaco] Function that generates a URL to browse a package directory. */
      pkgDirUrl?: (pkgName: string, pkgVersion: string, pkgPath: string) => string
      /** [monaco] Function that generates a URL to fetch the content of a file from a package. */
      pkgFileTextUrl?: (
        pkgName: string,
        pkgVersion: string | undefined,
        pkgPath: string,
      ) => string
    }
  12. Create a source map visualization link with toVisualizer()

    main

    The toVisualizer function generates a specialized URL for the evanw.github.io/source-map-visualization tool. It encodes both the source code and the RawSourceMap into a single base64-encoded binary string appended to the URL. This allows developers to instantly visualize how their source maps map back to the original code in an external web-based debugger.

    import { toVisualizer } from './sourcemap';
    
    const visualizerUrl = toVisualizer(code, sourceMap);
    // Returns a URL like: https://evanw.github.io/source-map-visualization#<base64_data>