熟悉本專欄的朋友們可能都了解,筆者CSDN的博客和公眾號上的發文,基本上專注于金融資料庫和芯片等一些偏后端的領域,不過去年筆者發了兩篇純前端的文章《兩行代碼引發的血案》和《Flash已死,Deno當立》,這兩篇文章在CSDN公眾號上發表以后,筆者甚至一直沒有勇氣點開鏈接多看一眼,因為這兩篇基本都是為紀念司徒正美老師而寫的,
我和司徒結識于CSDN,在2019年6月中旬當時在CSDN上看到一篇博文《前端開發 20 年變遷史》,心中不由贊嘆,竟有人能將前端技術上升到哲學高度來進行闡釋,于是千方百信找到了司徒的微信加為好友,和司徒聊天中,明顯能感受到他對于前端技術的理解深度和積極熱情,誰知天有不測風云,司徒年紀輕輕竟然溘然長逝,在此筆者也提示各位讀者朋友們保重身份,切莫透支健康,

因此清明時節再發此文,一是紀念司徒老師,二是致敬那個曾經風靡一時的前端技術Flash,由于前端并不是筆者的領域,如有錯漏還請各位讀者批評指正,
只見新人笑,不見舊人哭的前端世界
去年年底微軟正式全面移除了對于Flash的支持,無論是經典版的Edge(Spartan)、還是IE11都徹底告別了Flash插件,在早在2015年開始,谷歌的Chrome就開始逐步進行去Flash操作了,Flash的壽終正寢使這項在 PC 時代立下汗馬功勞的互動影片技術,被H5這項新興的前端技術徹底拍倒在岸上了,
今年3月2號deno1.8正式版發布了,Node.js之父Ryan Dahl 認為他在設計 Node.js 時犯一些包括安全性、package.json、node_modules等等一系列的錯誤,并表示這些bug 問題嚴重且不可回避,于是他在一系列的前端大會上都在怒懟Node,并在去年重新設計了 Deno 這門腳本語言,眼看著Flash和Node的滑落,也徹底澆滅了筆者這個門外漢想學習前端技術的熱情,面對著變化莫測的技術堆疊,前端世界的程式員前浪們是不是太難了?
致敬-短視頻和小游戲的共同始祖,曾經無比輝煌的Flash
Flash 誕生于 1990 年代初期,當時,FutureWave 推出了一款名為SmartSketch 圖形軟體,它使用觸摸筆而不是鍵盤來操作,后來,FutureWave又將SmartSketch 重新設計成一款能在靜態網頁上插入影片和視頻的工具,取名 FutureSplash Animator,它就是 Flash 的前身,
從90年代末到2006年左右,Flash獲得了極速的發展,與目前所有IT培訓機構都教Python的情況不同,當時的程式員如果不和人聊聊網頁三劍客,簡直出門都不好意思和人打招呼,而Flash作為三劍客中的絕對C位,風頭一時無兩,
說幾個暴露年齡的梗,比如2003年一則Flash視頻《大學生自習曲》突然紅遍整個網路,據不完全統計在在其推出的一個月內,其播放量就突破了一億次,而這可以說是短視頻的始祖,后來如《東北人都是活雷鋒》等神曲,也都為Flash火爆網路不斷的增添動力,而且Flash也還是網頁游戲的始祖,最早如《打飛機》、《超級賽車》等經典小游戲,也都是基于Flash的,可以說Flash能夠爭霸PC時代的一個重要原因,就是它極大的降低了制作影片的技術門檻,使得創意產業得到了極大的發展,當時各大廣告公司將 Flash 視為非常重要的工具,在2006年之前Flash一直被認為會是互聯網上“永恒的存在”,
成敗皆插件
Flash特別適用于低速互聯網的內容,因為它的檔案非常小,Flash是通過廣泛使用矢量圖形做到這一點的,與位圖圖形相比,矢量圖形需要的記憶體和存盤空間小很多,因為它們是以數學公式而不是大型資料集來表示的,我們可以看到一般來講Flash每分鐘影片的大小一般不到1M,遠比目前的高清視頻小得多,可以說體積小,用戶體驗卻很高的優勢,正是Flash在十幾年前稱霸互聯網的不二法門,
?而也正是因為放棄使用普通的圖片格式而使用知量圖形,這使得Flash并不是瀏覽器原生的,矢量圖的渲染Flash的瀏覽器插件的運行效率并不高,而且訪問電腦資源也很不方便,導致很多程式員在開發的程序中出現許多的問題,就算成功發布了一款 Flash 應用,瀏覽器也會被 Flash 插件拖得很慢,電腦會因此變得很卡,所以 H5 技術出現后,很多人就開始轉投到轉而開發基于H5的互動技術,并開發出了如Hilo等新型互動框架,不過憑心而論Hilo其實并不是Flash的終結者,一切都在IPhone開啟了移動時代之后全部都變了,
錯失移動時代的Flash
2007 年,蘋果推出了初代 iPhone,Adobe 的工程師自然也很快地接受并使用了它,iPhone 的出現給 Adobe 移動端開發帶來了問題:Flash插件運行的缺點,被無限放大了,由于Flash日益臃腫,需要大量計算資源才能支持其影片的渲染,這在 PC 端并沒有問題,而在手機端,Flash的運行需要消耗大量的電力,但手機的電池有限,以至于蘋果選擇不支持 Flash,Flash 需要重新開發才能適應 iPhone,然而 Adobe 并未能和蘋果達成最終的合作協議,這個決定為蘋果招來了不少批評,人們認為喬布斯不支持 Flash 反應了蘋果的封閉,為此,喬布斯在 2010 年發表了一封公開信,表示“iPad 永遠不會支持 Flash”,并指出了 Flash 的問題:耗電嚴重、安全漏洞多,不適合蘋果的移動系統,
蘋果的表態之后,視頻生態開始轉向,YouTube 等網站開始采用基于開放標準的免費軟體,這種技術既適合桌面端也適合移動端,2014 年10 月制定的 HTML5 標準也成為 Flash 的替代品被廣泛使用,它讓網站在沒有插件的情況下運行視頻和影片,而 Adobe 自身也認為,Flash 對該公司的業務不太重要,Adobe CEO Shantanu Narayen 表示,現在,Flash 僅占 Adobe 營收總額的一小部分,因此也沒有對Flash進行持續進行輸血,這也加速了Flash的落漠,
同樣也是由于Flash插件運行缺點,使其近年來頻繁爆出安全漏洞,這無疑給 Flash 帶來了更大的打擊,Gartner高管Danny Brian 在2014年就曾表示,Flash 的消亡已經不可避免,
Node之父反出Node,問題出在哪里
去年底,Node.js之父Ryan Dahl在柏林JS大會上發表了題為“Design Mistake in Node”的主題演講,并提出“Node失誤太多無法回避,Deno前景明朗”其中Deno就是Node的反寫,其也有內涵反Node的意味,目前看Node與Deno的主要引數比較如下:
| 專案 | Node | Deno |
| 入口 | package.json配置 | import url 直接引入 |
| API 引入方式 | 模塊引入 | 全域物件 |
| 安全 | 無安全限制 | 默認安全 |
| Typescript | 第三方,如通過 ts-node 支持 | 原生支持 |
| 包管理 | npm + node_modules | 原生支持 |
| 異步操作 | 回呼 | 原生支持Promise |
| 包分發 | 中心化 npmjs.com | 去中心化 import url |
| 打包、測驗、格式 | 第三方eslint、gulp、webpack、babel | 原生支持 |
我們看到Node.js并不能像Deno一樣原生支持異步操作,這還在去年年中引發了一場大規模的“血案”,在is-promise(npm地址:https://www.npmjs.com/package/p-is-promise,Githubf地址:https://github.com/sindresorhus/p-is-promise)更新后,超過300萬個參考了該模塊的前端專案均出現了問題,甚至讓整個 JavaScript 生態系統陷入了混亂,
Node.js中需要通過promise機制實作異步回呼功能,而根據MDN上對于Promise機制的描述(https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise),Promise物件是一個代理物件(代理一個值),被代理的值在Promise物件創建時可能是未知的,它允許你為異步操作的成功和失敗分別系結相應的處理方法(handlers), 這讓異步方法可以像同步方法那樣回傳值,但并不是立即回傳最終執行結果,而是一個能代表未來出現的結果的promise物件,示例及注釋如下:
//創建一個Promise物件,定義resolve方法,在3000ms后執行,
const promise1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('promise');
}, 3000);
});
//非阻塞執行promise1,在promise完成后此方法會被執行,
promise1.then(function(value) {
console.log(value);
// 3s后會輸出promise
});
console.log(promise1);
//直接輸出 [object Promise]
而本次出現問題的is-promise包,就是用來測驗一個JavaScript物件是否為Promise的,is-promise包的代碼其實非常短,其主要的功能實作代碼只有兩行而已,前端開發人員在引入is-promise包之后,就能在自己的專案中引用它,而且is-promise包是基于MIT協議的,因此參考該專案,也不必須要求開源,雖然只有兩行代碼,但is-promise 庫卻是當今最受歡迎的 JavaScript 軟體包之一,據不完全核計is-promise是700余個知名的JavaScript 庫的依賴項,其影響專案數量至少超過300萬,范圍涵蓋至封閉源 JavaScript 代碼庫和 JavaScript 生態系統中一些最大的專案,其中包括有:Facebook 的 Create React App(用于創建 React 應用程式的標準模板)、谷歌的 Angular.js 框架、谷歌的 Firebasse-tools、亞馬遜的 AWS Serverless CLI、Nuxt.js 和 AVA 等,
is-promise 庫之所以引發問題,關鍵在于他沒有遵循正確的ES模塊標準,而提到ES模塊標準,我們還要從最基本的概念聊起,我們知道JavaScript是一門動態的腳本化的語言,它使得前端頁面的開發變得非常簡單,JavaScript的編程范式抽象成維護變數,賦值和計算操作,大量的代碼在用于操作變數,開發者需要懂得如何去組織和維護這些變數,JavaScript 提供了一種方式,即函式作用域,在一個函式內只需要考慮這個函式的變數問題,不必去擔心其他函式會操作這些變數,當然,隨之帶來的問題是,變數無法共享,無法在不同的函式之間相互共享變數,如 果想要在作用域外共享變數,只能通過外層作用域,或者全域作用域,
而ES模塊標準,則提供了更好的方式來組織變數和函式,把相關的變數和函陣列織到一起,具體就是將這些函式和變數放到一個模塊作用域內,實作在模塊間共享變數,與函式作用域不同的是,模塊內部的變數實作了在其他模塊內共享,而且可以指定哪些變數、類或者函式可以共享,在其他模塊中共享,被稱為 export,這就出現了模塊間的依賴,是一種很明確的關系,當移除一個模塊時可以準確的知道哪些模塊會出錯,一旦有了模塊間匯出和參考變數的能力,我們就可以將代碼打成小包,然后就可以像樂高玩具那樣組合,再組合,使用小模塊就可以創建出各類應用,在使用模塊的時候,其實就是在做一個依賴關系圖,ESM的模塊包括三個程序:
1:構建:下載,決議,然后把檔案決議為模塊記錄
2:實體化:為模塊分記憶體空間(此時還沒賦值),然后依斬訓入,匯出陳述句把模塊指向記憶體地址,這個程序叫鏈接
3:運行(求值):運行代碼的時候,才會給記憶體空間填充真實的值
而ES則通過一系列的標準來確保相關代碼可以實作上述模塊化的功能,
is-promise v.2.2.0 版本卻未遵循正確的 ES 模塊標準,因此在其更新發布后,參考了is-promise在各個專案都在的構建鏈時出現了問題,
后記
從Flash和Deno的情況可以看出,互聯網世界曾經的繁榮真的不能代表未來可以一直高枕無憂,就像Flash一樣,曾經紅極一時的霸主也難逃最終的落莫結局,不過筆者看到程式員對于這種變化卻是比較樂觀,最后筆者參考司徒老師的名言做結“當初JavaScript被誤解為最糟糕的語言,時至今日它是最流行的語言,GitHub 60%的專案都是與JavaScript有關,任何可以使用JavaScript來撰寫的應用,最侄訓由JavaScript撰寫,”愿前端開發之路越來越好!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/273324.html
標籤:AI
上一篇:困在“墻”里的中年程式員
