将现有的Umijs添加electron支持

介绍

UMIjs在前端的范围内算是比较广泛选择的技术栈,因为其开箱即用而且集合了大部分前端开发中的常用工具,并且整合了Antd,对前端开发,特别是类似于控制台的开发都有较大的优势。

electron是将网页打包成桌面端应用的工具,对于前端来说,可以一套代码生成网页端和桌面端,非常的方便。

本文主要内容是将现有Umijs添加Electron支持。

所有的代码请查看 AllenTom/umi-electron-typescript-template

Electron

electron主要由Main和Renderer组成,Main包含了Node等常用的依赖,renderer包含了应用的UI,这两个共同组成了一个应用。

在UMIjs中 我们会使用umi build命令来输出打包后的文件,一般在/dist的文件夹中,例如:
将现有的Umijs添加electron支持_第1张图片
UMIjs可以将复杂的工程一键打包,输出多个源文件,输出的源文件可以任意地部署在需要的环境上。Electron并不使用Umijs的工程源码,而是在renderer中运行打包后的代码。

使用UMI生成前端代码
生成Electron代码
生成桌面应用

所以我们在生成electron应用前先执行umi build来将renderer中的代码准备好。

整个流程为

umi build
webpack
electron builder
使用UMI生成前端代码
Umi生成文件
dist
Electron
生成的Electron代码
release

改造

添加依赖

将一下依赖添加至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的代码

创建名为electron的目录并添加main.ts(文件夹名和文件名可自定义)
在这里插入图片描述

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();
  }
});

配置electron

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"
}

同时运行两个命令,就可以看到效果
将现有的Umijs添加electron支持_第2张图片
到了这里就算成功了一半,剩下的只需要输出对应平台的文件即可

生成App

配置

package.json中添加以下选项

 "build": {
    "appId": "com.my.app",
    "files": [
      "dist/",
      "node_modules/",
      "package.json"
    ],
    "directories": {
      "output": "release"
    }
  }
项目 注释
appId apid
files 包含的文件
directories.output 这里可以指定输出的文件夹名称,上文配置后,将会输出至./release,可以自定义

更多的配置项,请参阅electron-builder文档

添加资源文件,weback配置文件

创建build文件夹并添加
在这里插入图片描述
webpack.base.config.jswebpack.main.config.jswebpack.main.prod.config.js三个文件,分别对应开发环境的配置和生产环境的配置。

webpack.base.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',
}

webpack.main.config.js

开发环境

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',
})

webpack.main.prod.config.js

生产环境

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"
}

打包Electron

运行yarn build:electron:prod生成文件。

过程中可能会遇到报错,导致程序退出。其很大一部分是类似于语法规范的问题。
将现有的Umijs添加electron支持_第3张图片

可以选择根据错误提示逐个修复。
也可以在tsconfig.json中添加配置,忽略错误。

"awesomeTypescriptLoaderOptions": {
    "errorsAsWarnings": true
}

此时dist中包含的文件
将现有的Umijs添加electron支持_第4张图片

最后一步

执行相应的electron-builder命令,即可输出不同平台的应用,例如electron-builder --dir。其他的命令请参阅electron-builder文档

你可能感兴趣的:(Electron,typescript,前端)