Vue Playground 演练场源码解读(二)

Vue Playground 演练场源码解读(二)

在《Vue Playground 演练场源码解读(一)》中咱们学习到了:

  1. 动态获取版本,并且简单了解了下jsdelivr
  2. 动态设置高度
  3. ?raw 是做什么的,以及jszip配合file-saver的下载项目.

在本篇中,咱们主要讲解一下:@vue/repl包中的一些源码。@vue/repl是整个playground演练场的核心, @vue/repl主页地址

接下来还是会一步步的对代码块进行拆分,先了解基础技术,才能读懂该源码的精髓。

importmap

在浏览器中直接运行 ES 模块(<script type="module">)时,模块标识符(如 import Vue from 'vue')必须是完整的 URL 或相对路径。浏览器无法像 Node.js 或构建工具(如 Webpack)那样自动解析 node_modules 中的依赖。

Import Maps 提供了一种机制,将简写的模块名(如 'vue')映射到具体的 CDN URL,从而让浏览器能正确加载依赖。

html 复制代码
<script type="importmap">
      {
        "imports":{
            "vue":"https://cdn.jsdelivr.net/npm/@vue/runtime-dom@3.5.13/dist/runtime-dom.esm-browser.js",
            "vue/server-renderer":"https://cdn.jsdelivr.net/npm/@vue/server-renderer@3.5.13/dist/server-renderer.esm-browser.js"
        },
        "scopes":{}
    }
</script>

Playground 需要允许用户动态切换 Vue 版本或添加其他依赖,而无需重新构建或预配置。

Playground 通常在 iframe 沙盒中运行,限制了文件系统访问和网络请求。使用 Import Maps 配合 CDN 资源,可以确保所有依赖都通过受控的 HTTPS 加载,避免安全风险。

这里咱们先了解下importmap的用法,后面在去讲Playground中实际去应用。

利用路由 hash 实现分享功能

这里可能有些同学不是太了解路由的模式,先解释下路由模式hashhistory的区别:

hash模式:

https://www.baidu.com/#/home带一个#号,就是hash模式。

特点是不回携带路由去请求服务器,访问后端是https://www.baidu.com/,缺点是 URL 看起来不够"干净"。

history模式:

https://www.baidu.com/home优点是 URL 更美观,更符合传统的网址结构,缺点是需要后端服务器的支持,因为服务器需要正确处理这些路径。就是请求服务会携带路由。

回到Playground中,利用hash模式,来进行传值,就是文件内容都在hash中。get 请求中如果是字符过长会溢出 (Chrome:8182字符),使用hash模式就不会有该问题了。

分享功能 给别人查看你的代码就是这么实现的。

当然官方对hash字符还进行了一系列压缩处理,处理如下:

可以看到利用了fflate这个包实现的压缩,fflate是一个快速、轻量级且纯 JavaScript 实现的压缩库,用于处理 gzip、zlib 和 Deflate 格式的数据压缩与解压缩。

以后有需要压缩的场景可以直接使用这种方式,对压缩原理比较感兴趣的可以去看下zlibSync、unzlibSync方法

以下图函数serialize deserialize是对文件的处理:

大致就是对file的压缩以及解压。

useVueImportMap 和 useStore

useVueImportMap方法主要用来控制界面以下功能:

  1. 记录选中的vue版本vueVersion,没选中就用默认的。
  2. 记录是不是生产模式productionMode
  3. 根据以上1、2 俩字段动态生成需要的引入依赖的importmap

代码如下:

useStore 方法主要是全局对files的处理,以及当前选中了那个file如下图所示:

还有部分针对files编译报错提示的errorcompileFile 这个方法稍后再看,先略过 这里主要是收集error信息的

js 复制代码
watchEffect(() => {
  compileFile(store, activeFile.value).then((errs) => (errors.value = errs))
})

界面展示报错信息

files是一个对象,key是文件名,value是File类实例,如下:

js 复制代码
export class File {
  compiled = {
    js: '',
    css: '',
    ssr: '',
  }
  editorViewState: editor.ICodeEditorViewState | null = null

  constructor(
    public filename: string,
    public code = '',
    public hidden = false,
  ) {}

  get language() {
    if (this.filename.endsWith('.vue')) {
      return 'vue'
    }
    if (this.filename.endsWith('.html')) {
      return 'html'
    }
    if (this.filename.endsWith('.css')) {
      return 'css'
    }
    if (this.filename.endsWith('.ts')) {
      return 'typescript'
    }
    return 'javascript'
  }
}

总结

本篇中咱们学习到了:

  1. importmap 的相关用法。
  2. 简单介绍了hashhistory模式的区别。
  3. 介绍了playground分享功能利用hash模式的实现。
  4. 使用hash模式下利用fflate对数据进行压缩、解压。
  5. 介绍了核心源码useVueImportMap 和 useStore的实现逻辑
相关推荐
Li_Ning2140 分钟前
【Docker】让前端也能用Docker部署,以ruoyi(若依)为例,极简部署流程
前端·docker·容器
cyw89982 小时前
vue命令总结
vue.js·vue
_平凡之路_3 小时前
实现限制同一个账号最多只能在3个客户端(有电脑、手机等)登录(附关键源码)
android·java·vue.js·spring·servlet
Anlici4 小时前
还只会express?今儿使用Koa2 实现 Jwt鉴权
前端·koa
zhenryx4 小时前
前端-导出png,jpg,pptx,svg
开发语言·前端·javascript
QBorfy4 小时前
02篇 AI从零开始 - 部署本地大模型 DeepSeek-R1
前端·人工智能·deepseek
QBorfy4 小时前
01篇 AI从零开始 - 基础知识和环境准备
前端·人工智能
115432031q4 小时前
基于SpringBoot养老院平台系统功能实现十五
java·前端·后端
朦胧之5 小时前
React Native 新架构 (一)
前端·react native
患得患失9495 小时前
【前端】【面试】ref与reactive的区别
前端·面试·vue3