Blockly 可视化编程编辑器入门教程:从拖积木到生成代码只需 4 步
【免费下载链接】blocklyThe web-based visual programming editor.项目地址: https://gitcode.com/gh_mirrors/bloc/blockly
给课程页面嵌一个拖拽编程框时,最烦的不是拖积木,而是学生改错一个引号,你就得盯着屏幕逐字符纠错。Blockly 是 Google 开源的 Web 可视化编程编辑器,用可拼接的图形块表示变量、循环、逻辑这类代码概念,拼完之后能直接导出成 JavaScript、Python、Lua 等语言的真实代码。下面这条路径能跑通「拼块 → 出码 → 自动存档」的最小闭环。
项目速览:可视化编程编辑器长什么样
一句话定位:Blockly 把编程语法翻译成可拖拽的图形块,块之间的连接关系天然就是合法语法,用户不用碰分号和括号。
适合的场景:教学平台、少儿编程工具、IoT 规则配置器,以及任何想把「写代码」降级成「搭积木」的 Web 应用。
目录结构看这四个就够:
core/— 编辑器本体:工作区、积木块、工具箱、事件、代码生成器都在这里blocks/— 逻辑、循环、数学等标准积木块的 JSON 定义generators/— 代码生成器,JavaScript、Python、PHP、Lua、Dart 各占一个目录demos/— 可打开的官方演示页,其中 demos/code/ 是「拼块转代码」的完整样例
快速上手:两行命令跑起编辑器
环境要求:现代浏览器(Chrome、Firefox、Safari 均可)+ Node.js 14+ 和 npm。
方式一,装包(大多数集成场景选这个):
npm install blockly方式二,从源码构建(要改 Blockly 自身代码才需要):
git clone https://gitcode.com/gh_mirrors/bloc/blockly cd blockly npm install npm run build注入编辑器只需要一个容器 div 和一个 toolbox:
import * as Blockly from 'blockly'; const workspace = Blockly.inject('blocklyDiv', { toolbox: { kind: 'flyoutToolbox', contents: [{ kind: 'block', type: 'controls_repeat_ext' }], }, });页面里出现一个可拖拽的工作区和一个飞出式工具箱,说明环境没问题。完整注入配置项可翻 core/blockly_options.ts。
主线实战:做一个会弹提示的积木块
这个 Demo 贯穿四步:定义一个自定义块 → 让它生成 JavaScript → 监听修改自动存档 → 刷新后恢复现场。目标效果:用户拖出「打招呼」块、填个名字、点生成,页面就弹出对应提示框。
1. 定义积木块:JSON 声明 + 生成函数
块分两部分:长什么样由 JSON 描述,出什么代码由生成函数决定。
Blockly.Blocks['hello_world'] = { init: function () { this.jsonInit({ message0: '向 %1 打招呼', args0: [{ type: 'field_input', name: 'NAME', text: '世界' }], previousStatement: null, nextStatement: null, colour: 160, }); }, };白话:这个块有一个文本输入位NAME,默认值「世界」,previousStatement/nextStatement为 null 表示它只能独立成段、不能串进别的块里。把hello_world加进 toolbox 的contents里,块就会出现在工具箱中。更多标准块写法可以看 blocks/logic.ts。
2. 生成代码:拼块变 JavaScript
Blockly.JavaScript.forBlock.hello_world = function (block) { const name = Blockly.JavaScript.valueToCode(block, 'NAME'); return 'alert("你好, ' + name + '");\n'; };valueToCode负责把输入框里的内容变成代码字符串并处理优先级。取整块代码只用一行:
const code = Blockly.JavaScript.workspaceToCode(workspace);生成器内部逻辑见 core/generator.ts,JavaScript 实现的入口在 generators/javascript.ts,Python、Lua 等同理。
3. 监听事件:改一块就存一次
workspace.addChangeListener((event) => { if (event.type === Blockly.Events.BLOCK_CHANGE) { const json = Blockly.serialization.workspaces.save(workspace); localStorage.setItem('myProgram', JSON.stringify(json)); } });任何块被修改都会触发BLOCK_CHANGE,顺手序列化存进 localStorage。事件基类与各类事件定义在 core/events/,每个事件类型一个文件。
4. 💾 恢复现场:JSON 双向持久化
const data = JSON.parse(localStorage.getItem('myProgram')); if (data) Blockly.serialization.workspaces.load(data, workspace);存和取都是 JSON,后端落库、多人协作都省事;XML 格式在 core/xml.ts 也有现成工具。到这里「建块 → 出码 → 存档 → 恢复」整条链路就通了。
源码速读:三个目录看懂架构
- core/workspace.ts — 工作区是中心:块的增删、移动、缩放、序列化都围绕它
- core/block.ts — 积木块的抽象模型;SVG 渲染细节在 core/block_svg.ts
- core/events/ — 事件系统,
events_abstract.ts是基类,其余文件按事件类型拆分 - core/toolbox.ts — 左侧工具箱与分类树的实现
读源码的顺序建议:workspace → block → events,工具箱和主题可以放后面。
避坑清单:高频问题的排查顺序
拖拽卡顿现象:块多之后拖动掉帧。原因:每次变更都触发全量代码生成或多余的事件监听器。解法:用防抖(如 300ms 节流)再生成代码,清掉不用的监听。
自定义块不出现在工具箱现象:定义了块,工具箱里却是空的。原因:块定义和 toolbox 配置是两件事,只定义没挂进 toolbox 不会显示。解法:确认 toolbox 的contents里有kind: 'block'且type与定义一致,再看控制台报错。
生成代码语法正确但不符合预期现象:输出合法,但优先级或格式不对。原因:生成函数里没用valueToCode带运算符优先级。解法:对照 tests/generators/ 下的 golden 测试,看标准块是怎么写的。
保存后覆盖未保存的修改现象:加载旧数据把用户刚拼的块冲掉了。原因:load之前没清工作区。解法:调用workspace.clear()后再Blockly.serialization.workspaces.load。
延伸资源
- 拼块转代码的完整演示:demos/code/;最小地图插件示例:demos/minimap/
- 多语言代码生成器对比:generators/
- 主题定制参考实现:core/theme/classic.ts
- 云存储后端(Google App Engine):appengine/
- TypeScript 类型定义:typings/index.d.ts
把这几个目录过一遍,从「嵌入编辑器」到「二次开发」基本就都有着落了。
【免费下载链接】blocklyThe web-based visual programming editor.项目地址: https://gitcode.com/gh_mirrors/bloc/blockly
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考