整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          electron 和 tauri 都不想用,那就自己

          electron 和 tauri 都不想用,那就自己寫個想用的吧

          在《屠龍少年終成惡龍,前端轉產品的我給前端挖了個坑》這篇文章里,有講到我是如何把我們的前端帶坑里去。同時評論區(qū)有一條評論 你那個demo.exe是用什么實現(xiàn)的?可以直接套殼現(xiàn)有的系統(tǒng)? 看起來好像是在坑外徘徊不定若有所思的樣子。因此我打算寫本文把他踹坑里去,能踹一個是一個。

          不想用 electron 和 tauri ?那我們一起來寫個像 electron 的垃圾玩意吧~ 我們的目標是:前端程序員無需會三方語言就可獨立完成桌面程序,創(chuàng)建托盤程序和服務、讀寫文件、處理進程、剪貼板這些都沒有問題,預計整體體積不超過1M。

          為什么做

          我當前已經使用 nodejs 開發(fā)一個命令行程序,這個程序的工具方式是,從網絡上獲取動態(tài)的配置,然后讀取這個配置進行啟動。啟動后就能去做其他額外的事情了,而不需要管這個程序。因為這個程序只是一個輔助工具。

          但是目前有一些痛點:

          每次啟動的時候我都得先找到項目目錄,然后運行 node xxx.js,然后啟動一個黑框框,然后我再最小化這個框。啟動步驟相當麻煩并且有一個不用管的窗口在任務欄,相當?shù)K眼。

          有很多方法可以處理啟動問題,比如 pm2/快捷鏈接/全局安裝/制作 PKG 安裝包等。但各自有各自的問題,這里不一一列舉。

          對于有一個黑框需要最小化到任務欄問題,我嘗試過使用 node child_process 的 detached=false, windowsHide=true 等參數(shù)配合 pm2 都是沒有用的,黑框還是會彈出。 假設有用,我要的也不僅如此。

          我覺得這個工具不錯,我想要把這個工具發(fā)給別人使用,雖然這個工具是 nodejs 寫的,但我不希望別人還要去學習安裝 nodejs 環(huán)境。雖然這個工具是命令行啟動,并支持參數(shù)配置,但我希望像常規(guī)程序一樣,別人點擊一個圖標就能啟動,可以從界面上配置參數(shù)??梢栽诮缑嫔峡吹匠绦虻膶崟r日志,最小化之后,變成一個小圖標在任務欄,不占空間不礙眼。

          那么問題來了,因為我經常用 html/css/js 畫界面,對很多前端組件庫比較熟悉,所以我打算用前端寫界面。但 js 是跑在瀏覽器里的,讀取不了保存在電腦里的配置文件,更實現(xiàn)不了托盤圖標功能,也運行不了 node 程序。

          據(jù)我所知,像這種想使用前端語言開發(fā)界面,又需要與操作系統(tǒng)進行交互的功能,有不少方案。下面是我對他們的調研結果:

          名稱

          前端

          后端

          體積 MB

          內存 MB

          放棄原因

          備注

          nodegui

          chromium

          nodejs

          100

          100

          體積大


          miniblink49

          Chromium

          nodejs

          ?

          ?

          體積大

          僅支持 window

          NW.js

          Chromium

          nodejs

          100

          100

          體積大


          electron

          Chromium

          nodejs

          100

          100

          體積大


          Wails

          webview

          go

          8M

          ?

          需其他語言


          Tauri

          webview

          rust

          1

          ?

          需其他語言


          Qt

          可選

          C++

          30

          ?

          需其他語言


          wpf

          可選

          C#

          ?

          ?

          需其他語言

          僅支持 window

          Muon

          Chromium

          go

          42

          26

          需其他語言


          Sciter

          Sciter

          QuickJS

          5

          ?

          與普通瀏覽器和 nodejs 可能有差異


          gluon

          瀏覽器

          nodejs

          1

          80

          生態(tài)小,例如沒有找到托盤圖標實現(xiàn)方式


          neutralino

          瀏覽器

          API

          2M

          60

          api 不多


          當前大家比較火有 electron 和 tauri。四年前我使用過 electron 做過一個桌面劃詞程序,由于涉及到系統(tǒng)操作,所以需要安裝 node-gyp/pytohn/visual studio 等依賴來進行本地編譯,能否操作成功與 electron/node/node-ffi 等版本兼容性有很大的關系,安裝過程和 electron 的體積都給我留下了不好的印象,另外 electron 里的主進程、渲染進程、通信的一些使用上的差異,也讓我覺得不那么便利,所以我放棄 electron 。

          接下來就是 tauri,它由于不打包 nodejs 和 chromium ,所以體積較小。但我看他官網上的 demo,就連啟動都 rust 代碼。

          雖然代碼沒幾行,但我也是相當拒絕:說好的只使用前端語言就能寫桌面程序呢?

          所以我放棄了 tauri 。原因是我真想找一個不使用三方語言就能做桌面程序的工具。我發(fā)現(xiàn) neutralino 比較貼近我的需求,但它當前還很年輕,很多 api 和示例都沒有。這相當于如果遇到了操作系統(tǒng)層面上的問題,只要他不提供 api 我就沒法操作,因為我不會寫原生代碼,所以又放棄了 neutralino 。

          所以就自己做一個吧。

          準備怎么做

          準備使用當前了解的一個語言做一個基于 webview 的工具,我們暫且叫 main。它加載好前端頁面,并向前端頁面注入 api 并連接上 websockets 。如果前端有什么對系統(tǒng)操作的訴求,告訴 main 即可,由 main 完成,對于前端而言,就像調用一個普通的 js 方法一樣,傳參、處理結果、完事。

          語言名為 aardio ,由于“各種原因”這里不做過多敘述。后面文檔中統(tǒng)一稱其為語言。

          那么為什么都去搞一個語言了不搞 rust 這些?有幾點考慮:

          • 提供了 js/webview/nodejs 互相調用的例子
          • 提供了一些常見的系統(tǒng)托盤、窗口操作示例等
          • 我對作者維護這個語言這么多年心存敬畏

          程序的整體架構是這樣的:

          • 配置層:常用的定制化需求,都可以通過一個 json 配置文件解決。js處理起來也簡單。
          • 依賴層:比如注入到 web 頁的經過封裝的 js 文件。
          • 內核層:完成與 web 頁面的通信,滿足 web 頁面對系統(tǒng)進行操作的常規(guī)訴求。
          • 工具層:例如健壯性、安全性、自動升級、調試、打包、啟動等。

          做成了什么樣

          下面這個圖片演示了啟動程序時,有一個綠色的進度條,然后進入界面。

          目前已過可行性驗證階段,給客戶做了一個文件管理系統(tǒng)程序,類似一個網盤,頁面由前端完成,然后文件的下載、預覽、同步這些交給 main 提供的 api。

          下面這個圖片演示了在 web 中關閉程序。

          對于自己的話,做了一個 ai 助手,對接的開源 ai-ui,已發(fā)給同事使用,也沒有問題。做了一個文章開關提到的助手程序,自己使用。

          再次演示一下透明窗口,上面的啟動時的進度條也是使用透明窗口完成的。

          演示自定義窗口標題和托盤。

          程序啟動時的進度條也是使用 html 實現(xiàn)的

          <!DOCTYPE html>
          <html lang="en">
          <head>
          <meta charset="UTF-8" />
          <meta name="viewport" content="width=device-width, initial-scale=1.0" />
          <title>loading...</title>
          <style>
          body,
          html {
          height: 100%;
          overflow: hidden;
          }
          body {
          display: flex;
          align-items: center;
          justify-content: center;
          }
          @property --progress {
          syntax: '<percentage>';
          inherits: false;
          initial-value: 0%;
          }
          
          .g-progress {
          margin: auto;
          width: 240px;
          height: 10px;
          border-radius: 25px;
          background: linear-gradient(90deg, #0f0, #0ff var(--progress), transparent 0);
          border: 1px solid #eee;
          transition: .3s --progress;
          }
          </style>
          </head>
          <body>
          <div class="box">
          <div id="progress" class="g-progress progress-bar-striped" style="--progress: 10%"></div>
          </div>
          </body>
          </html>

          遇到的問題及處理方案

          官方示例中給到的 webview 交互示例通過 external 注入到頁面的 window 上,通過此方法能讓 js 中的數(shù)據(jù)和 main 進行類型轉換(比如 js 里傳一個 number,那么到 main 里也是 number),還提供了一些可以直接啟用 main 里對象方法的操作。好用是好用,但是與 nodejs 交互的時候,沒有這種自動轉換的功能,而且示例中的 node 服務連接很慢。

          為了讓 main 支持 webview 和 nodejs,并且使用方法統(tǒng)一,并且加快啟動速度,查了一些資料,發(fā)生像這種跨語言通信通常都是使用 rpc 協(xié)議完成的,有 json-rpc/http-rpc/rpc-ws 等,為了實時性更強,我選擇了 websockets 這種方式, 我 npm 社區(qū)中發(fā)現(xiàn)有 www.npmjs.com/package/rpc… 這個包可用,還兼容 node 和瀏覽器,嘗試過后選擇了它,這解決了跨語言通信問題。

          另一個問題是,mian 中有很多方法是現(xiàn)成的。比如以下代碼在 main 中可以使用:

          // 有一個 winform 對象
          
          winform.hitMax() // 最大化
          winform.show() // 顯示窗口
          winform.hwnd // 獲取窗口句柄
          winform.hitCaption() // 拖動窗口
          winform.text="title" // 設置窗口標題
          // ... 上百個現(xiàn)在的方法和屬性

          如果我們要為 js 提供 api, 我們是每個屬性和方法都得去寫嗎?這又麻煩,代碼又還臃腫。

          經過一波掙扎,我想起了使用代理這種方式去實現(xiàn),還是 js。

          const obj=new Proxy(
          {},
          {
          get: function (target, key, receiver) {
          console.log(`getting ${key}!`);
          return Reflect.get(target, key, receiver);
          },
          set: function (target, key, value, receiver) {
          console.log(`setting ${key}!`);
          return Reflect.set(target, key, value, receiver);
          },
          }
          );

          根據(jù) proxy,我們可以實現(xiàn)攔截到某個對象的方法調用和屬性訪問、設置等。再加上深層代理的話,像 winform.process.close() 這種有任何層方法屬性都沒有問題。

          同時,在 main 中我們有這樣的代碼,來處理 proxy 攔截到的每個 key path:

          我們把攔截到的 path ,比如在 js 里寫 winform.process.close(true) 的時候,我們把攔截到的 winform.process.close 和參數(shù) true 通過 rpc-ws 提供的 call 方法傳給 main,這時候 main 根據(jù) path 去動態(tài)調用函數(shù)并把參數(shù)傳進去。我們把執(zhí)行結果又丟給 call 方法返回給我們的 js 即可。

          那么問題又來了,既然都實現(xiàn)了在 js 里調用方法和訪問屬性都像在寫 main 中的代碼一樣,那真的就能不能以 js 的形式去寫 main 的代碼呢?看了一天的教程,發(fā)現(xiàn)這水很深啊,約等于創(chuàng)造一門語言,怕了怕了,逃。

          但是思路著要有吧?好的:

          如果簡單一些呢,我們依然可以使用 proxy,實現(xiàn)操作符的攔截,從而實現(xiàn)一些簡單的加減乘除的操作。然這沒什么用啊,我們要實現(xiàn)的是比如用 js 里對 winform 對象進行遍歷之前,我們就要做一個生成器之類的東西,在生成器的每一步里,去獲取 main 里的遍歷結果。感覺上好像能實現(xiàn),實際我也不知道我在說什么。但是就算實現(xiàn)了,像這種遍歷器,頻繁的語言交互應該會消耗大量時間,感覺應該得不償失。

          所以在 js 里獲得 main 中語言的編寫體驗,就不實現(xiàn)啦。如果我們真的要在 js 里寫另一種語言,我們開放一個類似 js 的 eval 的功能。它可以向 main 傳原生代碼和參數(shù)。

          // 創(chuàng)建目錄
          const dir=`C:/my/`
          await ws.call(`run`, [
          `
          fsys.createDir(arg)
          `, dir])

          例如上面這段代碼,直接傳送目錄參數(shù) C:/my/ 到 arg,使用原生語言 fsys.createDir(arg) 去執(zhí)行。

          后期計劃是什么

          計劃一:使用 main 去做更多的桌面 app,以此促進 main 的完善。

          計劃二:為某個當前成熟的 ui 框架制定一套 css 皮膚,例如 win7 皮膚 ,例如 element-ui 樣子很 web,但應用了這個皮膚之后,整體頁面風格和控件都看起來就像原生 win7 桌面程序一樣。

          計劃三:盡快完成 api 的封裝和文檔,讓前端朋友只調用指定的 js api 即可完成托盤、進程、剪貼板、IO等系統(tǒng)操作。我們封裝的 api 盡量向 neutralino 靠近,做到最小成本的遷移。等它成熟后,可以遷入,沒成熟之前我們也能自己用著。

          需要什么幫助

          可以幫我們封裝 api,這需要你了解 main 的語言;可以用 main 來做些小工具嘗試一下,這就是最好的幫助;可以做操作系統(tǒng)風格皮膚,等你做好了,electron 和 tauri 他們都能用,因為他只是 css;或者可以點個 star https://github.com/wll8/sys-shim

          好了,餅畫了,牛吹了,坑挖了,我要去玩了。


          作者:程序媛李李李李李蕾
          鏈接:https://juejin.cn/post/7304538151480803366

          了解一樣東西,我認為最重要的莫過于了解Ta的過去,Ta的現(xiàn)狀,以及Ta的未來.學習CSS也不外乎如此.

          通過網絡學習一樣新東西,最大的困惑就是----網上的文章,寫得非常好.但就是碎片化,不系統(tǒng).而且還有個情況就是:有些問題,大神們覺得很簡單,不屑一提或者毫無意識的內容或知識,對于那些剛入門的人因為不知道,也沒人點播,有可能會在這個問題上迷茫很久.這一點我體會頗深.

          經驗分享:入門階段不要管好那么多細節(jié),記憶之類的東西,盡快地入門才是最重要的.其實入門,無非就是對所學內容形成一套概念,知其然,所以然.大概的就成了.

          一開始不要在W3C網站上學習,因為內容太多,雖然很系統(tǒng),但是我一點都不相信你會有耐心全部看下來!

          一開始學習,首先找些小的實戰(zhàn)項目看看,小編上方推薦的裙里就有免費的網課做小項目的課堂,里面講的非常細,一開始可能有一些不是很懂,但是你只要堅持聽完一節(jié)網課,學習到老師們的代碼風格和做項目的思路,對你的幫助是非常大的。

          我覺得最好的方式是實踐出來的。如果你沒有一個網站或者一個服務器等等之類的。你可以用Github去做一個自己的博客,雖然是靜態(tài)的但是也是夠的。

          可以按下面的步驟來學習,一個網站正常情況下由三部分組成:

          1. Head 頂部導航

          2. Content 內容

          3. Footer 頂部導航

          對于Head來說有不同的玩法,而首先你需要學會的是ul li a 這三個基礎的HTML,而對于大部分前端程序員來說。要手動寫一個水平導航可以說是一個入門的標志,還有豎直的導航,浮動的導航等等。

          接著你還會遇到的問題是如何處理底部的footer,讓他一直在最下面的。而不會亂跑,

          大概需要的過程

          1. 學會分析一個網頁的結構

          2. 理解每部分的原理

          3. 手動寫CSS

          小編就分享到這里了,關注小編,可以看小編的更多優(yōu)質文章。

          取一個網頁,我們需要了解一下網頁的結構,如果想要深入學習,建議看一下《網頁設計與制作》,這本書講述較為詳細,推薦閱讀。

          網頁的三大組成部分——HTML、CSS、JavaScript,如果把網頁比作一個人的話,HTML相當于骨架,JavaScript相當于肌肉,而CSS相當于皮膚,三者結合起來形成一個完整的網頁。

          網頁基本結構

          1.HTML

          HTML(Hyter Markup Language 超文本標記語言),主要是通過HTML標記對網頁中的文本、圖片、聲音等內容進行描述。HTML提供了很多種標記,如段落標記(p標簽)、圖片標記(img標簽)、視頻標記(video標簽)等,網頁中需要定義什么內容,就可以用相應的標記描述。

          首頁源代碼

          從圖可見,網頁內容是通過HTML標記(圖中帶有“<>”的符號)描述的,整個網頁由各種標簽嵌套而成。

          2.CSS

          HTML其實是一個純文本文件,只是網頁的一個骨架,只有HTML的網頁其實并不美觀,為了讓網頁看起來更好看,我們需要借助CSS。

          CSS(Cascading Style Sheets 層疊樣式表),“層疊”指的當HTML中引用了數(shù)個樣式文件,并且樣式發(fā)生沖突時,瀏覽器能依據(jù)層疊順序處理,“樣式”指的是網頁文字、圖片等的大小、顏色、排列等格式。

          body {
              font: 12px/1.14 SF Pro Display,PingFang SC,Hiragino Sans GB,Microsoft YaHei,WenQuanYi Micro Hei,Helvetica Neue,Arial,sans-serif;
              -webkit-font-smoothing: antialiased;
              color: #333;
              outline: 0;
          }
          font、color、outline即樣式設置

          CSS的位置很靈活,即可以嵌入在HTML文檔中,也可以時一個單獨的外部文件,如果是獨立的文件,則必須以.css為擴展名,使用link標簽引入文件。上圖CSS顯示為內嵌方式,一般集中放在HTML文檔頭部(<head>標簽內)。

          3.JavaScript

          JavaScript,簡稱JS,是一種腳本語言,可使網頁具有交互性(HTML和CSS制作的網頁是靜態(tài)網頁),js腳本語言使得用戶與信息是一種實時、動態(tài)、交互的頁面功能,如頁面效果切換、動畫效果、頁面游戲等,它還可以控制cookies,包括創(chuàng)建和修改等。

          JavaScript通常也是以單獨文件形式加載,后綴為js,在HTML中通過script標簽引入,如<scrip src="jquery-2.1.0.js" type="text/javascript"></script>。

          4.爬蟲的基本原理

          我們可以把互聯(lián)網看作一張大網,而爬蟲(即網絡爬蟲)就是在網上爬行的蜘蛛,把網的節(jié)點比作一個個網頁,爬蟲爬到一個節(jié)點就相當于訪問了該頁面,獲取了其信息,節(jié)點之間的線就像與網頁與網頁之間的鏈接關系,蜘蛛可順著節(jié)點連接繼續(xù)爬行到下一個節(jié)點,即通過一個網頁爬取另一個網頁,這樣整個網的節(jié)點都可以被爬取到了。

          那么爬蟲的基本過程可以簡單概述為:獲取網頁——提取信息——保存數(shù)據(jù)。

          靜態(tài)網頁與動態(tài)網頁

          靜態(tài)網頁:用HTML代碼編寫的頁面,每個網頁都有一個固定的URL,加載速度快,編寫簡單,但可維護性差、交互性差,不能根據(jù)URL靈活多變地顯示內容。

          動態(tài)網頁:以數(shù)據(jù)庫技術為基礎,可以大大降低網站維護的工作量,它可以動態(tài)解析URL參數(shù)的變化,關聯(lián)數(shù)據(jù)庫并動態(tài)呈現(xiàn)不同的頁面內容,可以實現(xiàn)用戶登錄與注冊功能。


          主站蜘蛛池模板: 亚洲国产精品一区二区九九| 精品一区二区三区| 日本香蕉一区二区三区| 小泽玛丽无码视频一区| 亚洲制服丝袜一区二区三区| 国产伦精品一区二区三区四区 | 精品视频午夜一区二区| 99精品一区二区免费视频 | 国产一区风间由美在线观看| 亚洲成AV人片一区二区密柚| 高清一区二区三区| 日韩免费无码一区二区视频| 中文字幕在线不卡一区二区| 色欲综合一区二区三区| 任你躁国产自任一区二区三区| 无码日韩AV一区二区三区| 亚洲av无码一区二区三区天堂古代| 亲子乱AV视频一区二区| 亚洲高清成人一区二区三区| 亚洲精品无码一区二区| 亚洲国产一区在线观看| 日韩精品无码一区二区中文字幕| 一区二区三区91| 一区二区精品在线观看| 国产一区中文字幕在线观看| 日韩精品一区在线| 日本一区二区三区在线看| 国模视频一区二区| 国产精品一区二区久久乐下载| 亚洲国产成人久久一区二区三区 | 在线一区二区三区| 国产成人高清亚洲一区久久| 在线观看中文字幕一区| 国产一区二区三区在线观看免费| 最新中文字幕一区二区乱码| 日韩三级一区二区三区| 国产AV一区二区精品凹凸 | 日本一区二区三区免费高清| 中文精品一区二区三区四区| 亚洲变态另类一区二区三区| 午夜DV内射一区区|