一.搭建react+electron項目1.創(chuàng)建一個react項目create-react-app my-app cd my-app npm start 看下頁面是否打開,,是否運行正確,。 注意:如果頁面沒有src文件夾, 第一種:卸載全局安裝包:
然后 npm start,,瀏覽器會打開頁面,。 如果第一種不行,,用第二種 第二種:忽視掉本地的create-react-app已存在的版本進行項目的創(chuàng)建
2. 引入electronnpm install electron --save-dev
3. 配置1):在package.json配置入口文件,,具體如下:“main”:”main.js”
修改啟動命令:
2):main.js文件編寫const { app, BrowserWindow } = require('electron') const path = require('path') const pkg = require('./package.json'); let mainWindow function createWindow() { mainWindow = new BrowserWindow({ width: 800, height: 600, webPreferences: { preload: path.join(__dirname, 'preload.js') } }) // 加載應(yīng)用----react 打包 //mainWindow.loadURL(url.format({ //pathname: path.join(__dirname, './build/index.html'), //protocol: 'file:', //slashes: true //})) // 加載應(yīng)用----適用于 react 項目和開發(fā)階段npm run electron mainWindow.loadURL('http://localhost:3000/'); mainWindow.on('closed', function () { mainWindow = null }) } app.on('ready', createWindow) app.on('window-all-closed', function () { if (process.platform !== 'darwin') app.quit() }) app.on('activate', function () { if (mainWindow === null) createWindow() })
啟動:npm start npm run dev/electron 兩個命令都執(zhí)行時,,瀏覽器打開頁面,會打開桌面應(yīng)用,。
二.搭建react路由npm install --save react-router-dom
src/Index.jsimport React from 'react'; import ReactDOM from 'react-dom'; import ReactMap from './router/routerMap'; import * as serviceWorker from './serviceWorker'; ReactDOM.render( <div> <ReactMap /> </div> , document.getElementById('root')); // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: https:///CRA-PWA serviceWorker.unregister(); src/router/routerMap.js import React from 'react' import { HashRouter as Router, Route } from 'react-router-dom' import Login from '../pages/Login/Login' class ReactMap extends React.Component { updateHandle() { console.log("每次router變化后觸發(fā)") } render() { return ( <Router history={this.props.history}> <Route exact path="" component={Login} /> </Router> ) } } export default ReactMap;
三.搭建reduxnpm install --save react-redux npm install --save redux npm install --save redux-thunk
src/Index.jsimport React from 'react'; import ReactDOM from 'react-dom'; import ReactMap from './router/routerMap'; import * as serviceWorker from './serviceWorker'; import { Provider } from 'react-redux' import { createStore, applyMiddleware, compose } from 'redux' import rootRedux from './redux' import thunk from 'redux-thunk' const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose const enhancer = composeEnhancers(applyMiddleware(thunk)); const store = createStore( rootRedux, enhancer // applyMiddleware(thunk), // window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() ) ReactDOM.render( <div> <Provider store={store}> <ReactMap /> </Provider> </div> , document.getElementById('root')); // If you want your app to work offline and load faster, you can change // unregister() to register() below. Note this comes with some pitfalls. // Learn more about service workers: https:///CRA-PWA serviceWorker.unregister();
src/redux/index.jsimport { combineReducers } from 'redux'
import set from './set'
export default combineReducers({
data: set
})
src/redux/set.js
const set = (state = [], action) => { switch (action.type) { case 'GET_LIST': return { ...state, list: action.list } case 'SET_USERNAME': return { ...state, userName: action.list } default: return state } } export default set
src/actions/index.jsexport const getList = () => { return { type: 'GET_LIST', list: '1111' } } export const setUserName = (list) => { return { type: 'SET_USERNAME', list: list } }
四.不抽離 webpack配置的方案antd(npm run build 后找不到圖片路徑,,暫未解決)cnpm install --save react-app-rewired customize-cra cnpm install --save babel-plugin-import
1.配置less,less-loadercnpm install --save less less-loader
2. 根目錄新建config-overrides.js文件const { override, fixBabelImports, addWebpackAlias, addLessLoader } = require('customize-cra') const path = require('path') function resolve(dir) { return path.join(__dirname, dir) } // addLessLoader 添加less的引用 // fixBabelImports 按需加載antd組件 // addWebpackAlias 路徑別名配置 /* 路徑別名配置 */ module.exports = override( addWebpackAlias({ '@': resolve('src'), components: resolve('./src/components'), assets: resolve('./src/assets'), static: resolve('./src/static'), img: resolve('./src/static/img'), js: resolve('./src/static/js'), css: resolve('./src/static/css'), }), /* antd組件按需加載 */ fixBabelImports('import', { libraryName: 'antd', libraryDirectory: 'es', style: true, }), addLessLoader({ javascriptEnabled: true, modifyVars: { '@primary-color': '#1DA57A' }, }), );
3. 修改package.json文件,,目錄結(jié)構(gòu)
4. 使用:頁面引用lessimport '@/static/css/index.less'
五.抽離 webpack配置的方案npm run eject
運行后會出現(xiàn)config文件夾,,在里面配置less 和路徑別名配置 1.配置less,less-loadercnpm install --save less less-loader 在webpack.config.js里面進行less的配置
2.配置路徑別名在webpack.config.js里面進行路徑別名的配置
六.打包1.打包的準備工作:在package.json,里面加上”homepage”:”.”
在public里面加上main.js 和 package.json 和 preload.js package.json { "name":"crh_chat", "version":"1.0-test", "main":"main.js", "author": { "name":"YOURNAME" }, "license": "MIT" }
main.js 如果需要引用一些模塊就加入preload: path.join(__dirname, 'preload.js'),不用可以注釋掉這段 const electron = require('electron'); const path = require('path'); // 控制應(yīng)用生命周期的模塊 const { app } = electron; // 創(chuàng)建本地瀏覽器窗口的模塊 const { BrowserWindow } = electron; // 指向窗口對象的一個全局引用,,如果沒有這個引用,,那么當該javascript對象被垃圾回收的 // 時候該窗口將會自動關(guān)閉 let win; function createWindow() { // 創(chuàng)建一個新的瀏覽器窗口 win = new BrowserWindow({ width: 1920, height: 1080, autoHideMenuBar: true, webPreferences: { preload: path.join(__dirname, 'preload.js') } }); // 并且裝載應(yīng)用的index.html頁面 win.loadURL(`file://${__dirname}/index.html`); // 打開開發(fā)工具頁面 //win.webContents.openDevTools(); // 當窗口關(guān)閉時調(diào)用的方法 win.on('closed', () => { // 解除窗口對象的引用,通常而言如果應(yīng)用支持多個窗口的話,,你會在一個數(shù)組里 // 存放窗口對象,,在窗口關(guān)閉的時候應(yīng)當刪除相應(yīng)的元素。 win = null; }); } // 當Electron完成初始化并且已經(jīng)創(chuàng)建了瀏覽器窗口,,則該方法將會被調(diào)用,。 // 有些API只能在該事件發(fā)生后才能被使用。 app.on('ready', createWindow); /* var mainWindow = new BrowserWindow({ webPreferences: { nodeIntegration: false } }); */ // 當所有的窗口被關(guān)閉后退出應(yīng)用 app.on('window-all-closed', () => { // 對于OS X系統(tǒng),,應(yīng)用和相應(yīng)的菜單欄會一直激活直到用戶通過Cmd + Q顯式退出 if (process.platform !== 'darwin') { app.quit(); } }); app.on('activate', () => { // 對于OS X系統(tǒng),,當dock圖標被點擊后會重新創(chuàng)建一個app窗口,并且不會有其他 // 窗口打開 if (win === null) { createWindow(); } });
preload.js 這里引入了electron,,需要用的時候,,window.electron global.electron = require('electron') window.addEventListener('DOMContentLoaded', () => { const replaceText = (selector, text) => { const element = document.getElementById(selector) if (element) element.innerText = text } for (const type of ['chrome', 'node', 'electron']) { replaceText(`${type}-version`, process.versions[type]) } })
有兩個地方需要preload.js 外面那個是開發(fā)時要用的,public里面是打包后需要用到的,。
2.npm run build成功后會出現(xiàn)build文件夾,,雙擊index.html在瀏覽器打開,,可以正常運行
3.npm run package在pacakge.json里面的scripts配置
"package": "electron-packager ./build package0514 --win --out package/ --arch=x64 --app-version=1.1.0 --electron-version=8.0.0"
然后 npm run package 成功后頁面會生成一個package文件,里面有我們打包好的文件
|
|