投資本地技術產業

上星期的公司的活動,很榮幸的能面對面和紐西蘭辦公室的 Robert O’Callahan (:roc) 聊到一些關於本地技術產業與矽谷關係的問題。問了之後才知道 roc 是在矽谷工作 10 年之後才反過來決定回到紐西蘭的。2005 年,他和 Mozilla 的雇用協議就是讓他成立紐西蘭辦公室,讓他可以在當地帶技術人貢獻 Mozilla Project。

問他這樣會不會影響他自己的職涯,他說會,如果他要當 VP 或是 Senior VP,大概真的就得一直待在矽谷,但是他選擇回鄉,投資本地的技術產業。他一路說到,如果 Mozilla 有一天無法支撐這個辦公室了,他自己應該有能力做一些事情繼續下去,例如開一間公司來養。在 Mozilla Project,roc 和奧克蘭辦公室負責 Gecko 大部分的 Graphics codebase。他最近也獲得了 Mozilla Distinguished Engineer 的殊榮。

為何會聊到這個,也是因為看到台灣業界的一些感想吧!可能在職涯的年資或是地位不同,如果有機會,大部分的人是會選擇去國外工作的。創投甚至公開以「獲得投資就可以去矽谷工作」為號招。而在矽谷創業的勇敢台灣青年,會把技術團隊留在台北,通常都是因為節省開銷,而不是為了深耕以及貢獻台灣的產業發展。

紐西蘭比起台灣的狀況是比較艱鉅的:地理位置在世界的邊緣、經濟規模渺小、都講英文,所以一直被澳大利亞或是美國 Brain drain。而在商言商,或是追求個人價值最大化並沒有錯。我也說不上來當我面對同樣的機會或是在同樣的資格時會做出什麼決定。但是當自己都不幫忙自己的時候,求別人是不會有什麼結果的。

about:mozilla 更新

這篇文章原刊登於謀智台客,公司的技術 Blog,歡迎訂閱。

用過 Firefox 等 Mozilla 系列瀏覽器的朋友,或許知道 Mozilla 瀏覽器都內建一份 about:mozilla 頁面。該頁以深紅色為底,節錄一本不存在的《Mozilla 之書》,以基督教聖經的語調講述 Mozilla 的歷史。

在 Netscape/Mozilla 的歷史中,about:mozilla 改版了 6 次。就如聖經一樣,都是用寓意的方式將網路的現狀,以及 Mozilla 挑戰與行動記錄下來。Wikipedia 的條目詳列了先前各個版本的原文與寓意。簡略來說:

  • 12:10:1995 年撰寫,提到了當時主流瀏覽器(Nestcape)如何面對新瀏覽器的競爭,以及 Netscape 推出的私有標準。
  • 3:31:1998 年 3 月 31 日,Netscape 將 Mozilla 原始碼公開。這個章節寫出了 Netscape 對 Mozilla 開放原始碼後的期許。關於這段故事可以參考紀錄片《Code Rush》。
  • 7:15:2003 年出現在 Firefox 1.5 之中的章節。描述 Netscape 被收購,Mozilla 浴火重生,以 Firefox 和 Thunderbird 這些新產品重新撼動市場。
  • 8:20:2007 年出現在最後一個版本的 Netscape Navigator,描述 AOL/Netscape 產品與 Mozilla 基金會原始碼/產品的平行關係。
  • 11:9:2008 年更新的章節,描述 Internet Explorer 停滯更新之後,Firefox 所帶動的瀏覽器市場文藝復興,直到微軟開始反應 Mozilla 在市場的威脅,重新推出新版 Internet Explorer。

目前的版本為章節 15:1,今年 1 月剛剛更新:

瑪門的雙生子發生了爭吵。他們的交戰使世界進入了一個新的黑暗,而野獸憎恨黑暗。於是它迅速的採取行動,變得更加強大,並不斷地前進和繁衍。野獸為黑暗帶來了火焰與光明。

關於這個章節的討論與寓意可以參考 Bug 上的討論。「瑪門的雙生子」比喻 Apple 與 Google 在手機作業系統上的競爭以及平台的私有化。Mozilla,即「野獸」,在新的時代則推出了 Firefox OS、Firefox for Android 以及高速釋出開發週期以面對新的挑戰。

One scope per module, or, on success of adoption of CommonJS module format

I recently did some research on well-known Javascript module formats. Not sure why I missed this topic back in 2009, however some archeology revealed an conflicting reality:

  • The most accepted package format, for Javascript in general, is the CommonJS format.
  • However, the format is unfriendly to browser context, and it’s impossible to implement the loader 100% correctly.
  • In the browser, people ended up using AMD format instead. Also, AMD try to incorporate CommonJS format by introducing special dependency names; see the 3rd and 4th paragraph of the spec.

For years, a lot of discussion on the difference of the formats surrounds the sync v.s. async nature of the format. jrblake, the author of the AMD spec and require.js, have already explicitly explain his argument on why he disagreed with the trade-offs made in the CommonJS module format.

However, I still ended up drawing the conclusion of my research — as of 2013, CommonJS modules is more welcomed to the developers than AMD modules. But why? In my humble opinion, of all the differences in design between CommonJS module and AMD module, this one stands out and made the difference: CommonJS module spec requires one scope per module. This in turn gives CommonJS modules the following behavior:

  • Every module get a private scope, for free — the only things expose to others are the ones you explicitly expose in the exports object.
  • In return, module scripts don’t get to access the globe object of the main context — e.g. the window object in browsers. This has significant implication — module scripts can never take global APIs for granted — one would have always explicitly require() for it. On the other hand, one could never mess up with the dependency system by attaching fake fake APIs on the global object — everyone has to be honest to the dependency tree, and the loader.
  • Without the global object, native APIs available to the module would also need to be require()‘d. This in turn provided an uniform experience for the developers, which is extremely helpful to new Javascript runtime/platforms, both on inventing one and on learning one. With that, it is not surprising almost every “new kid in town” adopts CommonJS modules, e.g. NodeJS, PhantomJS, and Mozilla Add-on SDK.
  • Limiting one file per module is pretty much an outcome of the scope design. It will be really hard to define scope syntax, to house multiple scopes within one file, and it will be even harder to implement.
  • Same applies to sync dependency loading. If modules are loaded in their own scope, they could surely block the execution of requestee.
  • Lastly, and sadly, one of the drawbacks of the one scope per module design: you can never ever simulate private scope in the browser reasonably. One could surely wrap CommonJS module into a function scope, or simulate sync loading with sync xhr and eval() (Yabble), but one would never stop script within from referencing variables on the outer scope s (except running your own Javascript runtime on top of the native Javascript runtime, I presume).

What does all that means

For someone who write Javascript for the browsers most of the time (we all are I think), I hate to be the proponent of something that doesn’t work in the browser context. What’s good come out of CommonJS module spec is all begin with the decision to ditch the browser. Alternatively, the legacy limitation of the browser is just too heavy for AMD module format to carry — thus, the AMD format never propagates, beyond browser, so does the promise to Javascript modules debate to the developers — you should be able to write your code once and use it everywhere.

What is broken, for modern day needs, is the browser context, not AMD, which tried really hard to address it. What AMD proofed is that we need new language feature, or browser APIs, to cope what we are facing. Hopefully, the new ECMAScript Harmony module is being worked on in Gecko and will be landed soon. How Harmony module could deliver the promise is not the scope of this article; it would be a further pending research topic for me.

An unified Javascript ecosystem awaits

Javascript, 18 years after invention, a fundamental cornerstone is still missing for building a library repository, like what PEAR for PHP, CPAN for Perl, or RubyGems for Ruby. The momentum is there already, and it had been there, for a long time. npm could be considered the most promising one, however, again, the lack of a common module format limits the uses of the modules on the site.

It also limits people writing heavy client-side web applications — people is currently prevented to split their apps into modules agnostically of any frameworks. This is worse than PHP, in which the frameworks have already start working together on common standards, i.e. PSRs.

We are still eagerly waiting another universal Javascript module format, to ignite everything and to start realize all the possibilities. I remain optimistic on this issue given the wide acceptance of the language itself had attracted lots of talents. But, first step toward the solution at full speed is to admit there is one.