electron踩坑记(一):electron + react + typescript + antd 开发环境搭建

electron + react + typescript + antd 环境搭建

  • 一定要用管理员权限打开
  • 一定要保证网络快速(否则会有各种问题)
  • 安装过程中可能出现的问题和解决方法
    • 1. 更新npm到最新版本,并安装淘宝镜像
    • 2. 安装yarn
    • 3. 安装create-react-app
    • 4. 创建 react + typescript 项目
    • 5. 安装 react-app-rewired 以及 cross-env
    • 6. 在根目录下,创建 react-app-rewired 配置文件 config-overrides.js 用于扩展 webpack 配置
    • 7. 安装 electron 环境
    • 8. 在根目录下,创建 electron 入口文件;在`package.json`中加入【`"main": "./main.js"`】
    • 9. 在`package.json`中修改覆盖相关脚本
    • 10. 安装antd,babel-plugin-import,customize-cra
    • 11. 安装react-router-dom
    • 12. 在src/views下,新建`read-txt.tsx`
    • 13. 在根目录下,新建`router.tsx`,并引入当前已经有的两个页面:App,read-txt
    • 14. 修改src下的`index.tsx`
    • 15. 修改`App.tsx`
    • 16. 修改`config-overrides.js`
    • 17. 启动程序
    • 关于electron打包的问题,身为electron菜鸟还需要再研究研究....

参考博客
1.electron + react + typescript 环境搭建
2. react+electron+AntD编辑桌面应用
3. 在React中使用react-router-dom路由

这里只是总结安装命令,具体原理请查看上面的参考博客。

一定要用管理员权限打开

·win10系统

第一种方法:点击底部操作栏的放大镜,输入【cmd】,选择【以管理员身份运行】
第二种方法:在项目目录下,按【shift + 右击】,选择【在此处打开Powershell窗口】
第三种方法:按【win + x】,选择【Windows Powershell(管理员)】

一定要保证网络快速(否则会有各种问题)

安装过程中可能出现的问题和解决方法

  1. Maximum call stack size exceeded 超过最大调用栈问题
    npm install -g npm
  2. WARN deprecated [email protected]: request has been deprecated
    npm install -g cnpm --registry=https://registry.npm.taobao.org
    或者npm config set registry https://registry.npm.taobao.org
  3. Install fail! Error: EBUSY: resource busy or locked, rename
    (1)关闭项目所在的文件夹,cmd窗口
    (2)执行cnpm cache clean --force清除npm的缓存
    (3)重新打开cmd窗口运行安装命令cnpm install
    (4)注意,如果一开始用cnpm,就最好一直用cnpm,不要跟npm来回换,可以试试yarn。
  4. 执行过程出错或者网络超时,可以先试试执行cnpm cache clean --force清除npm的缓存,再重新安装。

1. 更新npm到最新版本,并安装淘宝镜像

# 更新到最新版本
npm install -g npm
# 安装淘宝镜像
npm install -g cnpm --registry=https://registry.npm.taobao.org
# 配置淘宝镜像
npm config set registry https://registry.npm.taobao.org
# 查看配置
npm config get registry
# 查看版本
npm  -v
cnpm  -v

2. 安装yarn

# 安装yarn
cnpm install -g yarn
# 查看版本
yarn -v

3. 安装create-react-app

cnpm install --global create-react-app

4. 创建 react + typescript 项目

npx create-react-app my-app --typescript
# 进入项目目录
cd my-app

5. 安装 react-app-rewired 以及 cross-env

cnpm i -D react-app-rewired cross-env

6. 在根目录下,创建 react-app-rewired 配置文件 config-overrides.js 用于扩展 webpack 配置

/config-overrides.js
module.exports = (config, env) => {
     
  // 为了方便使用 electron 以及 node.js 相关的 api
  // 需要将 target 设置为 electron-renderer
  // 设置了 target 之后,原生浏览器的环境将无法运行此 react 项目(因为不支持 node.js 相关的 api),会抛出 Uncaught ReferenceError: require is not defined 异常
  // 需要在 electron 的环境才能运行(因为支持 node.js 相关的 api)
  // 这一步的操作, 都是为了能与 electron 进行更好的集成
  config.target = 'electron-renderer';
  return config;
};

7. 安装 electron 环境

cnpm i -D electron

8. 在根目录下,创建 electron 入口文件;在package.json中加入【"main": "./main.js"

/main.js
const {
      app, BrowserWindow } = require('electron');
const path = require('path');
const url = require('url');

// 创建浏览器窗口
let mainWindow = null;
const createWindow = () => {
     
  let mainWindow = new BrowserWindow({
     
    width: 800,
    height: 600,
    webPreferences: {
     
      nodeIntegration: true,
      // preload: path.join(__dirname, 'preload.js')
    }
  });
  /**
     * loadURL 分为两种情况
     *  1.开发环境,指向 react 的开发环境地址
     *  2.生产环境,指向 react build 后的 index.html
     */
  const startUrl =
    process.env.NODE_ENV === 'development'
      ? 'http://localhost:3000'
      : path.join(__dirname, "/build/index.html");
  mainWindow.loadURL(startUrl);

  // 打开开发者工具
  mainWindow.webContents.openDevTools()

  mainWindow.on('closed', function () {
     
    mainWindow = null;
  });
};
app.on('ready', createWindow);

app.on('window-all-closed', function () {
     
  // 在 macOS 上,除非用户用 Cmd + Q 确定地退出,
  // 否则绝大部分应用及其菜单栏会保持激活。
  if (process.platform !== 'darwin') app.quit();
});

app.on('activate', function () {
     
  // 在macOS上,当单击dock图标并且没有其他窗口打开时,
  // 通常在应用程序中重新创建一个窗口。
  if (mainWindow === null) createWindow();
});

9. 在package.json中修改覆盖相关脚本

"scripts": {
     
    "start": "cross-env BROWSER=none react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test --env=jsdom",
    "eject": "react-scripts eject",
    "start-electron": "cross-env NODE_ENV=development electron .",
    "start-electron-prod": "electron ."
  },

10. 安装antd,babel-plugin-import,customize-cra

# 安装antd
cnpm install antd
# 或
yarn add antd

# 安装babel-plugin-import
cnpm install babel-plugin-import
# 或
yarn add babel-plugin-import --dev

# 安装customize-cra
cnpm install customize-cra --save-dev
# 或
yarn add customize-cra

注意,安装antd只有出现下图才是安装成功
electron踩坑记(一):electron + react + typescript + antd 开发环境搭建_第1张图片

11. 安装react-router-dom

# 安装react-router-dom
cnpm install react-router-dom --save-dev
# 安装@types/react-router-dom
cnpm install @types/react-router-dom

12. 在src/views下,新建read-txt.tsx

src/views/ReadTxt.tsx


import React from 'react';
import {
      remote } from 'electron';
import fs from 'fs';
interface Props {
     
}
interface State {
     
    txtFileData: string;
}
export default class ReadTxt extends React.Component<Props, State> {
     
    constructor(props: Props) {
     
        super(props);
        this.state = {
     
            txtFileData: ''
        };
    }
    /**
       * 弹出文件选择框,选择 .txt 文件
       * 将选中的 .txt 内容展示到页面
       */
    public readTxtFileData = async () => {
     
        const result = await remote.dialog.showOpenDialog({
     
            title: '请选择 .txt 文件',
            filters: [
                {
     
                    name: 'txt',
                    extensions: ['txt']
                }
            ]
        });
        fs.readFile(result.filePaths[0], 'utf-8', (err, data) => {
     
            if (err) {
     
                console.error(err);
            } else {
     
                this.setState({
     
                    txtFileData: data.replace(/\n|\r\n/g, '
'
) }); } }); }; public render = (): JSX.Element => { return ( <section style={ { padding:20}}> <button onClick={ this.readTxtFileData}>读取一个txt文件的内容</button> <div dangerouslySetInnerHTML={ { __html: this.state.txtFileData }} /> <a type="link" href="/">返回到App页面</a> </section> ); }; }

13. 在根目录下,新建router.tsx,并引入当前已经有的两个页面:App,read-txt

router.tsx
import React from 'react';
import {
      HashRouter, Route, Switch } from 'react-router-dom';
import App from "./App";
import ReadTxt from "./views/ReadTxt"

export default class Router extends React.Component {
     
    public render = (): JSX.Element => {
     
        return (
            <HashRouter>
                <Switch>
                    <Route exact path={
     '/'} component={
     App} />
                    <Route exact path={
     '/readTxt'} component={
     ReadTxt} />
                </Switch>
            </HashRouter>
        );
    }
}

14. 修改src下的index.tsx

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
// import App from './App';
import * as serviceWorker from './serviceWorker';
import Router from './router';

ReactDOM.render(
  <React.StrictMode>
    <Router />
  </React.StrictMode>,
  document.getElementById('root')
);

serviceWorker.unregister();

15. 修改App.tsx

import React from 'react';
import {
      DatePicker } from 'antd';
const {
      MonthPicker, RangePicker, WeekPicker } = DatePicker;

export default class IndexPage extends React.Component {
     

  public onChange(date: any, dateString: any) {
     
    console.log(date, dateString);
  }

  public render = (): JSX.Element => {
     
    return (
      //  
      <div style={
     {
     padding:20}}>
        <DatePicker onChange={
     this.onChange} />
        <br />
        <MonthPicker onChange={
     this.onChange} placeholder="Select month" />
        <br />
        <WeekPicker onChange={
     this.onChange} placeholder="Select week" />
        <br />
        <a type="link" href="/#/readTxt">跳转到ReadTXT</a>
      </div>
    )
  }
}

16. 修改config-overrides.js

config-overrides.js
// react-app-rewired是react社区开源的一个修改CRA配置的工具,
// 用于扩展Create React App的Webpack配置,
// 而customize-cra提供了一组用于自定义利用react-app-rewired核心功能的Create React App v2配置, 
// 可以通过config-overrides.js文件来对webpack配置进行扩展

const {
     
  override,
  fixBabelImports,
  addWebpackAlias
} = require('customize-cra');

const path = require("path");
module.exports = override(
  //按需加载antd
  fixBabelImports('import', {
     
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: 'css', // true是less,如果不用less style的值可以写'css' 
  }),
  //别名配置
  addWebpackAlias({
     
    ["@"]: path.resolve(__dirname, "./src"),
    ["@views"]: path.resolve(__dirname, "./src/views"),
    ["@components"]: path.resolve(__dirname, "./src/components")
  }),

  (config) => {
     
    // 为了方便使用 electron 以及 node.js 相关的 api
    // 需要将 target 设置为 electron-renderer
    // 设置了 target 之后,原生浏览器的环境将无法运行此 react 项目(因为不支持 node.js 相关的 api),会抛出 Uncaught ReferenceError: require is not defined 异常
    // 需要在 electron 的环境才能运行(因为支持 node.js 相关的 api)
    // 这一步的操作, 都是为了能与 electron 进行更好的集成
    config.target = 'electron-renderer';
    return config;
  }
);

17. 启动程序

打开两个命令行窗口,一个命令行窗口跑 react 项目:npm run start,另一个命令行窗口跑 electron 项目:npm run start-electron。注意,必须启动两个。

程序运行结果如下图:
electron踩坑记(一):electron + react + typescript + antd 开发环境搭建_第2张图片
electron踩坑记(一):electron + react + typescript + antd 开发环境搭建_第3张图片

关于electron打包的问题,身为electron菜鸟还需要再研究研究…

你可能感兴趣的:(Electron,react,javascript)