mcpField
S
slidev-monaco-editor

slidev-monaco-editor

github.com/yoanbernabeu文档处理41209 次安装39 周前更新
代码仓库

关于 slidev-monaco-editor

slidev-monaco-editor 是面向 Slidev 演示文稿作者的技能,讲解如何将 Monaco Editor 用于现场编码和交互式代码演示。它涵盖可编辑代码块、运行代码、输出显示及编辑器配置。

主要功能

  1. 01可编辑的 Monaco 代码块
  2. 02JavaScript 与 TypeScript 代码运行
  3. 03显示运行输出
  4. 04只读与差异编辑器模式
  5. 05配置编辑器选项与主题

适用场景

  1. 01现场演示代码编辑
  2. 02运行示例并查看输出
  3. 03讲授编程概念
  4. 04制作可交互的代码练习

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/yoanbernabeu/slidev-skills --skill slidev-monaco-editor

安装后在 Claude Code 中输入/slidev-monaco-editor确认已加载。

详细介绍

Slidev 中的 Monaco Editor

本技能介绍如何在 Slidev 演示文稿中集成 Monaco Editor(VS Code 使用的编辑器),以实现实时编码、交互式演示和可执行代码块。

何时使用此技能

  • 实时编码演示
  • 演示期间交互式编辑代码
  • 实时运行代码示例
  • 教授编程概念
  • 展示自动补全和类型提示

启用 Monaco Editor

基础 Monaco 代码块

在任意代码块中添加 {monaco}:

```typescript {monaco}
const greeting = 'Hello, World!'
console.log(greeting)
```

这会创建一个可编辑代码块,支持:

  • 语法高亮
  • 自动补全
  • 类型检查(适用于 TypeScript)
  • 括号匹配
带行高亮的 Monaco
```typescript {monaco}{2,3}
const a = 1
const b = 2  // highlighted
const c = 3  // highlighted
```

Monaco 运行器

在演示文稿中直接执行代码:

JavaScript 运行器
```javascript {monaco-run}
const numbers = [1, 2, 3, 4, 5]
const doubled = numbers.map(n => n * 2)
console.log(doubled)
```

点击“Run”即可执行并查看输出。

TypeScript 运行器
```typescript {monaco-run}
interface User {
  name: string
  age: number
}

const user: User = {
  name: 'John',
  age: 30
}

console.log(`${user.name} is ${user.age} years old`)
```
加载时自动运行
```javascript {monaco-run} {autorun:true}
console.log('This runs automatically!')
```
仅显示输出
```javascript {monaco-run} {showOutputAt:'+1'}
// Output shows after one click
console.log('Hello!')
```

配置选项

编辑器高度
```typescript {monaco}{height:'300px'}
// Taller editor
function longFunction() {
  // ...
}
```
只读模式
```typescript {monaco}{readonly:true}
// Cannot be edited
const CONSTANT = 'value'
```
差异编辑器
```typescript {monaco-diff}
const original = 'Hello'
~~~
const modified = 'Hello, World!'
```

Monaco 设置配置

setup/monaco.ts
import { defineMonacoSetup } from '@slidev/types'

export default defineMonacoSetup((monaco) => {
  // Editor options
  return {
    editorOptions: {
      fontSize: 14,
      fontFamily: 'JetBrains Mono, monospace',
      minimap: { enabled: false },
      lineNumbers: 'on',
      wordWrap: 'on',
      tabSize: 2,
      scrollBeyondLastLine: false,
      automaticLayout: true,
    },
    // Light/dark theme
    theme: {
      light: 'vs',
      dark: 'vs-dark',
    },
  }
})
自定义主题
import { defineMonacoSetup } from '@slidev/types'

export default defineMonacoSetup((monaco) => {
  // Define custom theme
  monaco.editor.defineTheme('my-theme', {
    base: 'vs-dark',
    inherit: true,
    rules: [
      { token: 'comment', foreground: '6A9955' },
      { token: 'keyword', foreground: 'C586C0' },
    ],
    colors: {
      'editor.background': '#1a1a2e',
    },
  })

  return {
    theme: {
      dark: 'my-theme',
      light: 'vs',
    },
  }
})

类型定义

为库添加类型
// setup/monaco.ts
import { defineMonacoSetup } from '@slidev/types'

export default defineMonacoSetup(async (monaco) => {
  // Add React types
  const reactTypes = await fetch(
    'https://unpkg.com/@types/react/index.d.ts'
  ).then(r => r.text())

  monaco.languages.typescript.typescriptDefaults.addExtraLib(
    reactTypes,
    'file:///node_modules/@types/react/index.d.ts'
  )
})
内联类型定义
```typescript {monaco}
// Types defined inline
interface Todo {
  id: number
  text: string
  completed: boolean
}

const todos: Todo[] = [
  { id: 1, text: 'Learn Slidev', completed: true },
  { id: 2, text: 'Create presentation', completed: false },
]
```

交互式示例

计数器演示
```typescript {monaco-run}
// Interactive counter
let count = 0

function increment() {
  count++
  console.log(`Count: ${count}`)
}

// Click Run multiple times!
increment()
```
API 模拟
```typescript {monaco-run}
// Simulated API call
async function fetchUser(id: number) {
  // Simulate network delay
  await new Promise(r => setTimeout(r, 500))

  return {
    id,
    name: 'John Doe',
    email: '[email protected]'
  }
}

const user = await fetchUser(1)
console.log(user)
```
算法可视化
```typescript {monaco-run}
// Bubble sort with steps
function bubbleSort(arr: number[]) {
  const result = [...arr]
  const steps: string[] = []

  for (let i = 0; i < result.length; i++) {
    for (let j = 0; j < result.length - i - 1; j++) {
      if (result[j] > result[j + 1]) {
        [result[j], result[j + 1]] = [result[j + 1], result[j]]
        steps.push(`Swap: [${result.join(', ')}]`)
      }
    }
  }

  return { result, steps }
}

const { result, steps } = bubbleSort([5, 3, 8, 4, 2])
console.log('Steps:', steps.length)
steps.forEach(s => console.log(s))
console.log('Final:', result)
```

代码运行器模式

先展示概念,再让用户编辑
# Array Methods

```typescript {monaco-run}
const numbers = [1, 2, 3, 4, 5]

// Try changing the function!
const result = numbers
  .filter(n => n % 2 === 0)
  .map(n => n * 2)

console.log(result)
```

Try modifying the code to:
- Filter odd numbers
- Triple instead of double
交互式测验
# Fix the Bug

```typescript {monaco-run}
// This code has a bug - can you fix it?
function reverseString(str: string) {
  return str.split('').reserve().join('')
}

console.log(reverseString('hello'))
// Expected: 'olleh'
```
实时数据处理
```typescript {monaco-run}
const data = [
  { name: 'Alice', score: 85 },
  { name: 'Bob', score: 92 },
  { name: 'Charlie', score: 78 },
]

// Calculate statistics
const average = data.reduce((sum, d) => sum + d.score, 0) / data.length
const highest = Math.max(...data.map(d => d.score))
const passing = data.filter(d => d.score >= 80)

console.log(`Average: ${average.toFixed(1)}`)
console.log(`Highest: ${highest}`)
console.log(`Passing: ${passing.map(d => d.name).join(', ')}`)
```

与动画结合

先揭示,再编辑
<v-click>

```typescript {monaco}
// Code appears on click, then is editable
function greet(name: string) {
  return `Hello, ${name}!`
}
```

</v-click>
使用 Monaco 分步展示
<v-clicks>

Start with this code:

```typescript {monaco}
const x = 1
```

Then try adding more lines!

</v-clicks>

最佳实践

1. 聚焦示例内容
```typescript {monaco-run}
// GOOD: Single concept
const sum = [1, 2, 3].reduce((a, b) => a + b, 0)
console.log(sum) // 6
```
2. 提供起点
```typescript {monaco-run}
// Complete the function:
function capitalize(str: string): string {
  // Your code here
  return str
}

console.log(capitalize('hello')) // Should print: 'Hello'
```
3. 显示预期输出
```typescript {monaco-run}
// Code example
const result = [1, 2, 3].map(n => n ** 2)
console.log(result)
// Expected output: [1, 4, 9]
```
4. 妥善处理错误
```typescript {monaco-run}
try {
  const result = riskyOperation()
  console.log(result)
} catch (error) {
  console.error('Error:', error.message)
}

function riskyOperation() {
  // Might throw an error
  throw new Error('Oops!')
}
```

限制

  • 无法访问 DOM:不能操作页面 DOM
  • API 有限:仅提供标准 JavaScript API
  • 不支持导入:无法导入外部包
  • 仅支持控制台输出:输出基于控制台

输出格式

创建 Monaco 代码块时:

PURPOSE: [What the code demonstrates]
INTERACTION: [How audience should interact]

CODE:
```[language] {monaco-run}
// Clear comments explaining purpose

[Code with good defaults]

// Expected output noted

建议修改:

  • 尝试将 X 改为 Y
  • 修改函数以实现 Z

评论

支持 Markdown