如今寫個前端誰還不用個構建工具,天天早晨回去,找對應的項目目錄,打開命令行工具,敲個
npm run xxx
,重複得有點無聊。特別面對着日漸增加的項目數量,好但願有個工具能夠幫我管理全部的項目,兩手抓,一手起項目,一手抓個人叉燒包。emmmm...html
項目添加:經過拖拽項目package.json
文件到應用面板完成解析(不是.json文件?你試試) vue
項目管理:紅色區域展現添加的項目,支持切換/刪除/重命名;黃色區域展現package.json
中的scripts
腳本,點擊便可執行;綠色區域管理該項目下的多個命令行窗口,支持增長/刪除/切換;藍色區域爲命令行執行區域。 node
一次過知足您三個願望:react
node v8
+ electron v4.0 + macOSX v10.13(還沒支持windows,由於node-pty在windows上一直運行出錯,使用官網demo測試都不行,黔驢技窮呀。大佬們有興趣能夠試試,指點下我 連接)electron —— electron-quick-startwebpack
package.json目錄的main
字段指定electron應用的主渲染進程文件,除了該js文件之外,其餘的都屬於在渲染進程運行。git
"main": "electron/index.js"github
在electron/index.js中,配置electron加載的文件——開發環境下加載開發服務器文件,生成環境下加載本地文件。web
isDev
? mainWindow.loadURL('http://localhost:3000/index.html')
: mainWindow.loadFile(path.join(__dirname, '../react/build/index.html'))
複製代碼
react —— create-react-appvuex
把react的index.html指向electron目錄,在react/config/paths.js
中修改
appHtml: resolveApp('../electron/index.html')
react的腳手架沒有默認支持stylus?心好痛啊。本身動手,豐衣足食。create-react-app腳手架默認把webpack配置藏到node_modules中,須要執行npm run eject
後才能釋放出來。找到/config/webpack.config.js
文件,參照sass的配置,寫一遍stylus的,這樣以後xx.styl
的文件會被stylus-loader
處理,xx.module.styl
的文件會被當成局部樣式處理,相似於.vue
文件的<style lang="stylus" scoped>
const stylusRegex = /\.(styl)$/;
const stylusModuleRegex = /\.module\.(styl)$/;
// module裏追加stylus的配置
{
test: stylusRegex,
exclude: stylusModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
},
'stylus-loader'
),
sideEffects: true,
},
{
test: stylusModuleRegex,
use: getStyleLoaders(
{
importLoaders: 2,
sourceMap: isEnvProduction && shouldUseSourceMap,
modules: true,
getLocalIdent: getCSSModuleLocalIdent,
},
'stylus-loader'
),
},
複製代碼
使用開發者工具。安裝react-devtool(待續...)
componentDidUpdate
應用窗口resize後,web終端模擬器都要從新適配父元素的大小。在react中涉及dom更新後須要處理的邏輯(放在callback函數裏),一是使用this.setState({}, callback)
;二是在componentDidUpdate
裏處理。前者特別方便快捷,更新行爲跟數據源綁定到一塊兒,相似於vue
的vm.$nextTick
。後者就要麻煩不少了(誰叫你把狀態放在全局中處理呢),要特別設定一個isNew
變量來決定dom的更新回調是否執行。
ref屬性引用的傳遞
ref屬性不屬於props
,所以不走尋常路,在高階組件裏須要「委曲求全」地轉發(官宣)。
// Layout.js
import Main from 'Main.js'
export default class Layout extends Component {
constructor (props) {
super(props)
this.mainRef = React.createRef()
}
render () {
return (
<Main ref={this.mainRef} />
)
}
}
// Main.js
class Main extends Component {
render () {
const {
myRef
} = this.props
return (
<div ref={myRef}></div>
)
}
}
export default React.forwardRef((props, ref) => {
// 把ref引用賦給名爲'myRef'的props,達到傳遞的目的
return (
<Main
myRef={ref}
{...props}
/>
)
})
複製代碼
異步dispatch action
可以使用redux-thunk/redux-saga,因爲nodejs環境原生支持文件同步讀取fs.readFileSync
,因此如下兩種方法都可以。
reselect
相似vuex的computed屬性
// /store/selectors/project.js
import { createSelector } from 'reselect'
// 計算依賴值
const projectsSelector = state => state.project.projects
const activeIdSelector = state => state.project.activeId
export const getXtermList = createSelector(
projectsSelector,
activeIdSelector,
(projects, id) => {
// 入參對應createSelector前兩位參數的結果值
const project = projects.find(p => p.id === id)
// must return a new "xterms", otherwhiles, it cannot update. 這裏使用[ ...project.xterms ]是返回新的對象引用,不然不被看作有更新
const xterms = (project && project.xterms) ? [...project.xterms] : []
return xterms
}
)
// /src/Tab.js
import { getXtermList } from '/store/selectors/project.js'
@connect(
state => ({
xterms: getXtermList(state),
})
)
class Tabs extends Component {
render () {
<div>
{
this.props.xterms.map(() => (
<div>
{/* ... */}
</div>
))
}
</div>
}
}
export default Tabs
複製代碼
redux-persist
node-pty僞終端是node和系統shell之間的通信中間庫;xterm.js負責繪製瀏覽器端的終端模擬器。web終端使用表單模擬輸入,基本具有全部表單的api能力,支持代碼自動觸發和手動輸入觸發。
const os = window.require('os')
const pty = window.require('node-pty')
const Terminal = window.require('xterm').Terminal
class Xterm {
constructor () {
this.xterm = null
this.ptyProcess = null
this.createTerminal()
}
createTerminal () {
const shell = Xterm.shell
// 建立僞終端進程
this.ptyProcess = pty.spawn(shell, [], this.opts)
// 建立web終端模擬器
this.xterm = new Terminal()
this.initEvent()
}
initEvent () {
// web終端模擬器監聽用戶輸入,寫入系統shell
this.xterm.on('data', data => {
this.ptyProcess.write(data)
})
// node-pty監聽系統shell輸出,寫入web終端模擬器
this.ptyProcess.on('data', data => {
this.xterm.write(data)
})
}
/**
* 獲取系統信息,拿到對應的shell終端
*/
static get shell () {
return window.process.env[os.platform() === 'win32' ? 'COMSPEC' : 'bash']
}
}
複製代碼
window.require
,就能夠逃過webpack的編譯main process 調試
熱重啓:
// package.json
"scripts": {
"start": "electron .",
"watch": "nodemon --watch . --ignore 'app' --exec \"npm start\"",
"rebuild": "electron-rebuild -f -w node-pty"
}
複製代碼
打印:使用electron-log,打印信息和node調試信息同樣展現在控制檯中
主進程和渲染進程的通訊
Electron爲主進程( main process)和渲染器進程(renderer processes)通訊提供了多種實現方式,如可使用ipcRenderer 和 ipcMain模塊發送消息。經過這種方式能夠模擬右鍵菜單進行系統級的操做(如打開系統的某個文件目錄)
// react
const { ipcRenderer } = window.require('electron')
// renderer process 發送顯示右鍵菜單的請求
ipcRenderer.send('show-context-menu'})
// electron
const {
app,
BrowserWindow,
ipcMain,
Menu,
MenuItem
} = require('electron')
const template = [
{
label: '重命名',
click: this.rename.bind(this)
},
{
label: '打開文件目錄',
click: this.openFileManager.bind(this)
}
]
// 建立右鍵菜單
const menu = Menu.buildFromTemplate(template)
// main process 監聽renderer process請求
ipcMain.on('show-context-menu', (e, data) => {
const win = BrowserWindow.fromWebContents(e.sender)
// 彈出右鍵菜單
menu.popup(win)
})
複製代碼
原生desktop app菜單
讓換膚/toggle控制檯/刷新程序等app功能常駐於程序菜單項裏
打包。工具使用electron-builder,確保系統環境 必定要使用nodev8版本
必定要使用nodev8版本
必定要使用nodev8版本
,曾經使用了v10
,把網上幾乎全部的demo項目都運行過了一遍,發現都在打包過程當中出錯,絕望地死磕了三、4天。
package.json
中加入 "homepage": "./"。由於electron應用加載資源是使用本地文件的方式,使用相對路徑,而之前web服務後臺習慣使用絕對路徑加載。node原生模塊的編譯
若是項目裏使用了一些node原生模塊(用 C++ 編寫的 Node.js 擴展),在安裝後須要通過編譯才能被使用。例如該項目使用了node-pty
,能夠經過如下兩種辦法編譯,不編譯會報錯!!第一種方式在npm install
後將自動執行,第二種則須要手動執行。
To ensure your native dependencies are always matched electron version 源自electron-builder的說明
"postinstall": "electron-builder install-app-deps"
"rebuild": "electron-rebuild -f -w node-pty"
electron依賴下載。windows和mac都有全局緩存路徑的,若是使用npm下載卡住沒法進行下去,能夠嘗試去淘寶鏡像網站(electron下載連接)下載文件放到對應系統的緩存目錄,而後使用npm install安裝已經下載的版本號,緩存的electron文件便可被使用。(我?固然是搬個🍇(和諧了)直接下載)
發佈release版本
使用Travis配合electron-builder --publish指令,git push
後自動經過travis-ci打包,把app提交到github的release中。
GitHub上已提供打包後的程序,歡迎下載使用或者下載源碼自行構建(目前僅支持macOS)下載體驗地址
安裝程序
安裝時提示非信任應用程序??抱歉,來不及作macOS簽名。因此須要自行容許運行程序。處理教程
點個贊
或star
,謝謝鼓勵