作者PsMonkey (痞子军团团长)
看板java
标题[翻译] GWT 的 Super Dev Mode 是怎麽运作的?
时间Sun Jun 17 17:12:22 2012
有图有 link、理论上比较好读的网志版:
http://blog.dontcareabout.us/2012/06/gwt-super-dev-mode.html
=====================================================================
原文网址:
http://tbroyer.posterous.com/how-does-gwts-super-dev-mode-work
GWT 的 Super Dev Mode(别名:Super Draft Mode)一个月前第一次 tease,
然後持续发展到上个礼拜正式 land,for your testing pleasure.
(译注:翻译不能 Orz)
这个 Dev Mode 强化了哪些东西?
在回答这个问题前,让我们先回头了解一下 Dev Mode 的构造,
它是由 browser plugin 与 code server 所组成、
用 TCP 的 socket 彼此沟通以在 JVM 中执行你的 GWT 码
然後跟 browser 互动(以及执行 JSNI),
而不用先跑一次漫长的 compile 过程。
GWT 的 Dev Mode 也可以(额外)嵌入一个 servlet container
(预设是 Jetty 6,也可以用其他的),
所以它可以执行 server 端的程式码。
在 GWT 开发指南中可以找到这张图:
https://developers.google.com/web-toolkit/doc/latest/images/
DevModeTypical.jpg
Dev Mode 其中一个优点是在 JVM 中执行你的 client 端程式码,
你可以使用标准的 Java debugger,有 breakpoint、可以观察变数......等等。
此外,server 端的程式码也在同一个 JVM 上头执行,
就更容易 debug(不过只适用於小程式)。
缺点就是需要一个 browser plugin
(它得在 UI thread 中阻断 JS 的执行,
但是同步的 XMLHttpRequest 没办法提供够好的效能、
Dev Mode 又很聒噪地一直发,
更不用说同步的 XHR 将要被淘汰了。)
需要一个 browser plugin 会导致很多问题:
→每个 browser 有它自己的 API
(至少对 Dev Mode 而言,需要 branch into JS 引擎、
以及提供一个设定画面),
这表示你必须对每个 browser、每个平台维护一个 plugin。
这是为甚麽只有 IE(显然仅限 Windows)、
Firefox(所有平台)、Chrome(所有平台)、
Safari(仅限 Mac)上有 plugin,
而 Windows 上的 Opera、Safari 没有,
更不用说 mobile browser 了。
→你需要执行一个 plugin,这在 Web Worker 中办不到的、
对 browser extension 来说是个挑战(如果要全部通用的话),
在 mobile browser 上仍就不可能。
→Firefox 每次有新版本时,plugin 也必须更新,
因为它是 binary 的 extension;
Gecko SDK 也会在每次更新时改变。
这在去年 Mozilla 转变成 rapid release process 时变成问题。
虽然从二月导入 ESR 之後有所缓解,
但仍无法在 Beta、Aurora(甚至 Nightly)版本
的 Firefox 中使用 Dev Mode;
and sticking to the ESR (which is not the case)
would make it impossible to use bleeding edge feature in Dev Mode.
(译注:翻译不能 Orz)
→Dev Mode 需要某些 browser API,但并不总是能满足需求:
在 Chrome 中偶尔会烂掉,GWT Team 则建议使用其他 browser。
一言以蔽之,维护 Dev Mode 已经变成一场恶梦:
plugin 必须每六周更新一次;
开发者在 Firefox 更新但是新版 Dev Mode 还没出来前会抓狂;
而 Chrome 很难使用,因为它的行为不稳定也不可遇测;
在 Safari 也有相同问题,而支援 IE9 方面上也需要作一些调整。
迈向 Super Dev Mode
过去几年,Google 一直努力於他们 Closure Tool 的其中一部分,
设法能 debug compile 後的 JavaScript(最初是用 Closure Compiler 产生)
——如果原本的程式码是你写的。
他们最初以 Firebug 的 extension 方式写了一个 Closure Inspector;
随着 compiled-to-JS 语言(像是 CoffeeScript)的兴起,
他们提炼成果、并开始与 Mozilla 合作制定一个现在称为 Source Maps 的规格:
这是一个不管原始语言是什麽,
都可以从 compile 後的 JS 对应回原始的程式码。
Closure Inspector 没有再维护了
(也无法在最新版的 Firefox 与 Firebug 上运作),
但是 Chrome 现在内建、
Mozilla 也开始积极改善他们新的 developer tool,将会有这个功能。
Safari、Opera 与 IE 支援这个功能也是迟早的问题
(Opera Dragonfly 是 open source,
如果你想贡献 Source Maps 的支援度,快去吧!)
在 Mobile browser 上也会拥有远端 debug 的功能,几乎所有浏览器都有:
Android 版 Chrome、
Firefox(快了)、
Opera(早就有了)、
Safari(虽然只有在 iOS 模拟器上,不过有用 UIWebViews 的 application 也行)。
结合这些功能,你就会有一个不用 plugin 的 Dev Mode 代替品,
那就是 Super Dev Mode 啦。
所以,怎麽运作的?
Super Dev Mode 用另一种实作方式来取代 Dev Mode 中的 code server,
它仍然会提供程式码给 browser,
但是将你的 Java 程式码 compile 成没有最佳化的 JavaScript
(又名 draft,也叫做 Super Draft Code)。
现在,你可以在任意的 HTTP server(包含 Dev Mode)上
执行你的 application,因为 Super Dev Mode 跟 Dev Mode 不同,
就只是个 code server。
这表示必须 compile 一次你的 application
(如果用 Dev Mode 当 HTTP server 就可以不用)。
在确认稳定之前,你必须自己设定 devModeRedirectEnabled 这个属性为 true,
让 compile 时能启动 Super Dev Mode。
Super Dev Mode 也需要使用 xsiframe 这个 linker,
所以你需要把下面这两行加到 GWT module 中
(记得在产出 production 时拿掉第二行)。
<add-linker name="xsiframe" />
<set-configuration-property
name="devModeRedirectEnabled" value="true" />
在载入你的 application 之後,
启动 Super Dev Mode 就只需要点一个 bookmarklet。
这个 bookmarklet 会 inject 一段 script 到页面中,从 code server 读取资料、
列出哪些 GWT module 已经被载入、并问你要 debug 哪一个?
然後它会抓取 browser 的 deferred-binding 值,
向 code server 要求 compile 相关的 permutation,
接着重新载入页面来使用
(有些资料存在 browser 的 session 储存区中,
并且在载入时触发 script 的 injection
以从 code server 载入 application 而不是从 HTTP server)。
因为 compile 是弹性的,它只会发出单一 permutation,
compile 过程会在 10 秒内完成... 至少是以此为目标
(有些 generator 还没有更新到能享有 incremental generation 的好处,
会拖慢 Super Dev Mode)。
你可以在 Chrome Developer Tools 中看到你的 Java code,
然後你可以设定中断点、观察变数......等等,
就跟你在 Java IDE 选择对一个 Java application 作 debug 一样,
只不过你是在 browser 上头 debug JS。
还有一个优点是 Dev Mode 绝对没有的,
就是你可以跳进 JSNI method、然後观察里头的变数。
如果你的 browser 不支援 Source Maps,
JavaScript 会以 -style PRETTY 的方式 compile,所以会相对好读许多;
不过还是用 Source Maps 比较优
(就像用 Source Maps 来 debug CoffeeScript 会比较好一样)。
你可以改变你的 code(在 Vim 或 Eclipse),
当你觉得可以测试时,不用像之前 Dev Mode 一样 reload 页面,
而是再按一次 bookmarklet。
要关闭 Super Dev Mode,
有另一个 bookmarklet 可以清除 session 然後 reload 页面,
compile 过的 application 就会载入。
当存取 code server 的 web 介面时(预设是
http://localhost:9876),
bookmarklets 就会出现,直接把它们拖曳到你的书签列中。
总结来说,Super Dev Mode 载入一个有弹性的 GWT compiler,
有一个 endpoint 会尽快地以 on-the-fly 的方式
重新 compile 一个 permutation,
然後提供这些档案以及相关的 Source Maps 与 Java source 档案。
限制与安全性
技术上来说,目前 compile 需要用 JSONP 来触发,
因为得绕过 Same Origin Policy。
我们一直在讨论要改用 CORS,
它的优点是允许将 application 的 origins 加到白名单上
(当你忘记把你的 application 加到白名单上、
或是忘记启动 code server,
client-side 的error-detection 会发出警告)。
Super Dev Mode 每次会在新的目录下 compile 你的 application,
所以 server-side 的 code 不会有 .gwt.rpc 档,
直到你把它们复制到 war 目录下、
或是改写 loadSerializationPolicy 去搜寻你的 Super Dev Mode app space
(虽然我很怀疑能否在 App Engine 中使用)。
用 RequestFactory 应该不会有什麽问题。
接下来呢?
Super Dev Mode 仍然是一个比实验阶段还实验阶段的功能,现在还不要期望太多。
非常欢迎你们的回馈意见,
无论是以错误回报的方式,
还是在论坛中提出建议。
Super Dev Mode 会包含在 GWT 2.5 中,
然後 deploy 到 Central Repository(给 Maven、Gradle、Ivy 等使用者)。
期待在 2.5 版发布之後,
Super Dev Mode(如同其他 GWT 中的改变)会有更多改善 :-)
--
钱锺书:
说出来的话
http://www.psmonkey.org
比不上不说出来的话
Java 版 cookcomic 版
只影射着说不出来的话
and more......
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.25.2.60