electron-vite-vue/blog.md
草鞋没号 e8bed86cf9 blog
2020-08-17 17:43:07 +08:00

250 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Electron + vue3 + vite 整合
- 伴随着 `vue3` 的发布vue 全家桶又添新成成员 ——`vite` 脚手架工具;相比 `@vue/cli` 基于浏览器内置的 ES module 极快的冷启动速度、基于 `Rollup` 打包的配置更简单(确实简单)
`vite` 底层原理网上已有好多文章,本文主要讲使用
- 公司的项目用的整合方案是 `umi` + `electron` umi 是我用过目前最傻瓜化的框架了,你能想到的她都做了而且还是自动化的 👍
唯一一点不大好的 umi 的构建速度较慢;
vite 冷启动速度确实让人眼前一亮,索性拿来和 electron 集成一波;算是一个技术备选方案 `^_^`
> 毕竟 ****尤大出品,必是精品**** 定律嘛!
![](https://raw.githubusercontent.com/caoxiemeihao/electron-vue-vite/master/screenshot/800x600.png)
#### 准备材料
- `vue3`
- `vite` vue3 脚手架
- `electron`
- `electron-builder` electron 构建工具
- `electron-connect` 主进程代码修改热重启
- `rollup` 之前写过一个偏文章 [Electron、webpack、react、typescript 从零开始搭积木](https://www.jianshu.com/p/3aafab67ff70)
* 一来能少装个包vite 用的也是 rollup —— 入乡随俗
* 二来 rollup 的配置比 webpack 简单又专注于 js 的打包;只是用来打包 electron 主进程代码确实方便
- `concurrently` 同时启动 vite(渲染进程)、electron(主进程)
- `wait-on` 用于监听 vite 启动,随后拉起 electron 启动
- `chalk` 命令行文字颜色、背景色
- `ora` 命令行友好提示
- `minimist` 命令行参数解析
- `dotenv` 解析 .env 文件
#### 目录结构
```tree
.
├─dist 打包后的文件夹
├─screenshot
├─script
│ ├─build.js 主进程构建文件
│ └─rollup.config.js 主进程构建配置
└─src
├─main
│ └─index.ts 主进程入口文件
└─render
├─assets
├─components
├─dist vue 打包后目录
│ _assets
├─public
├─App.vue
├─index.css
├─index.html
└─main.js 渲染进程入口文件
└─.env 配置文件
```
#### 主进程构建配置
> script/rollup.config.js
- `@rollup/plugin-node-resolve` 支持引入 `node_modules` 模块
- `@rollup/plugin-commonjs` 支持 `require`、`module.exports` 写法
- `@rollup/plugin-typescript` 支持 `typescript`
```javascript
const path = require('path');
const { nodeResolve } = require('@rollup/plugin-node-resolve');
const commonjs = require('@rollup/plugin-commonjs');
const typescript = require('@rollup/plugin-typescript');
module.exports = (env = 'production') => {
return {
input: path.join(__dirname, '../src/main/index.ts'), // 入口文件
output: {
file: path.join(__dirname, '../src/main/_.js'), // 输出目标
format: 'cjs', // CommonJs 格式
name: 'ElectronMainBundle', // 模块名称(可选)
sourcemap: true,
},
plugins: [
nodeResolve({ jsnext: true, preferBuiltins: true, browser: true }), // 支持引入 node_modules 模块
commonjs(), // 支持 CommonJs 规范
typescript(), // 支持 TypeScript
],
external: [
// 告诉 rollup 碰到下面模块时候不要去打包
'fs',
'path',
'http',
'https',
'child_process',
'os',
'electron',
],
}
};
```
#### 主进程构建脚本
> script/build.js
- 实现思路: 使用 `wait-on` 监听 `vite` 启动,然后拉起 `electron` 打开渲染进程加载 vue 应用
- `rollup` 使用比较简单
* 如果是开发模式用 `rollup.watch(options)` 会监听文件变化,文件改变自动重新编译
* 如果只是构建使用 `rollup.rollup(options)` 只会执行一次构建
```javascript
/**
* electron 打包
*/
const path = require('path');
const rollup = require('rollup');
const argv = require('minimist')(process.argv.slice(2));
const chalk = require('chalk');
const ora = require('ora');
const waitOn = require('wait-on');
const electron = require('electron-connect').server.create({ stopOnClose: true }); // 表示要操作主进程端(对应的还是渲染进程端;渲染进程用的 vite 热更新)
require('dotenv').config({ path: path.join(__dirname, '../.env') }); // 解析项目根目录下的 .env 文件
const options = require('./rollup.config'); // 引入 rollup 配置
const opt = options(argv.env);
const TAG = '[script/build.js]';
const spinner = ora(`${TAG} Electron build...`);
if (argv.watch) { // 开发模式 (命令行传入 --watch 标识)
waitOn({
resources: [`http://localhost:${process.env.PORT}`], // 等待 vite 服务器启动,然后拉起 electron
log: false,
}, err => {
if (err) {
console.log(err);
process.exit(1);
}
// once here, all resources are available
const watcher = rollup.watch(opt);
watcher.on('change', filename => {
const log = chalk.green(`change -- ${filename}`);
console.log(TAG, log);
});
watcher.on('event', ev => {
if (ev.code === 'END') {
// init-未启动、started-第一次启动、restarted-重新启动
electron.electronState === 'init' ? electron.start() : electron.restart();
}
});
});
} else { // 构建模式
spinner.start();
rollup.rollup(opt)
.then(build => {
spinner.stop();
console.log(TAG, chalk.green('Electron build successed.'));
build.write(opt.output);
})
.catch(error => {
spinner.stop();
console.log(`\n${TAG} ${chalk.red('构建报错')}\n`, error, '\n');
});
}
```
#### 渲染进程 vite 配置
> vite.config.ts
- 需要改变 `vite` 的构建路径,因为 vue 代码移动到了 `src/render`
- 通过 `.env` 配置启动端口,配合主进程监听端口启动
```typescript
/**
* 参考链接: https://github.com/vitejs/vite/blob/master/src/node/config.ts
*/
import { join } from 'path'
import { UserConfig } from 'vite'
import dotenv from 'dotenv'
dotenv.config({ path: join(__dirname, '.env') })
const config: UserConfig = {
// vite 项目编译、启动的根目录
// 默认指向项目跟目录,我们把 vue(渲染进程) 代码全部搬到 src/render 下
root: join(__dirname, 'src/render'),
// 通过 .env 配置端口,能够让 electron 加载到正确的地址
port: +process.env.PORT,
// 打包后的 vue 项目引入 js、css、favicon 等资源路径
base: './',
}
export default config
```
#### 启动脚本配置
```json
{
"main": "src/main/_.js",
"scripts": {
"dev": "npm run dev:all",
"dev:all": "concurrently -n=vue,ele -c=green,blue \"npm run dev:vue\" \"npm run dev:ele\"",
"dev:vue": "vite",
"dev:ele": "node script/build --env=development --watch",
"build:vue": "vite build",
"build:ele": "node script/build --env=production",
"build": "npm run build:vue && npm run build:ele && electron-builder"
}
}
```
- main `electron` 启动后会加载 main 配置的文件
- dev:all 使用 `concurrently` 同时启动 `dev:vue`、`dev:ele`
- dev:ele `electron` 开发模式脚本,通过传入 `--watch` 表示 rollup 监听主进程变化自动编译
- build 使用 `electron-builder` 打包
#### 启动一下试试
```bash
$ yarn dev
yarn run v1.22.4
$ npm run dev:all
> electron-vue@0.0.1 dev:all D:\github\electron-vue-vite
> concurrently -n=vue,ele -c=green,blue "npm run dev:vue" "npm run dev:ele"
[ele]
[ele] > electron-vue@0.0.1 dev:ele D:\github\electron-vue-vite
[ele] > node script/build --env=development --watch
[ele]
[vue]
[vue] > electron-vue@0.0.1 dev:vue D:\github\electron-vue-vite
[vue] > vite
[vue]
[vue] vite v1.0.0-rc.4
[vue]
[vue] Dev server running at:
[vue] > Network: http://192.168.1.9:3344/
[vue] > Network: http://192.168.119.1:3344/
[vue] > Network: http://10.0.60.32:3344/
[vue] > Local: http://localhost:3344/
[vue]
[ele] [2020-08-17T08:57:11.850Z] [electron-connect] [server] started electron process: 1488
[ele] [2020-08-17T08:57:11.851Z] [electron-connect] [server] server created and listening on 30080
[ele]
```
#### 尾巴
- 2019 款 13 寸 mac-pro 启动速度 4秒 左右
- 奔腾 G4560 台机 CUP 神舟笔记本启动速度 6 秒左右
- 毋庸置疑 vite 的方案比起 @vue/cli、umi、create-react-app 这类基于 webpack 的脚手架启动这块的优势大的多滴多
- 技术总是飞快的迭代、进步,目的都是解决一些已经存在、或即将到来的问题;继续治疗、学习起来、加油哇~