视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
使用Electron构建React+Webpack桌面应用的方法
2020-11-27 22:23:34 责编:小采
文档

前言

Electron可以使用HTML、CSS、JavaScript构建跨平台桌面应用,可是在使用到React和Webpack时,会遇到一些配置问题,本文将针对React+Webpack下的Electron配置提供一个通用的解决方案。

环境配置

 "babel-core": "^6.26.0",
 "babel-loader": "^7.1.2",
 "babel-plugin-transform-class-properties": "^6.24.1",
 "babel-plugin-transform-object-rest-spread": "^6.26.0",
 "babel-preset-env": "^1.6.1",
 "babel-preset-react": "^6.24.1",
 "css-loader": "^0.28.7",
 "electron": "^1.7.9",
 "electron-packager": "^10.1.0",
 "extract-text-webpack-plugin": "^3.0.2",
 "node-sass": "^4.7.2",
 "react": "^16.2.0",
 "react-dom": "^16.2.0",
 "sass-loader": "^6.0.6",
 "style-loader": "^0.19.1",
 "webpack": "^3.10.0",
 "webpack-dev-server": "^2.9.7"

配置webpack.config.js

由于使用默认的Webpack打包,会生成一个很大的bundle文件,在桌面端比较影响性能,而调试的时候却需要较快地生成bundle,可是又需要使用sourcemap来定位bug,所以我们使用一个函数来切换各种环境:

module.exports = (env)=>{
 ******
 const isProduction = env==='production';
 ******
 devtool: isProduction ? 'source-map':'inline-source-map',

而我们在package.json文件里,编写以下命令:

"build:dev": "webpack",
"build:prod":"webpack -p --env production",

就可以较好的切换环境。

以下是全部webpack.config.js:

const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = (env)=>{
 const isProduction = env==='production';
 const CSSExtract = new ExtractTextPlugin('styles.css');
 console.log('env='+env);
 return {
 entry:'./src/app.js',
 target: 'electron-renderer',
 output:{
 path:path.join(__dirname, 'public','dist'),
 filename:'bundle.js'
 },
 module:{
 rules:[{
 loader: 'babel-loader',
 test: /\.js(x)?$/,
 exclude: /node_modules/
 }, {
 test: /\.s?css$/,
 use:CSSExtract.extract({
 use:[
 {
 loader:'css-loader',
 options:{
 sourceMap:true
 }
 },
 {
 loader:'sass-loader',
 options:{
 sourceMap:true
 }
 }
 ]
 })
 }]
 },
 plugins:[
 CSSExtract
 ],
 devtool: isProduction ? 'source-map':'inline-source-map',
 devServer:{
 contentBase: path.join(__dirname, 'public'),
 historyApiFallback:true,
 publicPath:'/dist/'
 }
 };
}

注意:target: 'electron-renderer',让我们的App在调试时只能在Electron下作用。

React

本次编写的是一个简单的显示时间的App,React 模块如下:

import React from 'react';
class Time extends React.Component{
 state = {
 time:''
 }
 getTime(){
 let date = new Date();
 let Year = date.getFullYear();
 let Month = date.getMonth();
 let Day = date.getDate();
 let Hour = date.getHours();
 let Minute = date.getMinutes();
 let Seconds = date.getSeconds();
 let time = Year+'年'+Month+'月'+Day+'日'+Hour+':'+Minute+':'+Seconds;
 return time;
 }
 componentDidMount(){
 setInterval(()=>{
 this.setState(()=>{
 return {
 time:this.getTime()
 }
 });
 },1000);
 }
 render(){
 let timetext = this.state.time;
 return (
 <div>
 <h1>{timetext}</h1>
 </div>
 );
 }
}
export default Time;

Electron

本次的App不涉及复杂的Electron API,仅仅作为展示的容器:

const electron = require('electron');
const {app,BrowserWindow} = electron;
let mainWindow = electron;
app.on('ready',()=>{
 mainWindow = new BrowserWindow({});
 mainWindow.loadURL(`file://${__dirname}/public/index.html`);
});

index.html

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>React-Webpack-Electron</title>
 <link rel="stylesheet" type="text/css" href="./dist/styles.css" rel="external nofollow" >
</head>
<body>
 <div id="app"></div>
 <script src="./dist/bundle.js"></script>
</body>
</html>

我们将webpack打包的js和css加载到html中。

调试

yarn run build:prod

首先我们用webpack打包文件,在dist/下生成bundle.js和style.css

yarn run electron

开始调试:

构建App

我们在package.json文件里添加如下命令:

"packager": "electron-packager . --platform=darwin --electron-version=1.7.9 --overwrite"

意思为构建Mac桌面应用,并覆盖之前我们使用该命令构建的文件。

等待一会儿会在目录下看到构建好的文件夹,里面便是我们的桌面应用。

而在这时我们打开应用,会发现其在调试中的导航栏菜单均已消失,只有一个退出选项,这是因为我们并没有设置应用的菜单栏项目,Electron在构建App时会舍去调试的各种菜单。

改进

大家应该注意到按照之前的方法,我们在调试时每修改一次就要重用webpack打包,当然也可以使用webpack-dev-server来监测改变。只不过这样我们需要对项目进行调整:

在index.js文件里修改loadURL为:

mainWindow.loadURL(`http://localhost:8080/index.html`);

再运行:

yarn run electron

因为此时我们是检测的webpack-dev-server下的文件,此时我们在项目中做的修改就能实时在electron中看到了。

若调试和测试完成,只需要修改loadURL为:

mainWindow.loadURL(`file://${__dirname}/public/index.html`);

即可进行下一步构建操作。

!注意,在构建最终应用前应该注意此时的web文件是否在webpack-dev-server下运作,若是则应该使用webpack生成静态打包文件。

本文项目文件地址:https://github.com/Voyager-One/react-webpack-electron

下载本文
显示全文
专题