什么是 blockly?
关于 blockly,它的创造者谷歌公司在 blockly 的官网中给出了详尽的说明,文档和用例展示
它的维基百科中文条目的翻译的水准实在差,我为此修改了维基百科 blockly 的中文条目,在这里为了保持原义,还是用这样一句英文来概括它:
A JavaScript library for building visual programming editors.
更完善的定义:
Blockly is a library that adds a visual code editor to web and mobile apps.
The Blockly editor uses interlocking, graphical blocks to represent code concepts like variables, logical expressions, loops, and more.
It allows users to apply programming principles without having to worry about syntax or the intimidation of a blinking cursor on the command line.
简而言之,blockly 是一个基于 JavaScript 的可视化的程序开发编辑器
第一眼看上去,它和我们常见的 Scratch 很像,事实上,Scratch3.0 基于 Blockly 构建,也就是说 Scratch3.0 中包含了 Blockly,但是二者都具有可视化模块编程的特点,但是在设计理念上却大相径庭
关于 Blockly 和 Scratch 之间的异同点,我推荐大家在这篇博客里寻找答案:blog.just4fun.site/post/少儿编程/s…
blockly 在少儿编程中能用来做什么?
近年来,少儿编程的概念在不断被热炒。计算机要从娃娃抓起
似乎已经实现了。在中国一、二线城市乃至我的家乡,一个山西的县级市里,我们都能看到各种品牌的少儿编程培训机构。他们或是同当地教育部门合作,在各个学校开展信息学教育;或是作为头部创业机构的加盟商,在焦虑的家长中寻找合适的韭菜客户。实事求是地说,联想到大学里很多同学的编程实践能力,我不认为目前市场上的少儿编程培训机构在现阶段对大多数普通青少年在智力开发和编程能力上能起到家长们想象中的作用。软件开发发展到今天,已经过了那个需要程序员在寄存器上跳舞的年代了,但是对很多不感兴趣的青少年和大学生而言,并没有那么强大的驱动力。你敢想象我见过很多计算机专业的大学生除了在课堂上和必要的作业之外一行代码都没写过?学习真正的编程是无疑会对青少年产生深远影响,但是在现在的中国,它似乎是一个被资本营销的泡沫。强烈建议那些对少儿编程抱有很大期望的家长自己先写个几百行代码,再决定要不要给孩子报名
但是有一点我十分认同:青少年是适当接触编程的基本概念和基础实践是有益无害的,有助于青少年建立缜密的逻辑思维能力,为他们未来发展打下良好的基础,但是这里有一个无法回避的问题:在很多青少年没有掌握英语和基本的计算机操作能力的时候,如何进行编程教学?他们可能键盘都不熟悉,怎么能奢求他们配置 IDE,键入和调试用英文书写的高级语言代码?这个无法回避的难题有一个不错的答案:使用 blockly 开展学习
作为可视化的程序开发编辑器,我们在有 blockly 集成的环境中,从左侧有限的选项里拖拽积木块
,按照我们所计划的顺序来排列
和组合
这些积木块
,单击运行按钮就可以看到运行结果,全程不需要用到鼠标和显示器外的其他计算机外设,这样的操作对青少年而言太友好了,这么看,blockly 这个答案是不错的

开发者的使命
首先我们应该明确一个观点:Blockly is for developers. Blockly apps are for students,开发者的使命不是拖拽积木设计程序,而是要对这个编辑器进行合理的开发,使之适应不同的需求
目前在互联网上关于各类语言、框架和库的中文教程可谓汗牛充栋,其中也不乏精品,但是关于 blockly 的教程却少而又少,只有部分博客零散的介绍了一些经验,我在一开始接手 blockly 开发时遇到了很大的困难。但事实上这是一件好事,因为这样的情况给了我一开始就只能阅读官方文档,运行官方示例的选项
clone 官方示例
git clone https://github.com/google/blockly.git
在 VScode 中打开这个文件夹,找到 blockly/demos/toolbox/index.html
在浏览器中打开这个 index.html
文件,在这里我们可以很方便的看到 blockly 编辑器的结构,并可以动手修改这里的 index.html
文件
在源码阅读中我们很容易知道:在图形界面上的增删积木,在 index.html 文件中通过增删<block>
标签进行,至于其他更多的内容,在阅读官方文档和实践中得真知吧!
在开发中我接触到的两个涉及源码的问题:
撤回操作的问题
在我接手的一个项目中,引入了 blockly 的编辑器区域初始化后会生成一个不可删除的 [ 开始 ] 积木来作为程序运行的唯一的入口,在没有进行任何操作的情况下右键选项选择撤回,会把 [ 开始 ] 积木删除,这样的行为是不被允许的
更难受的是!blockly源文件不是官方文件,是被重构的main_compressed.js
那么我是如何解决这个 bug 的呢?
很简单,这里就需要静下心来仔细寻找,在 VScode 中搜索 撤销
,我们找到了负责翻译的模块,顺藤摸瓜,在 main_compressed.js
中找到了
undoOption.text = Blockly.Msg['UNDO'];
它所在的函数名是:
Blockly.WorkspaceSvg.prototype.showContextMenu_
这么看就很清晰了,这个函数负责右键选项的逻辑,那么关于撤销
和重做
,我找到了这样的代码:
var undoOption = {};
undoOption.text = Blockly.Msg['UNDO'];
undoOption.enabled = this.undoStack_.length > 0;
undoOption.callback = this.undo.bind(this, false);
menuOptions.push(undoOption);
var redoOption = {};
redoOption.text = Blockly.Msg['REDO'];
redoOption.enabled = this.redoStack_.length > 0;
redoOption.callback = this.undo.bind(this, true);
menuOptions.push(redoOption);
可以看到undoStack_
是workspace
中的各项操作的储存的栈,而且undoOption.enabled
属性与其长度有关,于是打印输出初始状态下栈的长度
console.log(this.undoStach_.length);
运行程序,控制台输出2
果然!那接下来是事情就简单了,只需要把原来的该选项是否可用的判断条件改为是否大于2
undoOption.enabled = this.undoStack_.length > 2;
再次运行程序,问题解决
垃圾桶和禁用积木块的问题
这是一个很有趣的 bug : 在编辑区域禁用某个积木块后,将它删除掉,会发现在垃圾桶的已删除列表中单击这个积木无法还原,但是拖动却可以还原
blockly-demo.appspot.com/static/demo…
谷歌 blockly 源码中的处理是:在积木进入垃圾桶后,调用node.removeAttribute()函数,会把当前的位置属性和disable属性移除,所以单击垃圾桶中的积木不会出现在原来的位置,而是出现在workspace里垃圾桶中的位置;并且在被禁用的积木进入垃圾桶时,自身的disable属性会改为enable,blockly 官网中所给出的实例都是如此:被禁用的积木删除后在垃圾桶中的显示都会变为可用
而我修改的 blockly 源码在改动后,把移除disabled属性的方法删去,所以导致当前的 bug ,这里我觉得如果没有特殊情况,还是遵守谷歌官方的逻辑比较好