日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Dreamwear如何创建javascript_JavaScript 太糟糕,JVM 有妙招!

發布時間:2025/3/11 javascript 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Dreamwear如何创建javascript_JavaScript 太糟糕,JVM 有妙招! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

雖然 JavaScript 憑借其簡潔性、交互性等優勢橫掃了各大編程語言榜單,但是一直以來,JavaScript?應用程序的工具鏈極其復雜,引發不少開發者吐槽,在此,我們是否有更好的解決方案將其替代?

接下來,本文中將分享幾個 JVM 的替代方案,希望對大家有所裨益。

作者 |?Renato Athaydes

譯者 | 彎月

責編 | 屠敏

出品 | CSDN(ID:CSDNnews)

以下為譯文:

我是一個主要從事后端的開發人員,但時不時地也需要做一些前端工作。因為有時在個人的項目中也會用到前端。

出于這個原因,我一直在遠遠地關注JavaScript的發展,但說實話我并不喜歡JavaScript的世界。

我最不喜歡的一點是專業JavaScript應用程序的工具鏈極其復雜。從前,你只需要寫幾行HTML,然后用瀏覽器打開(file:///home/me/index.htlm)即可,在添加動態效果的時候只需要鏈接一個簡單的JS文件,然后刷新一下頁面就好了,但是這樣的日子已經一去不復返了。

JavaScript的MDN頁面(https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript)上展示的方法才是正確地使用HTML和JS的方法——不需要構建工具,也不需要框架。然而,很少有人聽得進去。

如今,JavaScript的工具鏈包含了后端工具鏈所有的復雜性,有過之而無不及。甚至就在幾年前,工具鏈的許多部分和現在都是不同的!看看StackOverflow上一些問題的答案(https://stackoverflow.com/questions/1480186/what-is-in-your-javascript-toolchain),你會有覺得很有意思。

這個Pluralsight JS開發環境(https://github.com/coryhouse/javascript-development-environment)建議你利用32種工具來構建你的應用程序(例如babel、chai、cheerio、eslint、mocha、webpack ......)。

2016年的這篇文章(https://italonascimento.github.io/configuring-a-basic-environment-for-javascript-development/)中記錄了在Google和DuckDuckGo中搜索基本的JS開發環境時,搜索結果中包含哪些工具:

  • 依賴管理工具(npm或yarn)

  • 模塊打包(webpack或gulp、browserify、bower)

  • ES6編譯(babel)

  • 任務自動化(npm腳本)

  • 實時重新加載(live-server)

如果你按照上述文章的說明操作,那么最終會得到3個配置文件(npm、babel和webpack每個工具各一個),你需要通過嵌入到JSON配置文件的shell腳本來管理構建的過程,而且你的項目需要通過編譯和實時重新加載HTTP服務器才能運行。

我認為如果我需要編譯東西,那么至少我應該使用編譯器來檢查我的代碼!

那么為什么不試試TypeScript呢?!

于是,我按照這個教程(https://alligator.io/typescript/new-project/)所說,創建了一個TypeScript項目。

創建好后,除了前面提到的那些配置文件之外,我還多了兩個配置文件:tsconfig.json和tslint.json。

這一切太復雜了,所以Google創建了一個工具(Google TypeScript Style,簡稱GTS)來管理TypeScript配置。

我曾嘗試使用這個工具,然而,由于一些模塊相關的錯誤,瀏覽器拒絕運行我的JavaScript文件。我不知道在我使用的無數的工具中,哪一個可以解決這個問題,我快被這種錯綜復雜的工具逼瘋了,于是我決定尋找其他的解決方案!

在尋找的過程中,我發現了這篇優秀的博客文章(https://itnext.io/you-might-not-need-a-build-toolchain-324edcef7f9a),文中宣稱你不需要構建工具鏈。

這篇文章表明,你可以使用像React這樣的現代工具,就不需要構建工具了!然而不幸的是,一旦你開始使用依賴項,而且你的應用程序包含幾百行以上的JavaScript代碼,那么這種方法就不太實用了。

我又回到了原點。

似乎無論我們做什么,構建/編譯步驟都是一個避無可避的惡魔,而且長期以來在后端的開發工作中,我們了解了如何使用優秀的工具編寫大型應用程序,所以何妨在前端的開發中也嘗試使用這些工具呢?

畢竟,早在2011年,當我還在做Web開發時,就有人嘗試這種做法了……例如,2011年我曾使用過GWT(這是一個基于Java的Web工具包)……當然,8年后,基于Java的Web應用程序應該有了很多改進,不是嗎?

于是,我開始檢查都有哪些工具可以用。一個習慣了使用Java世界里優秀的工具和良好生態系統的后端開發人員能否進軍前端的工作,而不至于被JS世界里的瘋狂湮沒呢?

就讓我們拭目以待吧!

方法

為了在本文中比較每一種備選的方案,我決定仿照上述我提到的博客文章“不需要構建工具鏈”,創建一個非常簡單的計數器應用程序。

作為參考,以下是用React(沒有JSX)編寫的應用程序的代碼。

我比較不同備選方案的方法非常簡單:

  • 找一個入門教程,然后通過運行演示的應用程序,感受設置的難易程度。

  • 檢查框架與Java開發人員期望的契合程度。

  • 使用產品/框架提供的最基本的工具創建計數器應用程序。

  • 衡量應用程序的大小、代碼行數和性能。

  • 最后一個要點的靈感來自這篇博客文章“前端框架的真實比較”(https://medium.freecodecamp.org/a-realworld-comparison-of-front-end-frameworks-with-benchmarks-2019-update-4be0d3c78075)。

    應用程序大小是通過查看瀏覽器的網絡選項卡來確定的(為了避免使用依賴于大量非JS資源的框架,我包含了所有類型的資源)。

    對于性能,我使用了Google Chrome自帶的Lighthouse。

    以下是使用React的結果,僅供參考。

    為了進行比較,我選擇從本地服務器(而不是CDN)上下載并提供React JS文件。

    應用程序的大小:

    性能:

    好了,以上就是我們的對比標準。

    現在,讓我們來看看最原始的基于Java的Web工具包:GWT。

    GWT:Java-source-to-JS,服務器和客戶端框架

    網址:http://www.gwtproject.org

    GWT是第一個在沒有Applet或插件的情況下,在瀏覽器中使用Java的工具,創建于2006年。這是一項非常成熟的技術,但自2013年以來Google支持的框架不再支持GWT……我記得當時Google將其Web開發工作的重點放在了Dart上,而Dart作為JS的替代方案與GWT有著直接的競爭關系,而且當時的GWT社區已被人遺棄。不知怎地,GWT這個項目依然存在,所以我覺得我必須把它包含在這個比較中,這樣才能真正看出現代替代方案的狀況。

    如果你想使用GWT,那么可以按照官網的建議下載SDK或安裝Eclipse插件……我已經有很多年沒碰過Eclipse了(我改用了IntelliJ),所以我決定下載SDK:

    ./webAppCreator?-out?gwt-app?com.athaydes.GwtApp

    這個命令運行得非???#xff0c;而且還創建了一個Ant項目(什么東西?!)。我使用Java的時間已經超過了10年,而且我錯過了Ant的鼎盛時期——如果我沒記錯的話,Maven是Java的構建工具。

    但我不介意Ant!稍后我可以將其轉換為Gradle或Maven構建。而且IntelliJ可以很好地支持Ant項目,所以你可以在IntelliJ中打開這個項目,而且一切都會正常工作。

    運行演示應用程序:

    ant?devmode

    這一步可以打開一個Swing應用程序,你可以通過它控制開發服務器!我感覺它與2009年一模一樣!在瀏覽器上打開這個應用后,我發現除了一些新鮮的樣式之外,這個應用也幾乎沒有變化。

    演示應用會向你展示如何使用GWT最強大的功能:無縫的RPC框架讓開發人員幾乎忘記了客戶端和服務器之間的區別,兩者之間的通信猶如調用Java方法一樣簡單。

    但是在構建計數器應用的時候,我們并不需要兩者之間的通信。所以,我做的第一件事就是從入門應用中刪除RPC的代碼。

    一般來說,GWT應用程序只包含一個源代碼根,它分為:

    • 客戶端:僅在瀏覽器中運行的客戶端代碼。

    • 服務器:服務器端代碼,即后端。

    • 共享:客戶端和服務器皆可見的代碼。

    你可以通過應用最頂層軟件包的GwtApp.gwt.xml文件,設置應用客戶端可以看到哪些軟件包。該文件還可以控制應用應該使用的GWT主題,因此你可以很輕松地在應用中使用黑暗主題。

    在這個入門的應用程序中,Java源代碼位于src/目錄下,而Web的源代碼位于war/目錄中。初始頁面的HTML文件是war/GwtApp.index.html。打開這個文件,你可以看到一個非常普通的HTML,但奇怪的是,大部分視圖都已經實現了(利用

    我想用自己的代碼實現視圖,所以我刪除了這個

    在基于小部件的API的幫助下,在GWT中實現用戶界面是一件非常容易的事情。因此,我在5分鐘內就創建計數器應用(請不要忘記我之前有過使用GWT的經驗,即便我幾乎什么都想不起來了)。但是,當我嘗試重新編譯代碼時,遇到了lambdas的錯誤——ant文件說我們需要使用Java 7!為什么沒人更新呢?!GWT支持Java 8,所以我將其更新到了Java 8,然后一切都正常了。

    以下是我在GWT中實現計數器應用的代碼:

    package?com.athaydes.client;

    import?com.google.gwt.core.client.EntryPoint;
    import?com.google.gwt.user.client.ui.*;

    import?java.util.function.Consumer;

    public?class?GwtApp?implements?EntryPoint?{
    ????public?void?onModuleLoad()?{
    ????????RootPanel.get(?"content"?).add(?new?Counter()?);
    ????}
    }

    class?Counter?extends?Composite?{

    ????private?int?value;

    ????Counter()?{
    ????????HorizontalPanel?buttonsPanel?=?new?HorizontalPanel();
    ????????buttonsPanel.setSpacing(?10?);

    ????????Button?up?=?new?Button(?"Increment"?);
    ????????Button?down?=?new?Button(?"Decrement"?);
    ????????Label?out?=?new?Label();

    ????????Runnable?update?=?()?->?out.setText(?"The?current?count?is?"?+?value?);
    ????????update.run();

    ????????Consumer?handler?=?(?increment?)?->?{if?(?increment?)?{value++;
    ????????????}?else?{value--;
    ????????????}
    ????????????update.run();
    ????????};
    ????????up.addClickHandler(?clickEvent?->?handler.accept(?true?)?);
    ????????down.addClickHandler(?clickEvent?->?handler.accept(?false?)?);
    ????????buttonsPanel.add(?up?);
    ????????buttonsPanel.add(?down?);
    ????????VerticalPanel?root?=?new?VerticalPanel();
    ????????root.setSpacing(?20?);
    ????????root.add(?buttonsPanel?);
    ????????root.add(?out?);
    ????????initWidget(?root?);
    ????}
    }

    看起來不錯。實時地重新加載適用于超級開發模式,可以快速地修復用戶界面中的小問題。

    編譯出該應用的生產版本:

    ant?build

    生成的JS文件放在war/gwtapp目錄中。通過war目錄就可以在瀏覽器中運行應用,所以我只需在IntelliJ中打開war/GwtApp.html,然后單擊右上角的瀏覽器圖標,就可以讓IntelliJ啟動一個負責運行HTML文件的HTTP服務器,并在我想要的瀏覽器中打開HTML文件。結果表明,該應用運行良好。

    應用程序的大小:

    性能:

    TeaVM:Java-bytecode-to-JS編譯器

    網址:http://teavm.org/

    TeaVM這個項目據稱可以將Java字節碼轉換成JavaScript和Webassembly。 因為它不需要Java源代碼,所以它也可以用于從Kotlin和Scala(以及其他基于JVM的語言)進行編譯。

    如果你想學習使用TeaVM,那么需要使用Maven archetype:

    $?mvn?-DarchetypeCatalog=local?\????????????????
    ??-DarchetypeGroupId=org.teavm???-DarchetypeArtifactId=teavm-maven-webapp???-DarchetypeVersion=0.5.1?archetype:generate

    這一步會創建一個標準的Java項目,根據Maven的約定,你可以在提示框中輸入項目的保存目錄。Java源代碼位于src/main/java,而Web的index.html等文件位于src/main/webapp目錄中。

    以下是我編寫的計數器的Java代碼:

    package?com.athaydes;

    import?org.teavm.jso.dom.html.HTMLButtonElement;
    import?org.teavm.jso.dom.html.HTMLDocument;
    import?org.teavm.jso.dom.html.HTMLElement;

    import?java.util.function.Consumer;

    public?class?Client?{
    ????public?static?void?main(?String[]?args?)?{
    ????????HTMLDocument?document?=?HTMLDocument.current();
    ????????HTMLElement?div?=?document.createElement(?"h2"?);
    ????????div.appendChild(?document.createTextNode(?"TeaVM?CounterApp"?)?);
    ????????document.getBody().appendChild(?div?);
    ????????div.appendChild(?new?Counter().build()?);
    ????}
    }

    class?Counter?{
    ????private?int?value?=?0;

    ????HTMLElement?build()?{
    ????????HTMLDocument?document?=?HTMLDocument.current();
    ????????HTMLButtonElement?up?=?(?HTMLButtonElement?)?document.createElement(?"button"?);
    ????????up.appendChild(?document.createTextNode(?"Increment"?)?);
    ????????HTMLButtonElement?down?=?(?HTMLButtonElement?)?document.createElement(?"button"?);
    ????????down.appendChild(?document.createTextNode(?"Decrement"?)?);
    ????????HTMLElement?out?=?document.createElement(?"p"?);

    ????????Runnable?update?=?()?->?out.setInnerHTML(?"The?current?count?is?"?+?value?);

    ????????Consumer?handler?=?(?increment?)?->?{if?(?increment?)?{
    ????????????????value++;
    ????????????}?else?{
    ????????????????value--;
    ????????????}
    ????????????update.run();
    ????????};
    ????????up.listenClick(?(?event?)?->?handler.accept(?true?)?);
    ????????down.listenClick(?(?event?)?->?handler.accept(?false?)?);
    ????????update.run();
    ????????HTMLElement?div?=?document.createElement(?"div"?);
    ????????div.appendChild(?out?);
    ????????div.appendChild(?up?);
    ????????div.appendChild(?down?);return?div;
    ????}
    }

    有趣的是,Java Counter組件僅包含34行代碼,比React.js(55行以上的代碼量)少很多!

    運行如下命令編譯:

    $?mvn?package

    該命令會像往常一樣編譯所有的Java代碼,并在target/classes目錄中生成.class文件(與普通的Java項目一樣),但它還會在target/-/teavm下創建JavaScript代碼,我的項目名為mytea,因此相應的目錄為:target/mytea-1-0-SNAPSHOT/teavm。

    在運行該應用程序時,你只需啟動Web服務器即可將目錄`target/mytea-1-0-SNAPSHOT/掛出來。

    應用程序的大小:

    性能:

    JSweet:帶有庫生態系統的Java-source-to-JS(和TypeScript)編譯器

    網址:http://www.jsweet.org/

    JSweet可以將Java源代碼編譯為TypeScript和JavaScript。Java庫可以作為TypeScript庫發布。與其他備選方案不同,Java代碼可以與JS / TS代碼互相轉換!

    如果你想學習使用JSweet,那么我推薦你從GitHub克隆快速入門的項目:

    $?git?clone?https://github.com/cincheo/jsweet-quickstart.git
    $?cd?jsweet-quickstart
    $?mvn?generate-sources

    同樣,Java項目會使用標準的Maven約定,將Java源代碼放入src/main/java中。然而,Web資源會直接放在webapp目錄下。

    與TeaVM不同,JSweet編譯器根本不會生成類文件:這就是為什么你只能運行mvn generate-sources來生成JS代碼,而無法使用更常見的mvn package或mvn install。

    最終我寫的Java代碼幾乎與TeaVM一樣(但有一點例外:JSweet API選擇java.util.function.Function作為點擊處理程序,而不是Consumer,因此必須返回一個值,用lambda來編寫這段代碼就會很尷尬,你需要使用大括號并強制返回null):

    package?quickstart;

    import?def.dom.HTMLButtonElement;
    import?def.dom.HTMLElement;

    import?java.util.function.Consumer;

    import?static?def.dom.Globals.document;

    public?class?QuickStart?{
    ????public?static?void?main(?String[]?args?)?{
    ????????HTMLElement?div?=?document.createElement(?"h2"?);
    ????????div.appendChild(?document.createTextNode(?"JSweet?CounterApp"?)?);
    ????????document.body.appendChild(?div?);
    ????????div.appendChild(?new?Counter().build()?);
    ????}
    }

    class?Counter?{
    ????private?int?value?=?0;

    ????HTMLElement?build()?{
    ????????HTMLButtonElement?up?=?(?HTMLButtonElement?)?document.createElement(?"button"?);
    ????????up.appendChild(?document.createTextNode(?"Increment"?)?);
    ????????HTMLButtonElement?down?=?(?HTMLButtonElement?)?document.createElement(?"button"?);
    ????????down.appendChild(?document.createTextNode(?"Decrement"?)?);
    ????????HTMLElement?out?=?document.createElement(?"p"?);

    ????????Runnable?update?=?()?->?out.innerText?=?"The?current?count?is?"?+?value;

    ????????Consumer?handler?=?(?increment?)?->?{if?(?increment?)?{
    ????????????????value++;
    ????????????}?else?{
    ????????????????value--;
    ????????????}
    ????????????update.run();
    ????????};
    ????????up.onclick?=?(?event?)?->?{
    ????????????handler.accept(?true?);return?null;
    ????????};
    ????????down.onclick?=?(?event?)?->?{
    ????????????handler.accept(?false?);return?null;
    ????????};
    ????????update.run();
    ????????HTMLElement?div?=?document.createElement(?"div"?);
    ????????div.appendChild(?out?);
    ????????div.appendChild(?up?);
    ????????div.appendChild(?down?);return?div;
    ????}
    }

    應用程序的大小:

    性能:

    CheerpJ:完全在瀏覽器上實現JVM

    網址:https://leaningtech.com/cheerpj/

    CheerpJ絕對是最瘋狂的選擇(甚至可能是你見過的最瘋狂的項目!)

    實際上,它并不是Java到JavaScript的轉換器……其實它是一個完整的Java運行時!沒錯,它可以完成更傳統的JVM可以執行的所有操作。線程、文件系統(顯然它通過IndexDB模擬文件系統)、反射、類加載、網絡,等等。

    如果這還不足以讓你頭暈目眩,那么就讓我們來看看CheerpJ的入門教程。

    這個入門教程可以讓你感受如何在沒有插件的情況下,在瀏覽器上運行包含Swing應用(記住Swing,面向桌面系統的多平臺Java UI框架??)的編譯好的jar。

    它運行的不是applet,它真的是在瀏覽器中運行Swing代碼!!而且還沒有插件!!

    說出來連我自己都不相信,所以讓我們一起來看看這個入門教程吧。

    為了方便起見,我將這些步驟進行了如下總結:

    • 下載Swing應用程序的jar。

    • 使用本地Java運行這個jar。

    • 安裝CheerpJ(據說,你必須手動下載并放在你的主文件夾下)。

    • 確認你安裝好了python3(對啊,我也覺得很奇怪,使用CheerpJ的時候,還需要用到Python)。

    • 運行~/cheerpj_1.3/cheerpjfy.py TextDemo.jar。

    • 創建一個index.html文件。

    • 讓Web服務器指向當前目錄。

    目前看起來這個入門教程行不通啊,因為你一直卡在了加載中……但是你需要漫長的等待,長到你開始懷疑人生!但最后終于成功了!

    這個Swing應用跟我在本地Java上運行的應用相同,但它嵌入到了瀏覽器的網頁中!

    在Ubuntu上運行Swing TextDemo

    在瀏覽器中通過CheerpJ運行Swing TextDemo

    如果你有現成的Swing應用,那么可能CheerpJ適合你。但是如果你想要寫一個新的應用,那么你可能不想選用CheerpJ。

    我嘗試使用CheerpJ對DOM的支持(發行包中包含cheerpj-dom.jar文件)來實現計數器應用,但是我在10分鐘內遇到了2個bug。而且這兩個bug很麻煩,我完全無法繼續……更別提我必須將每個Java String都包裝成對Global.JSString()的調用!

    給CheerpJ開發人員的一點提示:將你的jar放入Maven庫中(Java開發人員都不愿意將依賴項硬編碼到本地文件),千萬不要放在目錄下,絕對行不通!另外,你需要習慣語言的約定:不要調用Java方法set_onclick,你應該調用setOnClick,謝謝。

    我準備放棄CheerpJ了,但后來我想起了此次實驗的一項承諾:

    使用產品/框架提供的最基本的工具創建計數器應用程序。

    無奈,只能硬著頭皮繼續了。對CheerpJ來說,似乎實現用戶界面的基本工具即是JVM本身!這個JVM提供了一個UI工具包:Swing!

    從Java 12開始,Swing是隨JVM一起發布的唯一UI工具包……JavaFX已經成為一個獨立的項目。不管怎樣,CheerpJ只支持Swing。

    所以,如下是我在純Swing中實現的計數器應用:

    import?javax.swing.*;
    import?java.awt.*;
    import?java.util.function.Consumer;

    public?class?Main?implements?Runnable?{

    ????@Overridepublic?void?run()?{
    ????????JFrame?frame?=?new?JFrame(?"CheerpJ?Demo"?);

    ????????frame.setDefaultCloseOperation(?JFrame.EXIT_ON_CLOSE?);
    ????????frame.setSize(?400,?80?);
    ????????frame.add(?new?Counter()?);
    ????????frame.setVisible(?true?);
    ????}

    ????public?static?void?main(?String[]?args?)?{
    ????????SwingUtilities.invokeLater(?new?Main()?);
    ????}
    }

    class?Counter?extends?JPanel?{
    ????private?int?value;

    ????public?Counter()?{
    ????????JButton?up?=?new?JButton(?"Increment"?);
    ????????JButton?down?=?new?JButton(?"Decrement"?);
    ????????JLabel?out?=?new?JLabel();

    ????????Runnable?update?=?()?->?out.setText(?"The?current?count?is?"?+?value?);
    ????????update.run();

    ????????Consumer?handler?=?(?increment?)?->?{if?(?increment?)?{value++;
    ????????????}?else?{value--;
    ????????????}
    ????????????update.run();
    ????????};
    ????????up.addActionListener(?event?->?handler.accept(?true?)?);
    ????????down.addActionListener(?event?->?handler.accept(?false?)?);
    ????????JPanel?buttonsPanel?=?new?JPanel();
    ????????buttonsPanel.add(?up?);
    ????????buttonsPanel.add(?down?);
    ????????JLabel?title?=?new?JLabel(?"CheerpJ?CounterApp?(Swing)"?);
    ????????setLayout(?new?BorderLayout()?);add(?title,?BorderLayout.PAGE_START?);add(?buttonsPanel,?BorderLayout.PAGE_END?);add(?out,?BorderLayout.CENTER?);
    ????}
    }

    你完全可以在桌面系統上正常運行:這完全就是一個普通的Swing應用!

    首先,我們需要創建普通的jar:

    mvn?package

    然后用Java運行:

    java?-jar?cheerpj-swing/target/cheerpj-swing-1.0-SNAPSHOT.jar

    結果如下:

    在Ubuntu中運行計數器應用

    瘋狂的是你也可以在CheerpJ的瀏覽器中運行該應用。

    看一看瀏覽器上的“網絡”選項卡,你會發現非常有趣的東西:它一直在下載東西,顯然每個Java的標準庫包都有一個JS文件,CheerpJ會根據需要下載它們。

    應用程序的大小:

    性能:

    為了方便你了解該應用有多糟糕,請參照Lighthouse 提供的如下診斷信息:

    這是我第一次看到Avoid enourmous network payloads的診斷,我絕對會遵循這個建議!

    Vaadin Flow:Java-source-to-JS-source,服務器和客戶端框架

    網址:https://vaadin.com/flow

    很久以前我就聽說Vaadin是一個基于GWT的框架……但似乎他們最近創建了一個基于Web組件的產品Vaadin Flow。

    我喜歡網絡組件,所以我決定試試看。

    入門教程的頁面里有幾個選項,可以創建與Spring或CDI等集成的項目。我選擇了我能找到的最基本選項Project Base,因為我想要的只是一個客戶端應用程序。

    我按照說明下載了zip,而且只用了幾分鐘就可以讓這些代碼運行了。這是一個熟悉的Maven項目(我希望Gradle成為最受歡迎的選擇,但顯然情況并非如此)......我沒有看到index.html文件,這有點令人驚訝。瀏覽器是如何加載應用程序的呢?

    不管怎樣,我們只需要一個命令就可以運行這個應用:mvn jetty:run,然后訪問http://localhost:8080就能看到正在運行的應用。

    看一下這個巨大的POM文件(一個hello world應用就有139行的代碼),似乎他們使用了jetty-maven-plugin。

    所以,我再一次選用了我最喜歡的選項IntelliJ服務器,來提供index.html文件。然而,情況開始有點混亂,這對我來說有點太神奇了......當然,我是一名Java開發人員,但也沒關系,我還是可以應付一兩個HTML文件。

    在我改代碼的時候,似乎服務器重啟了,所以我感覺它可能在實時重新加載。這很好!但不幸的是,雖然不知道服務器在干什么,但是它并沒有實時地重新加載我的代碼。我試過幾次刷新頁面,卻導致了幾處報錯!!看起來像Vaadin應用不喜歡頁面刷新(應用處于調試模式,不過我估計它背后的工作太多了,結果因自身的復雜性而崩潰)。

    但是,編寫UI的Java API非常出色,非常易于使用和學習,顯然是為Java程序員編寫的,讓我感覺賓至如歸,簡直太好了!

    如下是我編寫的計數器應用,你有沒有覺得這段代碼很酷:

    package?com.example.test;

    import?com.vaadin.flow.component.Composite;
    import?com.vaadin.flow.component.button.Button;
    import?com.vaadin.flow.component.html.Div;
    import?com.vaadin.flow.component.html.H2;
    import?com.vaadin.flow.component.html.Paragraph;
    import?com.vaadin.flow.component.orderedlayout.VerticalLayout;
    import?com.vaadin.flow.router.Route;

    import?java.util.function.Consumer;

    @Route(?""?)
    public?class?MainView?extends?VerticalLayout?{

    ????public?MainView()?{
    ????????H2?header?=?new?H2(?"Vaadin?Flow?CounterApp"?);
    ????????add(?header,?new?Counter()?);
    ????}
    }

    class?Counter?extends?Composite<Div>?{
    ????private?int?value;

    ????Counter()?{
    ????????Paragraph?out?=?new?Paragraph();
    ????????Runnable?update?=?()?->?out.setText(?"The?current?count?is?"?+?value?);
    ????????update.run();

    ????????Consumer?handler?=?(?increment?)?->?{if?(?increment?)?{
    ????????????????value++;
    ????????????}?else?{
    ????????????????value--;
    ????????????}
    ????????????update.run();
    ????????};
    ????????Button?up?=?new?Button(?"Increment",?event?->?handler.accept(?true?)?);
    ????????Button?down?=?new?Button(?"Decrement",?event?->?handler.accept(?false?)?);
    ????????getContent().add(?out,?up,?down?);
    ????}
    }

    為了測量這個應用的性能,我通過如下命令在生產模式下運行了該應用:

    $?mvn?jetty:run-exploded?-Pproduction-mode

    感覺這個頁面非常生氣勃勃,即便沒有經過特殊的設計,頁面風格也非常好。

    應用程序的大小:

    注意:這個Vaadin的計數器應用至少需要312KB才能運行(主要是因為一個巨大的HTML文件,vaadin-flow-bundle:JS資源的總大小只有46.7KB)……這比我想象的還要多。

    性能:

    在運行應用時,Chrome在控制臺上顯示了一個警告,這有點讓人擔心。

    似乎Vaadin在很早就采用了HTML導入等實驗性的功能,而現在這些功能都被棄用了。很可惜,但是如果他們能夠持續更新這個產品的話,這應該不是一個大問題。

    Vaadin比JSweet和TeaVM慢一點,但公平地說,這個版本的計數器比其他版本更強大,盡管這并非我所愿(有沒有辦法從Vaadin應用中刪除樣式和字體?)!

    Bck2Brwsr:Java-bytecode-to-JS編譯器

    網址:http://wiki.apidesign.org/wiki/Bck2Brwsr

    Bck2Brwsr始于2012,旨在創建一個能夠快速啟動并百分百在現代瀏覽器中運行的小型Java。

    然而,與CheerpJ不同,它未能實現完整的JVM,只有一小部分功能可以在瀏覽器上運行,更類似于TeaVM,因為它也是將Java字節碼編譯成JS。

    apidesign.org上有一個看起來很舊的wiki頁面(http://wiki.apidesign.org/wiki/Bck2Brwsr),說明了如何使用bck2brwsr。頁面上建議的一種做法是使用Bck2BrwsrViaCLI,還有一種是Knockout4Java。

    我并不是很想使用Knockout.js(它自2015年左右開始就在JS的世界中失寵了),所以我選擇了CLI。

    我按照wiki所說,運行Maven原型創建了一個新項目:

    $?mvn?archetype:generate?????-DarchetypeGroupId=com.dukescript.archetype?????-DarchetypeArtifactId=knockout4j-archetype??-DarchetypeVersion=0.26?????-Dwebpath=client-web
    小心wiki頁面上給出的命令!最后一行少了一個反斜杠,而且命令中的版本是0.16,當前版本應該是0.26。

    然后,編譯并打包應用:

    $?mvn?package?

    警告:這一步會打開一個帶有JUnit Browser Runner的彈出窗口。

    我沒想到會彈出這個窗口……不過,沒關系,我們繼續,wiki頁面上說我們可以通過以下命令運行帶有FXBrwsr的應用:

    $?mvn?-f?client?process-classes?exec:exec

    但是,我在運行這個命令的時候,收到了如下的錯誤:

    Exception?in?thread?"main"?java.lang.IllegalStateException:?Can't?find?any?Fn.Presenter
    ????at?net.java.html.boot.BrowserBuilder.showAndWait(BrowserBuilder.java:255)
    ????at?com.athaydes.Main.main(Main.java:16)
    [INFO]?------------------------------------------------------------------------
    [INFO]?BUILD?FAILURE
    [INFO]?------------------------------------------------------------------------

    我快速搜索了Google,結果什么都沒找到(我猜測他們沒有在Linux上測試),所以我嘗試了一下在真正的瀏覽器中運行應用:

    $?mvn?-f?client-web?clean?package?-DskipTests?bck2brwsr:show

    結果,又遇到了另外一個錯誤:

    [ERROR]?Failed?to?execute?goal?on?project?bck2brwsr-web:?Could?not?resolve?dependencies?for?project?
    com.athaydes:bck2brwsr-web:jar:1.0-SNAPSHOT:?
    Could?not?find?artifact?com.athaydes:bck2brwsr-js:jar:bck2brwsr:1.0-SNAPSHOT?->?[Help?1]

    這是一個Maven經典的問題:有時你需要把你的應用放到某些插件可見的地方……通常你可以通過下述命令解決這個問題:

    $?mvn?install

    然后,再次運行命令啟動應用,看似沒問題,但應用毫無反應。

    檢查控制臺,果然出錯誤了:

    VM69?bck2brwsr.js:6?Uncaught?Cannot?find?com.athaydes.BrowserMain
    w?@?VM69?bck2brwsr.js:6
    v?@?VM69?bck2brwsr.js:2
    r?@?VM69?bck2brwsr.js:2
    load?(async)
    z?@?VM69?bck2brwsr.js:3
    r?@?VM69?bck2brwsr.js:4
    w?@?VM69?bck2brwsr.js:6
    n.loadClass?@?VM69?bck2brwsr.js:6
    (anonymous)?@?index.html:28

    我翻看了代碼……希望找到一些可以幫助我了解這個問題的東西,結果卻什么都沒找到……

    然而,我找到了大量的XML。準確地說,在4個Maven pom文件中找到了931行XML。

    我還發現該項目包含3個Maven模塊:client、client-web和js。

    js模塊包含一個Java類,其中包含一些標記為native的方法,還用@JavaScriptBody進行了注釋,其中包含實現方法的JavaScript代碼,但是嵌入到了Java Strings中。

    client模塊包含一個bootstrapping主類以及一個帶有更多注釋的DataModel類,似乎是為了將數據模型綁定到視圖,同時嘗試使用js模塊中聲明的函數。

    它引用了另一個名為Data的類,然而源代碼中并沒有這個類……它是在編譯項目時自動生成的。而我卻搞不清楚這個類是由什么生成的??赡苌盥裨?000行的pom中吧。

    client-web模塊包含缺少的類:com.athaydes.BrowserMain。因為這是我們在上述Maven命令中運行的模塊,所以我不明白為什么瀏覽器找不到這個類。

    我希望能夠使用DOM API來創建UI,就像之前的一些示例一樣。我想了很多辦法,最終只發現了一些NetBeans API,這絕對不是我想要的東西。

    似乎唯一可以與網頁交互的方法就是通過HTML文本上的data-bind屬性,其背后的支持是Knockout.js!

    我以為我已經避開了Knockout,但是看看“CLI”頁面上顯示的Maven原型的ID吧!

    也許我可以通過可怕的@JavaScriptBody注釋,直接在Java Strings中編寫JavaScript代碼(請別這么干……理智一點),但我并不想知道這樣是否可行。

    我覺得做了這么多嘗試就夠了。因為幾乎沒有文檔可以幫助我調試這個問題,在線搜索答案也是浪費時間——根本就沒有答案。

    我很抱歉無法在這篇文章中給出有關bck2brwsr性能的實際數據,雖然我花了一天的時間,卻未能成功。我覺得我可以說除非你有迫不得已的理由,否則就不應該碰任何與這個項目相關的東西,包括DukeScript。

    你可能會注意到,整個bck2brwsr文檔甚至源代碼中多次引用了DukeScript。DukeScript的入門頁面中顯示的示例與我使用的Maven原型創建的示例完全相同,如此看來這兩個項目似乎密切相關,盡管Dukescript創始人說bck2brwsr只是項目的一小部分,而且也屬于實驗性質,另外他們也支持TeaVM。

    結論

    讓我們看看最后的結果:

    我沒有將Bck2brwsr包含在內,因為我未能調試成功。如果有人能告訴我問題所在,那么我會更新下面的結果。

    性能:

    * FCP = First Contentful Paint(此值用于打破性能相同的工具之間的聯系)

    應用程序的大小:

    代碼行數:

    代碼行數不包括導入和注釋。

    總結

    問題:性能至關重要?

    答案:那么你應該選擇JSweet或TeaVM。

    問題:你喜歡占用空間較小的方案?

    答案:那么JSweet可以輕松勝任,但TeaVM也相當不錯。

    問題:你希望維護的代碼庫最小?

    答案:那么Vaadin Flow非常棒。其他方案都非常接近,所以這個因素不會產生太大的影響......但它們都能夠輕松擊敗React!

    問題:你想要一些盡可能接近普通Java的東西?

    答案:如果你關心UI組件的話,可以選擇Vaadin Flow;如果你關心業務邏輯的話,則可以選擇TeaVM。

    問題:你希望盡可能接近JS生態系統,但仍使用Java工具?

    答案:那么JSweet非常適合你。

    問題:你想要的東西是Java,但希望在瀏覽器中運行?

    答案:那么JSweet非常適合你。

    問題:你想嘗試一些與Java不同的東西,而不是JS?

    答案:Elm是一種現成的函數式編程語言,旨在創建Web應用程序。它有很棒的工具,包括一個很棒的IntelliJ插件,所以非常適合那些一直想要功能的Java開發人員!另外一個理想的選擇是Dart,它與Java非常相似,但有很多語法糖,所以常見的功能都很容易實現。Ant帶有很棒的工具,包括實時重新加載的服務器,還包括類似于Angular和React等的框架(如果你需要的話)。

    如果你對JVM備選方案與Dart的比較感到好奇,那么我可以告訴你我已經將Dart的實現添加到了我的GitHub代碼庫中。比較結果如下:

    應用程序大小:79KB,性能:100(FCP:1.4s),代碼行數:31。

    本文中顯示的所有代碼都上傳到了如下GitHub代碼庫中,包括React.js和Dart實現。

    https://github.com/renatoathaydes/jvm-alternatives-to-js

    原文:https://renato.athaydes.com/posts/comparing-jvm-alternatives-to-js.html

    本文為CSDN翻譯,轉載請注明來源出處。

    【END】

    作為碼一代,想教碼二代卻無從下手:

    聽說少兒編程很火,可它有哪些好處呢?

    孩子多大開始學習比較好呢?又該如何學習呢?

    最新的編程教育政策又有哪些呢?

    下面給大家介紹CSDN新成員:極客寶寶(ID:geek_baby)

    戳他了解更多↓↓↓

    ?熱 文?推 薦?

    ??李彥宏候選工程院院士;陌陌回應探探下架;拼多多回應“刷單”質疑 | 極客頭條

    ??華為硬核招聘程序員!| 極客頭條

    ??他 25 歲進貝爾實驗室,32 歲創建信息論,40 歲辦達特茅斯會議 | 人物志

    ?真の硬核粉絲!小學生也參加楊超越杯,作品優秀!

    ??阿里半跪過,任正非差點跳樓,京東被騙光錢:成年人的生活哪有容易二字?

    ?不改變比特幣, 如何擴容?

    ?強推!盤點阿里巴巴 15 款開發者工具 | 程序員硬核評測

    ?17篇論文入選CVPR 2019,百度AI都在關注什么?(附論文地址)

    ? 她說:為啥程序員都特想要機械鍵盤?這答案我服!

    System.out.println("點個在看吧!");
    console.log("點個在看吧!");print("點個在看吧!");printf("點個在看吧!\n");
    cout?<"點個在看吧!"?<Console.WriteLine("點個在看吧!");
    Response.Write("點個在看吧!");alert("點個在看吧!")echo "點個在看吧!"

    你點的每個“在看”,我都認真當成了喜歡

    總結

    以上是生活随笔為你收集整理的Dreamwear如何创建javascript_JavaScript 太糟糕,JVM 有妙招!的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产日韩久久久 | 1区2区3区在线观看 久久久久久久久久久影院 成人网址在线观看 | 国产精品日韩专区 | 中文字幕免费在线播放 | youjizz中国少妇 | 欧美视频网址 | 亚洲色p| 三级黄色片网站 | 国产一区二区在线观看免费 | 强行糟蹋人妻hd中文字幕 | 国产欧美一区二区精品性色超碰 | 亚洲精品久久久久avwww潮水 | 九九碰| 亚洲国产欧美视频 | 欧美精品在线一区二区 | 亚洲精品国偷拍自产在线观看蜜桃 | 国产精品久久久久久久久毛片 | 三级在线网址 | 亚洲综合色一区 | 精品少妇一区二区三区免费观看 | 美女屁股网站 | 亚洲成av | 男人干女人视频 | 日本一区二区精品视频 | 亚洲成熟毛多妇女av毛片 | 精品一区二区三区四 | 国产精品白嫩极品美女视频 | 91原创视频 | 日本一区二区成人 | 免费日本视频 | 2020国产精品视频 | 国产不卡在线 | 亚洲欧美综合一区 | 国产精品无码一区二区三区在线看 | 久久不卡影院 | 中文字幕在线第一页 | 少妇精品导航 | 精品伊人| 怡红院一区二区 | 清纯唯美亚洲色图 | 无码h黄肉3d动漫在线观看 | 国产视频一区二区视频 | 69sex久久精品国产麻豆 | 日韩av一区二区三区在线观看 | 成人毛片一区二区三区 | 精品久久免费观看 | 国产精品久久久久久久免费看 | 99久久久久久久久久 | 欧美性www| 色狠狠一区 | 轻点好疼好大好爽视频 | 国产 日韩 一区 | 亚洲av无码一区二区三区观看 | 91在线观看欧美日韩 | 麻豆蜜桃在线观看 | 日韩一区二区在线播放 | 亚洲视频在线一区 | 老司机深夜网站 | 国产一区二区三区在线免费 | 人妻一区二区三区四区 | 亚洲无码久久久久 | 老湿福利影院 | 日本一级视频 | 精品国模一区二区三区欧美 | 国产欧美精品一区二区色综合朱莉 | 96视频在线观看 | 国产一区导航 | 9色在线| 第一宅男av导航入口 | 中文字幕丰满孑伦无码专区 | 日韩欧美成人免费视频 | 黄色一级片欧美 | 黄色一级大片 | 日韩电影一区二区 | 欧美性受xxxx黑人xyx性 | 成人黄色激情视频 | 国产视频一区二区三区在线播放 | 亚洲中文在线一区 | 越南少妇做受xxx片 亚洲av综合色区无码一二三区 | 少妇高潮喷水在线观看 | 成人av网站在线播放 | 免费不卡视频 | 天天干夜夜夜 | 亚洲高清视频一区二区 | 亚洲一区二区欧美 | 久久99伊人 | 日本少妇作爱视频 | 激情五月婷婷久久 | 另类ts人妖一区二区三区 | 国产精品美乳在线观看 | 鲁在线视频 | 九九热视| 日韩精品一区二区三区色欲av | 国产精品久久久久久久久免费桃花 | 日日夜夜伊人 | 午夜影院操 | 欧美成人猛片aaaaaaa | 黄色片在线观看视频 | 国产大片一区 |