摘要:是一個使用和等技術(shù)創(chuàng)建原生程序的框架,它負(fù)責(zé)比較難搞的部分,你只需把精力放在你的應(yīng)用的核心上即可。談?wù)劶夹g(shù)選型使用去做底層的繪制,大項(xiàng)目首選狀態(tài)管理的最佳實(shí)踐肯定不是,目前首選,或者。
目前Electron在github上面的star量已經(jīng)快要跟React-native一樣多了
這里吐槽下,webpack感覺每周都在偷偷更新,很糟心啊,還有Angular更新到了8,Vue馬上又要出正式新版本了,5G今年就要商用,華為的系統(tǒng)也要出來了,RN還沒有更新到正式的1版本,還有號稱讓前端開發(fā)者失業(yè)的技術(shù)flutter也在瘋狂更新,前端真的是學(xué)不完的
回到正題,不能否認(rèn),現(xiàn)在的大前端,真的太牛了,PC端可以跨三種平臺開發(fā),移動端可以一次編寫,生成各種小程序以及React-native應(yīng)用,然后跑在ios和安卓以及網(wǎng)頁中 , 這里不得不說-------京東的Taro框架 這些人 已經(jīng)把Node.js和webpack用上了天對webpack不熟悉的,看我之前的文章 ,今天不把重點(diǎn)放在webpack
歡迎關(guān)注我的專欄 《前端進(jìn)階》 都是百星高贊文章
手寫React優(yōu)化版腳手架
前端性能優(yōu)化不完全手冊
手寫vue腳手架
本文源碼git倉庫地址
先說說Electron官網(wǎng)介紹: 使用 JavaScript, HTML 和 CSS 構(gòu)建跨平臺的桌面應(yīng)用 ,如果你可以建一個網(wǎng)站,你就可以建一個桌面應(yīng)用程序。 Electron 是一個使用 JavaScript, HTML 和 CSS 等 Web 技術(shù)創(chuàng)建原生程序的框架,它負(fù)責(zé)比較難搞的部分,你只需把精力放在你的應(yīng)用的核心上即可。什么意思呢?
Electron = Node.js + 谷歌瀏覽器 + 平常的JS代碼生成的應(yīng)用,最終打包成安裝包,就是一個完整的應(yīng)用
Electron分兩個進(jìn)程,主進(jìn)程負(fù)責(zé)比較難搞的那部分,渲染進(jìn)程(平常的JS代碼)部分,負(fù)責(zé)UI界面展示
兩個進(jìn)程之間可以通過remote模塊,以及IPCRender和IPCMain之間通信,前者類似于掛載在全局的屬性上進(jìn)行通信(很像最早的命名空間模塊化方案),后者是基于發(fā)布訂閱機(jī)制,自定義事件的監(jiān)聽和觸發(fā)實(shí)現(xiàn)兩個進(jìn)程的通信。
Electron相當(dāng)于給React生成的單頁面應(yīng)用套了一層殼,如果涉及到文件操作這類的復(fù)雜功能,那么就要依靠Electron的主進(jìn)程,因?yàn)橹鬟M(jìn)程可以直接調(diào)用Node.js的API,還可以使用C++插件,這里Node.js的牛逼程度就凸顯出來了,既可以寫后臺的CRUD,又可以做中間件,現(xiàn)在又可以寫前端。
談?wù)劶夹g(shù)選型使用React去做底層的UI繪制,大項(xiàng)目首選React+TS
狀態(tài)管理的最佳實(shí)踐肯定不是Redux,目前首選dva,或者redux-saga。
構(gòu)建工具選擇webpack,如果不會webpack真的很吃虧,會嚴(yán)重限制你的前端發(fā)展,所以建議好好學(xué)習(xí)Node.js和webpack
選擇了普通的Restful架構(gòu),而不是GraphQL,可能我對GraphQL理解不深,沒有領(lǐng)悟到精髓
在通信協(xié)議這塊,選擇了websoket和普通的http通信方式
因?yàn)槭?b>demo,很多地方并沒有細(xì)化,后期會針對electron出一個網(wǎng)易云音樂的開源項(xiàng)目,這是一定要做到的
先開始正式的環(huán)境搭建config文件放置webpack配置文件
server文件夾放置Node.js的后端服務(wù)器代碼
src下放置源碼
main.js是Electron的入口文件
json文件是腳本入口文件,也是包管理的文件~
開發(fā)模式項(xiàng)目啟動思路:先啟動webpack將代碼打包到內(nèi)存中,實(shí)現(xiàn)熱更新
再啟動Electron讀取對應(yīng)的url地址的文件內(nèi)容,也實(shí)現(xiàn)熱更新
設(shè)置webpack入口app: ["babel-polyfill", "./src/index.js", "./index.html"], vendor: ["react"] }忽略Electron中的代碼,不用webpack打包(因?yàn)?b>Electron中有后臺模塊代碼,打包就會報錯)
externals: [ (function () { var IGNORES = [ "electron" ]; return function (context, request, callback) { if (IGNORES.indexOf(request) >= 0) { return callback(null, "require("" + request + "")"); } return callback(); }; })() ]加入代碼分割
optimization: { runtimeChunk: true, splitChunks: { chunks: "all" } },設(shè)置熱更新等
plugins: [ new HtmlWebpackPlugin({ template: "./index.html" }), new webpack.HotModuleReplacementPlugin(), new webpack.NamedModulesPlugin(), ], mode: "development", devServer: { contentBase: "../build", open: true, port: 5000, hot: true },
#### 加入babel
{ loader: "babel-loader", options: { //jsx語法 presets: ["@babel/preset-react", //tree shaking 按需加載babel-polifill presets從后到前執(zhí)行 ["@babel/preset-env", { "modules": false, "useBuiltIns": "false", "corejs": 2, }], ], plugins: [ //支持import 懶加載 plugin從前到后 "@babel/plugin-syntax-dynamic-import", //andt-mobile按需加載 true是less,如果不用less style的值可以寫"css" ["import", { libraryName: "antd-mobile", style: true }], //識別class組件 ["@babel/plugin-proposal-class-properties", { "loose": true }], // ], cacheDirectory: true }, }看看主進(jìn)程的配置文件main.js
// Modules to control application life and create native browser window const { app, BrowserWindow, ipcMain, Tray, Menu } = require("electron") const path = require("path") // Keep a global reference of the window object, if you don"t, the window will // be closed automatically when the JavaScript object is garbage collected. let mainWindow app.disableHardwareAcceleration() // ipcMain.on("sync-message", (event, arg) => { // console.log("sync - message") // // event.returnValue("message", "tanjinjie hello") // }) function createWindow() { // Create the browser window. tray = new Tray(path.join(__dirname, "./src/assets/bg.jpg")); tray.setToolTip("wechart"); tray.on("click", () => { mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show() }); const contextMenu = Menu.buildFromTemplate([ { label: "退出", click: () => mainWindow.quit() }, ]); tray.setContextMenu(contextMenu); mainWindow = new BrowserWindow({ width: 805, height: 500, webPreferences: { nodeIntegration: true }, // titleBarStyle: "hidden" frame: false }) //自定義放大縮小托盤功能 ipcMain.on("changeWindow", (event, arg) => { if (arg === "min") { console.log("min") mainWindow.minimize() } else if (arg === "max") { console.log("max") if (mainWindow.isMaximized()) { mainWindow.unmaximize() } else { mainWindow.maximize() } } else if (arg === "hide") { console.log("hide") mainWindow.hide() } }) // and load the index.html of the app. // mainWindow.loadFile("index.html") mainWindow.loadURL("http://localhost:5000"); BrowserWindow.addDevToolsExtension( path.join(__dirname, "./src/extensions/react-dev-tool"), ); // Open the DevTools. // mainWindow.webContents.openDevTools() // Emitted when the window is closed. mainWindow.on("closed", function () { // Dereference the window object, usually you would store windows // in an array if your app supports multi windows, this is the time // when you should delete the corresponding element. mainWindow = null BrowserWindow.removeDevToolsExtension( path.join(__dirname, "./src/extensions/react-dev-tool"), ); }) } // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. app.on("ready", createWindow) // Quit when all windows are closed. app.on("window-all-closed", function () { // On macOS it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q if (process.platform !== "darwin") app.quit() }) app.on("activate", function () { // On macOS it"s common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (mainWindow === null) createWindow() }) // In this file you can include the rest of your app"s specific main process // code. You can also put them in separate files and require them here.今天只講開發(fā)模式下的配置,因?yàn)閷?shí)在太多,得分兩篇文章寫了~ 剩下的配置去git倉庫看 在開發(fā)模式下啟動項(xiàng)目:
使用 "dev": "webpack-dev-server --config ./config/webpack.dev.js", 將代碼打包到內(nèi)存中
使用 "start": "electron ." 開啟electron,讀取對應(yīng)的內(nèi)存地址中的資源,實(shí)現(xiàn)熱更新
項(xiàng)目起來后,在入口處index.js文件中,注入dvaimport React from "react" import App from "./App" import dva from "dva" import Homes from "./model/Homes" import main from "./model/main" const app = dva() app.router(({ history, app: store }) => (這里不得不說redux,redux-sage,dva的區(qū)別 直接看圖 首先是Redux)); app.model(Homes) app.model(main) app.start("#root")
React 只負(fù)責(zé)頁面渲染, 而不負(fù)責(zé)頁面邏輯, 頁面邏輯可以從中多帶帶抽取出來, 變成 store,狀態(tài)及頁面邏輯從
頁面邏輯就是 reducer,
上面說了, 可以使用 Middleware 攔截 action, 這樣一來異步的網(wǎng)絡(luò)操作也就很方便了, 做成一個 Middleware 就行了, 這里使用 redux-saga 這個類庫, 舉個栗子:
點(diǎn)擊創(chuàng)建 Todo 的按鈕, 發(fā)起一個 type == addTodo 的 action
saga 攔截這個 action, 發(fā)起 http 請求, 如果請求成功, 則繼續(xù)向 reducer 發(fā)一個 type == addTodoSucc 的 action, 提示創(chuàng)建成功, 反之則發(fā)送 type == addTodoFail 的 action 即可
最后是: Dva有了前面的三步鋪墊, Dva 的出現(xiàn)也就水到渠成了, 正如 Dva 官網(wǎng)所言, Dva 是基于 React + Redux + Saga 的最佳實(shí)踐沉淀, 做了 3 件很重要的事情, 大大提升了編碼體驗(yàn):
把 store 及 saga 統(tǒng)一為一個 model 的概念, 寫在一個 js 文件里面
增加了一個 Subscriptions, 用于收集其他來源的 action, eg: 鍵盤操作
model 寫法很簡約, 類似于 DSL 或者 RoR, coding 快得飛起??
約定優(yōu)于配置, 總是好的
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/104350.html
摘要:是一個使用和等技術(shù)創(chuàng)建原生程序的框架,它負(fù)責(zé)比較難搞的部分,你只需把精力放在你的應(yīng)用的核心上即可。談?wù)劶夹g(shù)選型使用去做底層的繪制,大項(xiàng)目首選狀態(tài)管理的最佳實(shí)踐肯定不是,目前首選,或者。 showImg(https://segmentfault.com/img/bVbtqlI?w=1308&h=565); 目前Electron在github上面的star量已經(jīng)快要跟React-nativ...
摘要:調(diào)用通過注冊表調(diào)用到實(shí)例,透過的,調(diào)用到中的,最后通過,調(diào)用,根據(jù)參數(shù)相應(yīng)模塊執(zhí)行。京東的,多端解決方案是一套遵循語法規(guī)范的多端開發(fā)解決方案。 showImg(https://segmentfault.com/img/bVbuMkw?w=1304&h=808); 對于一項(xiàng)技術(shù),我們不能停留在五分鐘狀態(tài),特別喜歡一句話,用什么方式繪制UI界面一點(diǎn)不重要,重要的是底層的思維,解決問題和優(yōu)化...
摘要:調(diào)用通過注冊表調(diào)用到實(shí)例,透過的,調(diào)用到中的,最后通過,調(diào)用,根據(jù)參數(shù)相應(yīng)模塊執(zhí)行。京東的,多端解決方案是一套遵循語法規(guī)范的多端開發(fā)解決方案。 showImg(https://segmentfault.com/img/bVbuMkw?w=1304&h=808); 對于一項(xiàng)技術(shù),我們不能停留在五分鐘狀態(tài),特別喜歡一句話,用什么方式繪制UI界面一點(diǎn)不重要,重要的是底層的思維,解決問題和優(yōu)化...
摘要:調(diào)用通過注冊表調(diào)用到實(shí)例,透過的,調(diào)用到中的,最后通過,調(diào)用,根據(jù)參數(shù)相應(yīng)模塊執(zhí)行。京東的,多端解決方案是一套遵循語法規(guī)范的多端開發(fā)解決方案。 showImg(https://segmentfault.com/img/bVbuMkw?w=1304&h=808); 對于一項(xiàng)技術(shù),我們不能停留在五分鐘狀態(tài),特別喜歡一句話,用什么方式繪制UI界面一點(diǎn)不重要,重要的是底層的思維,解決問題和優(yōu)化...
閱讀 1347·2021-11-25 09:43
閱讀 1906·2021-11-12 10:36
閱讀 6032·2021-09-22 15:05
閱讀 3490·2019-08-30 15:55
閱讀 2022·2019-08-26 14:06
閱讀 3651·2019-08-26 12:17
閱讀 511·2019-08-23 17:55
閱讀 2460·2019-08-23 16:23