diff --git a/source/_posts/vite-react-electron-boilerplate.md b/source/_posts/vite-react-electron-boilerplate.md new file mode 100644 index 0000000..8893d43 --- /dev/null +++ b/source/_posts/vite-react-electron-boilerplate.md @@ -0,0 +1,201 @@ +--- +title: 构建一套基于Vite+React的Electron应用脚手架 +tags: + - 前端 + - React + - Electron + - Vite +categories: + - - 前端 + - React +keywords: 'vite,react,electron,脚手架,应用' +date: 2022-05-11 11:14:31 +--- + +之前构建过一套基于Create-React-App的Electron应用脚手架,但是在日常的使用过程中发现,新出的Vite工具在构建和编译、打包的过程更加迅速。所以这就有了现在这篇文章,也就是尝试制作一个基于Vite进行构建的模板。 + +## 创建React项目 + +首先以一个普通的React项目作为整个项目的基础。利用`npm create`命令创建一个空白的React项目。 + +```bash +npm create vite@lastest vite-react-electron -- --template react-ts +``` + +!!! caution "" + 这里需要注意的是,如果使用的是NPM 6.x版本,name就不需要额外的`--`。 + +此时进入到项目中以后,可以运行`npm run dev`命令使项目运行在`http://localhost:3000`上。其实为了在项目中更加方便的使用环境变量,其实还需要安装`cross-env`库的支持。 + +## 增加Electron支持 + +接下来就是向项目中添加Electron框架的支持。这只需要在新建的项目目录中执行以下命令即可。 + +```bash +npm install --save-dev electron electronmon +``` + +!!! caution "" + 在国内的网络环境中,安装Electron经常会因为访问超时而失败。这时可以通过添加一个名为`ELECTRON_MIRROR`的环境变量来解决。环境变量的值可以设置为淘宝的镜像站,也就是`ELECTRON_MIRROR="http://npm.taobao.org/mirrors/electron/"`。 + +!!! caution "" + 或者还可以采用之前文章中所描述的使用`electron-fix`库获取Electron的方法。 + +完成添加Electron依赖以后,就需要在项目中添加用于启动Electron的`main.ts`文件。以下是目前最简单的`main.ts`文件内容。 + +```typescript +import { app, BrowserWindow } from 'electron'; +import path from 'path'; +import installExtension, { REACT_DEVELOPER_TOOLS } from 'electron-devtools-installer'; + +const isDev = process.env.NODE_ENV === 'development'; + +const createWindow = (): void => { + const mainWindow = new BrowserWindow({ + height: 600, + width: 800, + webPreferences: { + nodeIntegration: false, + nodeIntegrationInWorker: true, + nodeIntegrationInSubFrames: true, + enableRemoteModule: true, + contextIsolation: true, + preload: path.join(__dirname, 'preload.js') + } + }); + + if (isDev) { + installExtension([REACT_DEVELOPER_TOOLS]) + .then(() => { + mainWindow.loadURL('http://localhost:3000'); + mainWindow.webContents.openDevTools(); + }) + .catch(err => console.log('An error occurred: ', err)); + } else { + mainWindow.loadFile(path.join('build', 'index.html')); + } +}; + +app.whenReady().then(createWindow); + +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit(); + } +}); +``` + +与之前文章中拥有同样的原因,`src`目录被React占用,所以`main.ts`就只能放置在`src-main`这个目录里了。对于`src-main`目录中内容的编译,可以参考之前文章中的`tsconfig.main.json`配置。 + +!!! caution "" + 在晒伤`src-main`中需要创建的文件除了`main.ts`以外,还有`preload.ts`,这个文件的内容同样也可以参考之前文章中提到的基于CRA的模板项目。对于示例代码中所使用到的`electron-devtools-installer`,也可以直接参考之前的文章中介绍的内容。 + +## 附加的命令集配置 + +因为`main.js`是使用Typescript编写的,所以就需要进行实时编译。而且跟之前的文章中介绍的一样,在Electron应用开发调试的时候,是需要同时运行多个NPM命令的,所以还需要使用到`concurrently`库。同样运行以下命令安装`concurrently`。 + +```bash +npm install --save-dev concurrently +``` + +!!! info "" + 在之前的文章中采用了`wait-on`库来完成检测前端开发服务器是否启动。`wait-on`库的主要用途是检测一个条件,当条件不满足的时候阻塞后续命令的执行。加入进来的主要目的在于使Electron窗口启动的时候,调试内容不会出现加载失败的情况。但是在目前的许多测试中,`wait-on`库出现了很多不能正常工作的问题。 + +接下来需要编写一个用于检测前端开发服务器是否启动的脚本,来实现在前端开发服务器正常启动以后再启动ELectron的需求。 + +```bash +#!/bin/bash +# 这个脚本在项目中被命名为 wait-for +until $(curl --output /dev/null --silent --fail $1); do + sleep 5 +done +``` + +接下来就是继续编辑`package.json`,使其中的常用命令集能够方便启动Electron应用的开发模式和编译过程。在`package.json`中添加以下内容,顺序不限。 + +```json +{ + "main": "./build/main.js", + "scripts": { + "dev": "concurrently \"npm:dev:renderer\" \"npm:dev:main\" \"npm:dev:electron\"", + "dev:renderer": "vite", + "dev:main": "tsc --project tsconfig.main.json --watch", + "dev:electron": "./wait-for http://localhost:3000 && cross-env NODE_ENV=development electronmon .", + } +} +``` + +在这套命令集的支持下,Electron应用的开发运行可以通过`npm run dev`命令来启动。 + +## 在项目中使用Tailwind CSS + +Tailwind CSS是一款非常便捷的样式设置框架,其实要把它应用在项目李是十分容易的,但是在这里,我计划把它跟Emotion这个Styled Component库组合起来用。 + +首先要完成的事情是在已有的项目中安装Tailwind CSS,因为整个项目是使用Vite构建的,使用PostCSS导入Tailwind CSS样式是一个比较好的选择。所以需要安装以下依赖。 + +```bash +npm install -D tailwindcss postcss autoprefixer +``` + +接下来就是创建Tailwind CSS的配置文件和在启动时加载的基础样式文件。执行命令`npx tailwindcss init -p`可以在项目中创建一个默认的Tailwind CSS配置文件。这个命令会同时创建两个文件:`tailwind.config.js`、`postcss.config.js`。 + +!!! info "" + 创建Tailwind CSS配置的命令中的参数`-p`表示需要创建一个PostCSS的配置文件`postcss.config.js`。如果项目中已经存在了这个PostCSS的配置文件,那么就可以不使用`-p`参数了。 + + +然后是安装Emotion,但是在安装Emotion的时候,还需要捎带安装Twin.macro,这个库可以利用Babel宏,允许在Styled Components风格下使用Tailwind CSS,或者是代替`className`直接在组件上使用Tailwind CSS样式。在项目目录中运行以下命令可以完成Emotion和Twin.macro的安装。 + +```bash +npm install @emotion/react @emotion/styled +npm install --save-dev twin.macro @emotion/babel-plugin-jsx-pragmatic babel-plugin-macros +``` + +接下来需要配置Babel宏插件,把Twin.macro整合进来,然后再让Twin.macro能够使用Emotion库来形成Styled Component。要完成这一步的工作需要在项目的根目录中配置`babel-plugin-macros.config.js`文件。这个文件的内容很简单,如以下所示。 + +```javascript +module.exports = { + twin: { + preset: 'emotion' + } +}; +``` + +最后就是把Babel宏插件加入到Vite的构建配置中。这一步需要编辑`vite.config.ts`文件。以下是`vite.config.ts`文件的全部内容。 + +```typescript +import react from '@vitejs/plugin-react'; +import { defineConfig } from 'vite'; + +// https://vitejs.dev/config/ +export default defineConfig({ + server: { + port: 4500 + }, + plugins: [ + react({ + babel: { + plugins: [ + 'babel-plugin-macros', + [ + '@emotion/babel-plugin-jsx-pragmatic', + { + export: 'jsx', + import: '__cssprop', + module: '@emotion/react' + } + ], + ['@babel/plugin-transform-react-jsx', { pragma: '__cssprop' }, 'twin.macro'] + ] + } + }) + ] +}); +``` + +## 一个可以即刻使用的项目模板 + +进行到这里,项目就基本上可以用于Electron应用的开发了。不过为了方便项目的构建,我特地制作了一套脚手架项目供新建项目的时候快速搭建项目结构使用。 + +这个脚手架可以利用`degit`工具使用,在克隆到本地以后,只需要修改`package.json`中的项目名称,在运行`npm install`即可开始Electron应用的开发。 + +脚手架项目可以在[vite-react-electron](https://github.com/vixalie/vite-react-electron.git)找到。