UMIjs在前端的范围内算是比较广泛选择的技术栈,因为其开箱即用而且集合了大部分前端开发中的常用工具,并且整合了Antd,对前端开发,特别是类似于控制台的开发都有较大的优势。
electron是将网页打包成桌面端应用的工具,对于前端来说,可以一套代码生成网页端和桌面端,非常的方便。
本文主要内容是将现有Umijs添加Electron支持。
所有的代码请查看 AllenTom/umi-electron-typescript-template
electron主要由Main和Renderer组成,Main包含了Node等常用的依赖,renderer包含了应用的UI,这两个共同组成了一个应用。
在UMIjs中 我们会使用umi build
命令来输出打包后的文件,一般在/dist
的文件夹中,例如:
UMIjs可以将复杂的工程一键打包,输出多个源文件,输出的源文件可以任意地部署在需要的环境上。Electron并不使用Umijs的工程源码,而是在renderer中运行打包后的代码。
所以我们在生成electron应用前先执行umi build
来将renderer中的代码准备好。
整个流程为
将一下依赖添加至devDependencies
中,并安装。
{
"electron": "^9.1.0",
"electron-builder": "^22.4.1",
"electron-debug": "^3.0.1",
"electron-webpack": "^2.8.2",
"electron-webpack-ts": "^4.0.1"
}
创建名为electron
的目录并添加main.ts
(文件夹名和文件名可自定义)
代码在一些关键部分会给出注释,其他的请参阅Electron文档
import { app, BrowserWindow } from 'electron';
import * as path from 'path';
import * as url from 'url';
function createWindow() {
//创建窗口
const mainWindow = new BrowserWindow({
height: 900,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
webSecurity: false,
nodeIntegration: true,
},
backgroundColor: '#2e2c29',
darkTheme: true,
title: 'My App',
width: 1700,
frame: true,
minWidth:1300,
minHeight:900
});
if (process.env.NODE_ENV === 'development') {
// 开发环境
// 加载页面并打开调试工具,根据 NODE_ENV
// umijs 在dev时会给出相应的url,直接加载即可
mainWindow.loadURL('http://localhost:8000/');
mainWindow.webContents.openDevTools();
} else {
//生产环境
// 加载html文件
// 这里的路径是umi输出的html路径,如果没有修改过,路径和下面是一样的
mainWindow.loadURL(
url.format({
pathname: path.join(__dirname, './dist/index.html'),
protocol: 'file:',
slashes: true,
}),
);
}
mainWindow.on('closed', () => {
mainWindow = null;
});
}
app.on('ready', () => {
createWindow();
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 (BrowserWindow.getAllWindows().length === 0) createWindow();
});
});
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
在package.json
中添加相关内容
{
"main": "./dist/main/main.js",
"electronWebpack": {
"main": {
"sourceDirectory": "electron"
},
"renderer": {
"sourceDirectory": null
}
}
项目 | 注释 |
---|---|
main | 入口文件地址,即electron生成的文件路径 |
main.sourceDirectory | 源文件的文件夹(在上文中创建了electron 文件夹,可根据实际情况修改) |
renderer.renderer | 这里并不需要参与,由umijs来执行 |
到了这里我们可以简单的看一下开发环境下的状态了。
在package.json
中添加相应的script
{
"start:electron": "cross-env NODE_ENV=development electron-webpack dev",
"start": "umi dev"
}
同时运行两个命令,就可以看到效果
到了这里就算成功了一半,剩下的只需要输出对应平台的文件即可
在package.json
中添加以下选项
"build": {
"appId": "com.my.app",
"files": [
"dist/",
"node_modules/",
"package.json"
],
"directories": {
"output": "release"
}
}
项目 | 注释 |
---|---|
appId | apid |
files | 包含的文件 |
directories.output | 这里可以指定输出的文件夹名称,上文配置后,将会输出至./release ,可以自定义 |
更多的配置项,请参阅electron-builder文档
创建build
文件夹并添加
webpack.base.config.js
与webpack.main.config.js
和webpack.main.prod.config.js
三个文件,分别对应开发环境的配置和生产环境的配置。
通用的配置
const path = require('path')
module.exports = {
output: {
path: path.resolve(__dirname, '../dist/main'),
filename: '[name].js',
},
node: {
__dirname: false,
__filename: false,
},
resolve: {
extensions: ['.tsx', '.ts', '.js', '.json'],
},
devtool: 'source-map',
}
开发环境
const path = require('path')
const webpack = require('webpack')
const merge = require('webpack-merge')
const baseConfig = require('./webpack.base.config')
module.exports = merge.smart(baseConfig, {
target: 'electron-main',
entry: {
main: './electron/index.ts',
},
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'awesome-typescript-loader',
exclude: /node_modules/,
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
}),
],
mode: 'development',
})
生产环境
const path = require('path')
const webpack = require('webpack')
const merge = require('webpack-merge')
const baseConfig = require('./webpack.main.config')
module.exports = merge.smart(baseConfig, {
mode: 'production',
})
完成后,在package.json
中添加相应的scripts
{
"build:electron:prod": "cross-env NODE_ENV=production webpack --config ./build/webpack.main.prod.config.js",
"build:electron:dev": "cross-env NODE_ENV=development webpack --config ./build/webpack.main.config.js"
}
运行yarn build:electron:prod
生成文件。
过程中可能会遇到报错,导致程序退出。其很大一部分是类似于语法规范的问题。
可以选择根据错误提示逐个修复。
也可以在tsconfig.json
中添加配置,忽略错误。
"awesomeTypescriptLoaderOptions": {
"errorsAsWarnings": true
}
执行相应的electron-builder
命令,即可输出不同平台的应用,例如electron-builder --dir
。其他的命令请参阅electron-builder文档