跨年前兩天,Dan Abramov在Twitter上提了一個問題:
JS社群毫不猶豫的拋出了它們對於新科技的預期與期待,本文內容也是總結自Twitter的回复,依照流行度降序排列。有一個尚未確定的小點是既然函數式程式設計不再是少數派,是否要把它踢出紅毯呢?
去年筆者就表示過了對於WebAssembly的期待,WebAssembly就是面向Web平台的底層程式碼。其初衷是希望能夠讓所有語言都能夠編譯並運行到Web平台,這點對於許多函數式程式設計、響應式程式設計的粉絲充滿吸引力。特別是隨著這幾年JavaScript社群的突飛猛進,很多開發者並不能跟得上這門語言衍化的速度,因此他們也非常希望能夠直接用自己習慣的語言而不是要去重頭學一門從入門到直接放棄的語言。不過JavaScript目前還處於明顯的上升勢頭,暫時還沒有人唱衰它。而WebAssembly仍處於襁褓中,才進入到預覽階段,離真正的發布還有很長的距離。總結而言,筆者建議我們都應該對WebAssembly保持一定的關注,畢竟它會對未來的JavaScript造成極大的影響。如果你對WebAssembly有興趣,那麼推薦閱讀Eric Elliott的相關部落格。
筆者個人不太意願使用Elm,不過其特性還是很有借鑒價值
2016年不少的開發者參與到Elm的開發中,Elm不只是JavaScript的擴充函式庫,而是可以編譯到JavaScript的程式語言,對於許多熱衷於函數式程式設計的開發者來說是個不錯的選擇。參考Elm 入門介紹,Elm提供以下特性:
並不會存在執行階段錯誤,沒有null,沒有undefined is not a funtion。
非常友善的錯誤提示訊息能夠輔助你開發。
比較嚴格的程式碼規格與專案架構,保證了你的應用程式在快速迭代中依然保持著最佳實踐。
自動為所有的Elm套件新增語意版本描述。
總而言之,Elm為我們提供了優秀的工具來保證編寫乾淨、簡單與碎片化的程式碼,並且因為Elm是可以編譯到JavaScript,因此許多JavaScript開發者都可以保持下關注或嘗試下。
Babili最早於2016年8月份發布,它是基於Babel工具鏈上的支援原生ES6語法的壓縮工具。 Henry Zhu在這篇文章中稱述了為什麼我們需要另一個壓縮工具,關鍵點如下:
目前大部分壓縮工具只能夠處理ES5程式碼,因此在壓縮之前需要先進性編譯,而Babili能夠支援直接輸入ES2015+。隨著瀏覽器效能的提升,越來越多的瀏覽器支援直接執行ES2015的程式碼,因此我們不需要再進行轉換編譯。另外Babili也可以作為Babel preset引入到現有的Babel配置中,也可以作為直接使用的命令列工具。
這裡舉個簡單的例子,我們寫瞭如下的ES6類別:
class Mangler { constructor(program) { this.program = program; } } // need this since otherwise Mangler isn't used new Mangler();
之前,利用傳統的Babel進行編譯與壓縮,會得到如下程式碼:
// ES2015 code -> Babel -> Uglify/Babili -> Minified ES5 Code var a=function a(b){_classCallCheck(this,a),this.program=b};a();
而Babili的效果如下:
// ES2015 code -> Babili -> Minified ES2015 Code class a{constructor(b){this.program=b}}new a;
OCaml本身和JS沒啥關係,不過列表接下來的兩項都是基於OCaml,因此還是要先介紹下。如果你已經關注了近兩年來的函數式程式設計崛起之路,你或許聽過Haskell。而得益於OCaml能夠編譯到就S,其以後來居上的姿態凌駕於Haskell。 Facebook的許多開發者都是OCaml的粉絲,他們的Hack、Flow以及Infer都是基於OCaml建構的。
BuckleScript是基於OCaml實作的服務端框架,由著名的Bloomberg團隊創造而來。 Duane Johnson對他們的解釋如下:
BuckleScript或bsc,是基於OCaml編譯器的相對較新的JavaScript服務端框架。換言之,你可以使用優秀的函數式、自備類型的OCaml語言,同時也能繼續背靠基於npm套件管理器的Web生態系統。
我們來簡單的看下BuckleScript程式碼風格,譬如用BuckleScript實作簡單的服務端:
let port = 3000 let hostname = "127.0.0.1" let create_server http = let server = http##createServer begin fun [@bs] req resp -> resp##statusCode #= 200; resp##setHeader "Content-Type" "text/plain"; resp##_end "Hello world\n" end in server##listen port hostname begin fun [@bs] () -> Js.log ("Server running at http://"^ hostname ^ ":" ^ Pervasives.string_of_int port ^ "/") end let () = create_server Http_types.http
編譯輸出為:
'use strict'; var Pervasives = require("bs-platform/lib/js/pervasives"); var Http = require("http"); var hostname = "127.0.0.1"; function create_server(http) { var server = http.createServer(function (_, resp) { resp.statusCode = 200; resp.setHeader("Content-Type", "text/plain"); return resp.end("Hello world\n"); }); return server.listen(3000, hostname, function () { console.log("Server running at http://" + (hostname + (":" + (Pervasives.string_of_int(3000) + "/")))); return /* () */0; }); } create_server(Http);
OCaml最大的特性就是其函數式語言特性,我們再看下其對於不可變類型的支持,我們使用OCaml stdlib實現的不可變類型如下:
module IntMap = Map.Make(struct type t = int let compare (x : int) y = compare x y end) let test () = let m = ref IntMap.empty in let count = 1000000 in for i = 0 to count do m := IntMap.add i i !m done; for i = 0 to count do ignore (IntMap.find i !m) done let () = test()
而如果要用Facebook Immutable實現的代碼為:
'use strict'; var Immutable = require('immutable'); var Map = Immutable.Map; var m = new Map(); function test() { var count = 1000000; for(var i = 0; i < count; ++i) { m = m.set(i, i); } for(var j = 0; j < count; ++j) { m.get(j); } } test();
效能評測下,二者的執行時間比較為:
BuckleScript: 1186ms
BuckleScript (production): 899 Bytes
JavaScript: 55.3K Bytes
ReasonML与React师出同门,是基于OCamel设计的语法友好、编辑器支持程度高,并且有强大的编译工具支持的语言。建议阅读Sean Grove对ReasonML的介绍。本文简单介绍几个JavaScript与Reason的语法对比:
元类型| JavaScript | Reason |
333.14153.1415″Hello World!”"Hello world!”‘Hello world!’Strings must use “Characters are strings’a'truetrue[1,2,3][1,2,3]null()const x = y;let x = y;let x = y;reference cellsvar x = y;No equivalent (thankfully)[x, ...lst] (linear time)[x, ...lst] (constant time)[...lst, x] (linear time)Not supported{…obj, x: y}{…obj, x: y}
表达式| JavaScript | Reason |
login ? “hi” : “bye”login ? “hi” : “bye”let res = undefined;switch (thing) { case first: res = “first”; break; case second: res = “second”; break;};`let res = switch thing {first => “first”second => “second”}; `
另一个强类型、高性能的能够编译到JavaScript的编程语言,其定位与Elm类似,主要特性为:
没有运行时错误
严格的,类似于JavaScript的计算
支持JavaScript 对象语法
提供相较于Hashkell更强大方便的类型系统
更方便地JavaScript库集成
Dan Abramov说过,Webpack的定位就是在相对底层,因此将配置以编程块的方式实现会更加完备。
const { createConfig, defineConstants, env, entryPoint, setOutput, sourceMaps } = require('@webpack-blocks/webpack2') const babel = require('@webpack-blocks/babel6') const devServer = require('@webpack-blocks/dev-server2') const postcss = require('@webpack-blocks/postcss') const autoprefixer = require('autoprefixer') module.exports = createConfig([ entryPoint('./src/main.js'), setOutput('./build/bundle.js'), babel(), postcss([ autoprefixer({ browsers: ['last 2 versions'] }) ]), defineConstants({ 'process.env.NODE_ENV': process.env.NODE_ENV }), env('development', [ devServer(), devServer.proxy({ '/api': { target: 'http://localhost:3000' } }), sourceMaps() ]) ])
GraphQL是个不错的REST替代查询语言,特别是对于那些拥有大量数据的公司。这个案例分析很好地阐述了从REST到GraphQL的转变之路。我能够想象2017年GraphQL会继续处于上升势头,不过要谈到真的大规模实施,还要到2018年吧。
相信大家对于React Storybook并不陌生了,你能够独立于应用而交互式的开发你的组件,就如下图所示:
爷爷辈的jQuery仍然处于不断的迭代更新中,可能很多开发者忽略了2016年6月份发布的jQuery 3.0版本,可以参考这里获取更多信息。
如果你打算在浏览器中实现精彩的2D效果,特别是对于使用WebGL的游戏开发者,Pixi.js是个值得一看的库,可以参考这里获取更多的Demo。
非常优秀的React的替代库。
Rust可以编译到JavaScript啦(通过emscripten)。
Custom Elements(包括Shadow DOM)一直不被主流的开发者接受,不过看似2017这一点将会发生些许变化。变化的关键因素在于浏览器支持比例的改善。个人还是蛮期待Custom Elements的,可以关注SmashingMag或者Google’s关于Custom Elements的解释。
很难相信WebRTC已经五岁了,Facebook、Slack、Snapchat以及WhatsApp都在他们的服务中集成了WebRTC。可以预见WebRTC会在2017年被更多的公司采用,蒸蒸日上。
Next.js是个基于React、Webpack与Babel构建的,支持服务端渲染的小框架,其来源于ZEIT团队,在React社区获得了不小的关注度。
以上就是2017 年值得一瞥的 JavaScript 相关技术趋势的内容,更多相关内容请关注PHP中文网(www.php.cn)!