Blockly 实战:15 行代码注入可视化编程编辑器,五种语言出代码
【免费下载链接】blocklyThe web-based visual programming editor.项目地址: https://gitcode.com/gh_mirrors/bloc/blockly
给内部平台加一个拖拽式编程模块
你要给内部培训平台加个编程模块:学员不用碰语法,拖拽就能搭出程序,交付物还得是可执行的代码,而不是一堆截图。Blockly 就是为这类场景做的可视化编程编辑器库,它把变量、循环、条件这些编程概念变成可拖拽的积木块,并内置 JavaScript、Python、PHP、Lua、Dart 五种语言的代码生成。
3 分钟跑起来:装包、注入、工具栏
要求很轻:能跑 ES Modules 的现代浏览器即可,想从源码构建则用 Node 18+。装包一条命令:
npm install blockly页面里准备一个 div,把 workspace 注进去:
import * as Blockly from 'blockly'; const workspace = Blockly.inject('blocklyDiv', { toolbox: { kind: 'categoryToolbox', contents: [ { kind: 'category', name: 'Logic', contents: [{ kind: 'block', type: 'controls_if' }] }, ], }, });inject做三件事:在 id 为 blocklyDiv 的 div 里注入工作区、在旁边渲染分类工具栏、返回后面会一直用的 workspace 对象。打开页面就能看到 if 积木被拖进画布并拼起来。仓库里对应的完整演示在 tests/playground.html,inject 的全部参数项则列在 core/blockly_options.ts。
从积木定义到出代码:三步管线
Blockly 的数据流很线性:先定义积木,再挂上代码生成,最后用事件接住交互,三步都在同一个页面里完成。
积木定义:用 JSON 描述形状
内置积木定义在 blocks/,每个语言类别一个文件。自定义走defineBlocksWithJsonArray:
Blockly.defineBlocksWithJsonArray([ { type: 'hello_world', message0: '对 %2 说 %1', args0: [ { type: 'field_input', name: 'TEXT', text: 'Hello' }, { type: 'input_value', name: 'WHO' }, ], previousStatement: null, nextStatement: null, colour: 160, }, ]);它注册了一个叫 hello_world 的语句积木:第一个槽是文本输入框,第二个槽能插任意值型积木。注意还得在 toolbox 的 contents 里补一条{ kind: 'block', type: 'hello_world' },否则画布和工具栏里都看不到它。
代码生成:forBlock 告诉生成器怎么翻译
生成器按语言拆成独立模块,以 JavaScript 为例:
import { javascriptGenerator } from 'blockly/javascript'; javascriptGenerator.forBlock.hello_world = (block, gen) => { const text = gen.quote_(block.getFieldValue('TEXT')); const who = gen.valueToCode(block, 'WHO', gen.ORDER_ATOMIC); return `alert(${text} + ${who});\n`; }; const code = javascriptGenerator.workspaceToCode(workspace);forBlock存的是「这个积木该编译成什么」,valueToCode负责取出 WHO 槽里拼的子积木,优先级参数决定生成的表达式要不要加括号。workspaceToCode把整个画布变成一个字符串,落库或送沙箱都行。五种语言的实现都在 generators/,一语言一个目录。
事件响应:画布上的每次操作都会派发
实时保存、协同同步、自动判分,全都挂在事件流上:
workspace.addChangeListener((event) => { if (event.type === Blockly.Events.BLOCK_CHANGE) { console.log('积木变了:', event.blockId); } });工作区里的拖拽、改字段、删除,都会派发成一次事件。事件类型在 core/events/ 里一类型一个文件,完整清单见 core/events/events.ts。
想让它长你的样子:主题、存储、移动端
三样都是按需取用,不需要就跳过。
主题——要让画布配色跟产品走,用defineTheme覆盖 blockStyles:
const theme = Blockly.Theme.defineTheme('custom', { blockStyles: { logic: { colourPrimary: '#4a6785' } }, });再把theme: theme传进 inject 即可,内置主题的写法可参考 core/theme/。
存储——持久化直接走 JSON 序列化:
const state = Blockly.serialization.workspaces.save(workspace); // 下次打开时 Blockly.serialization.workspaces.load(state, workspace);需要多人云存储接口,appengine/ 目录有一份现成的 Python 后端,可以对着它起自己的服务。
移动端——目标设备含平板或手机时,看 demos/mobile/:html、Android WebView、iOS 三套示例,html 版是基底,两个原生壳都是 WebView 包一层。
踩过的坑
- 自定义积木不显示:定义注册了,但 toolbox contents 里没有对应的
{ kind: 'block', type: 'xxx' },工具栏才是展示的最后一步。 - 生成代码括号错乱:
valueToCode漏传优先级常量(如ORDER_ATOMIC),运算符优先级就会算错。 - 一次操作触发多次监听:同一 div 上二次 inject 不会自动移除旧 workspace 的 change 监听,重建画布前先调
workspace.dispose()。 - 照着旧教程写
Blockly.JavaScript:v11 起生成器拆成独立子包,旧文档的全局对象风格拿不到实例,要import 'blockly/javascript'。 - 直接 eval 生成代码:培训场景 alert 一行无所谓,生产环境请放进沙箱执行,别直接丢进当前页面。
项目地图
- core/workspace.ts — 工作区管理
- core/block.ts — 积木模型
- blocks/ — 内置积木定义
- generators/ — 五语言代码生成
- core/events/ — 事件系统
- tests/playground.html — 全功能试玩页
下一步
最快的上手方式是打开 tests/playground.html 直接玩,工具栏、JSON/XML 存取、五语言出代码都齐了。想看插件与移动端集成就翻 demos/。有具体场景想聊的,直接去仓库 Issue 区提。
【免费下载链接】blocklyThe web-based visual programming editor.项目地址: https://gitcode.com/gh_mirrors/bloc/blockly
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考