美文网首页技术干货
React+Electron+antd+Less集成环境配置

React+Electron+antd+Less集成环境配置

作者: 袁俊亮技术博客 | 来源:发表于2018-02-22 20:40 被阅读3143次

    React+Electron+antd+Less集成环境配置

    标签(空格分隔): React


    [TOC]

    React+Electron+antd+Less集成环境配置

    通过create-react-app创建React项目

    • 下载create-react-app并创建my-app项目
    npm install -g create-react-app
    create-react-app my-app
    
    cd my-app
    npm start
    
    • 打包项目

    这种打包方式一般是打包完以后直接将build文件夹中的内容上传到服务器。为webpack打包

    集成antdless

    • 下载antd安装包
    npm i antd --save
    
    • 集成antd的样式

    src/App.css的顶部引入antd/dist/antd.css

    @import '~antd/dist/antd.css';
    
    .App {
      text-align: center;
    }
    

    上诉方式已经集成了antd。但是这种方式是加载了全部的antd组件,对前端性能会造成影响。通常我们会通过以下方式集成antd

    • 添加react-app-rewired、添加babel-plugin-import、添加less
    yarn add react-app-rewired --dev
    yarn add babel-plugin-import --dev
    yarn add react-app-rewire-less --dev
    

    集成Electron

    • 安装Electron
    npm i electron --save
    
    • 在项目根目录创建main.js文件
    const {app, BrowserWindow} = require('electron')
    const path = require('path')
    const url = require('url')
    const pkg = require('./package.json')
    
    // 保持一个对于 window 对象的全局引用,如果你不这样做,
    // 当 JavaScript 对象被垃圾回收, window 会被自动地关闭
    let win
    
    function createWindow () {
      // 创建浏览器窗口。
      win = new BrowserWindow({width: 800, height: 600})
    
      // 然后加载应用的 index.html。
      // package中的DEV为true时,开启调试窗口。为false时使用编译发布版本
      if(pkg.DEV){
        win.loadURL('http://localhost:3000/')
      }else{
        win.loadURL(url.format({
          pathname: path.join(__dirname, './build/index.html'),
          protocol: 'file:',
          slashes: true
        }))
      }
    
      // 打开开发者工具。
      // win.webContents.openDevTools()
    
      // 当 window 被关闭,这个事件会被触发。
      win.on('closed', () => {
        // 取消引用 window 对象,如果你的应用支持多窗口的话,
        // 通常会把多个 window 对象存放在一个数组里面,
        // 与此同时,你应该删除相应的元素。
        win = null
      })
    }
    
    // Electron 会在初始化后并准备
    // 创建浏览器窗口时,调用这个函数。
    // 部分 API 在 ready 事件触发后才能使用。
    app.on('ready', createWindow)
    
    // 当全部窗口关闭时退出。
    app.on('window-all-closed', () => {
      // 在 macOS 上,除非用户用 Cmd + Q 确定地退出,
      // 否则绝大部分应用及其菜单栏会保持激活。
      if (process.platform !== 'darwin') {
        app.quit()
      }
    })
    
    app.on('activate', () => {
      // 在macOS上,当单击dock图标并且没有其他窗口打开时,
      // 通常在应用程序中重新创建一个窗口。
      if (win === null) {
        createWindow()
      }
    })
    
    // 在这文件,你可以续写应用剩下主进程代码。
    // 也可以拆分成几个文件,然后用 require 导入。
    // 在这里可以添加一些electron相关的其他模块,比如nodejs的一些原生模块
    // 文件模块
    // const BTFile = require('./sys_modules/BTFile')
    // BTFile.getAppPath()
    
    • package.json中添加以下命令
    "main": "main.js",
    "homepage": ".",
    "DEV": true 
    
    • 修改package.json文件中的script中的命令如下
     "scripts": {
        "start": "react-app-rewired start",
        "build": "react-app-rewired build",
        "test": "react-app-rewired test --env=jsdom",
        "eject": "react-scripts eject",
        "electron-start": "electron .",
        "electron-package": "electron-packager . app --darwin --out presenterTool --arch=x64 --overwrite --ignore=node_modulesls --electron-version=1.8.2"
      },
    

    运行electron项目

    npm start 
    npm run electron-start
    

    打包electron项目

    • 下载electron-package打包插件
    npm i electron-package --save-dev
    sudo npm i electron-package -g
    
    1. 修改package.json

    "DEV":true改为"DEV":false

    1. 运行npm run build

    2. 打包npm run electron-package

    解释

    - "main":"main.js"
    
    electron 打包的入口文件
    
    - "homepage":"."
    
    通过`npm run build`是通过`webpack`打包出来的`build`项目是绝对路径。在`electron`中很多资源都引用不到。添加该配置可以将路径改为相对路径
    
    - "DEV":true
    
    这是项目开发环境,如果为true  mian.js中electron的入口为`http://localhost:3000/`。通过`electron .`运行项目时需要先`npm start`启动项目。然后`electron .`运行项目
    
    - "DEV":false
    
    这是项目的发布环境。需要先`npm run build`打包项目。然后通过`electron-packager . app --darwin --out presenterTool --arch=x64 --overwrite --ignore=node_modulesls --electron-version=1.8.2`打包项目
    
    

    最终的配置文件

    • package.json
    {
      "name": "wallet",
      "version": "0.1.0",
      "private": true,
      "main": "main.js",
      "homepage": ".",
      "DEV": true,
      "dependencies": {
        "antd": "^3.2.1",
        "crypto-js": "^3.1.9-1",
        "eccrypto": "^1.0.3",
        "electron-log": "^2.2.14",
        "eosjs-ecc": "^2.0.1",
        "react": "^16.2.0",
        "react-amap": "^1.2.0",
        "react-dom": "^16.2.0",
        "react-intl": "^2.4.0",
        "react-redux": "^5.0.7",
        "react-router": "^3.2.0",
        "react-scripts": "1.1.1",
        "recharts": "^1.0.0-beta.10",
        "redux": "^3.7.2"
      },
      "scripts": {
        "start": "react-app-rewired start",
        "build": "react-app-rewired build",
        "test": "react-app-rewired test --env=jsdom",
        "eject": "react-scripts eject",
        "electron-start": "electron .",
        "electron-package": "electron-packager . app --darwin --out presenterTool --arch=x64 --overwrite --ignore=node_modulesls --electron-version=1.8.2"
      },
      "devDependencies": {
        "babel-plugin-import": "^1.6.5",
        "electron": "^1.8.2",
        "electron-packager": "^11.0.1",
        "react-app-rewire-less": "^2.1.0",
        "react-app-rewired": "^1.4.1"
      }
    }
    
    • mian.js
    const {app, BrowserWindow} = require('electron')
    const path = require('path')
    const url = require('url')
    const pkg = require('./package.json')
    
    // 保持一个对于 window 对象的全局引用,如果你不这样做,
    // 当 JavaScript 对象被垃圾回收, window 会被自动地关闭
    let win
    
    function createWindow () {
      // 创建浏览器窗口。
      win = new BrowserWindow({width: 800, height: 600})
    
      // 然后加载应用的 index.html。
      // package中的DEV为true时,开启调试窗口。为false时使用编译发布版本
      if(pkg.DEV){
        win.loadURL('http://localhost:3000/')
      }else{
        win.loadURL(url.format({
          pathname: path.join(__dirname, './build/index.html'),
          protocol: 'file:',
          slashes: true
        }))
      }
    
      // 打开开发者工具。
      // win.webContents.openDevTools()
    
      // 当 window 被关闭,这个事件会被触发。
      win.on('closed', () => {
        // 取消引用 window 对象,如果你的应用支持多窗口的话,
        // 通常会把多个 window 对象存放在一个数组里面,
        // 与此同时,你应该删除相应的元素。
        win = null
      })
    }
    
    // Electron 会在初始化后并准备
    // 创建浏览器窗口时,调用这个函数。
    // 部分 API 在 ready 事件触发后才能使用。
    app.on('ready', createWindow)
    
    // 当全部窗口关闭时退出。
    app.on('window-all-closed', () => {
      // 在 macOS 上,除非用户用 Cmd + Q 确定地退出,
      // 否则绝大部分应用及其菜单栏会保持激活。
      if (process.platform !== 'darwin') {
        app.quit()
      }
    })
    
    app.on('activate', () => {
      // 在macOS上,当单击dock图标并且没有其他窗口打开时,
      // 通常在应用程序中重新创建一个窗口。
      if (win === null) {
        createWindow()
      }
    })
    
    // 在这文件,你可以续写应用剩下主进程代码。
    // 也可以拆分成几个文件,然后用 require 导入。
    
    // 文件模块
    // const BTFile = require('./sys_modules/BTFile')
    
    // BTFile.getAppPath()
    

    Create-react-app与Electron中线程间的通信

    之前,将create-react-appelectron集成在了一个项目中。但是在React中无法使用electron

    当在React中使用require('electron')时就会报TypeError: fs.existsSync is not a function的错误。因为React中无法使用Node.js的模块.

    解决方案如下

    创建renderer.js文件

    在项目public/目录下新建renderer.js文件,该文件是预加载的js文件,并且在该文件内可以使用所有的Node.js的API。在renderer.js中添加

    global.electron = require('electron')
    

    修改main.js文件

    修改创建浏览器的入口代码,添加preload配置项。将renderer.js作为预加载文件

    win = new BrowserWindow({
        width: 800, 
        height: 600,
        autoHideMenuBar: true,
        fullscreenable: false,
        webPreferences: {
            javascript: true,
            plugins: true,
            nodeIntegration: false, // 不集成 Nodejs
            webSecurity: false,
            preload: path.join(__dirname, './public/renderer.js') // 但预加载的 js 文件内仍可以使用 Nodejs 的 API
        }
      })
    

    修改piblic/index.html文件

    <div id="root"></div>前引入renderer.js文件

    <script>require('./renderer.js')</script>
    <div id="root"></div>
    

    在React组件中如下使用electron

    const electron = window.electron;
    

    参考资料

    相关文章

      网友评论

        本文标题:React+Electron+antd+Less集成环境配置

        本文链接:https://www.haomeiwen.com/subject/nwgztftx.html