Blog

Blog

PHODAL

Atom Electron + React 桌面应用开发

想了想还是写点东西分享一下,Electron应用开发的一点过程吧,虽然已经是有些时候不会仔细地写每一个步骤。

没有试过的小伙伴可以按之前的《Electron 初体验》来试试。

遗憾的是这个项目没有能完成,被Electron Shell对SerialPort支持不好的缘故,或者是说新的Node.js对SerailPort支持不好给block了。

iot editor

功能需求

一开始是想做一个物联网相关的编辑器,支持MQTT、CoAP、HTTP协议的测试等等,当然它也应该有一个串口通信的功能。

  1. 想着有一个Fancy的UI,便想到了Material Design。

  2. 想着应该有一个新的View层,就想到了React

所以总的框架就是: React + Material UI + Electron,所以也就有了那么Web的桌面应用。谁也说不准这会不会是以后的趋势。

Quick Start

往我们的package.json里面添加下面的内容:

"dependencies": {
    "electron-debug": "^0.1.1",
    "material-ui": "^0.10.2",
    "mqtt": "^1.1.5",
    "react": "^0.13.3",
    "react-bootstrap": "^0.22.3",
    "react-router": "^0.13.3",
}

然后就是

npm install

接着就是添加browserify到gruntfile里了,用于生成app.js:

browserify: {
  options: {
    debug: true,
    transform: ['babelify']
  },
  app: {
    src: 'components/app.jsx',
    dest: 'app/app.js'
  }
},

当然你还需要有更多的配置,参见: Gruntfile.js

剩下的就是一些常用的React的内容了。如我们的app.jsx中的Router:

    import React from 'react';
    import Router from 'react-router';
    import { RouteHandler, Route, Navigation } from 'react-router';
    import { Nav, Navbar } from 'react-bootstrap';
    import { NavItemLink } from 'react-router-bootstrap';
    import { HomePage, NodeMCUPage, DebugPage } from './pages';
    import Menu from 'material-ui/lib/menus/menu';
    import MenuItem from 'material-ui/lib/menus/menu-item';
    var Link = Router.Link;
    let { Mixins, Styles } = require('material-ui');
    let { Spacing, Colors } = Styles;
    let { StyleResizable, StylePropable } = Mixins;
    let FileFolder = require('material-ui/lib/svg-icons/file/folder');
    let mui = require('material-ui');
    let {
        AppCanvas,
        FontIcon,
        FlatButton,
        Avatar,
        SvgIcon
        }
        = mui;
    var ThemeManager = require('material-ui/lib/styles/theme-manager')();
    ThemeManager.setTheme(ThemeManager.types.LIGHT);
    var remote = window.require('remote');
    var runtime = remote.require('./core/runtime');

    var _routes = runtime.routes.map(function (r) {
        var handler = window.require(r.handler);
        return <Route key={r.route} name={r.route} handler={handler}/>;
    });
    const App = React.createClass({
        mixins: [Navigation, StyleResizable, StylePropable],
        childContextTypes: {
            muiTheme: React.PropTypes.object
        },
        getChildContext() {
            return {
                muiTheme: ThemeManager.getCurrentTheme()
            };
        },
        propTypes: {
            menuItems: React.PropTypes.array
        },
        contextTypes: {
            router: React.PropTypes.func
        },
        componentDidMount() {
            var ipc = window.require('ipc');
            ipc.on('transitionTo', function (routeName) {
                //this.transitionTo(routeName, { the: 'params' }, { the: 'query' });
                this.transitionTo(routeName);
            }.bind(this));
        },
        render() {
            let styles = this.getStyles();

            return (
                <AppCanvas>
                        <RouteHandler />
                </AppCanvas>
            );
        },
    });
    var routes = (
        <Route name="app" path="/" handler={App}>
            <Route name="home" path="/" handler={HomePage}/>
            <Route name="debug" handler={DebugPage}/>
            <Route name="nodemcu" handler={NodeMCUPage}/>
            { _routes }
        </Route>
    );
    Router.run(routes, function (Handler) {
        React.render(<Handler />, document.body);
    });

完整的代码见: app.jsx

(ps:上面的代码让我又想到了是时候更新highlight.js了),让我们好好看上面的router,上面多数的代码在当前的context中不是那么重要。

关于我

Github: @phodal     微博:@phodal     知乎:@phodal    

微信公众号(Phodal)

围观我的Github Idea墙, 也许,你会遇到心仪的项目

QQ技术交流群: 321689806
comment

Feeds

RSS / Atom

最近文章

关于作者

Phodal Huang

Engineer, Consultant, Writer, Designer

ThoughtWorks 技术专家

工程师 / 咨询师 / 作家 / 设计学徒

开源深度爱好者

出版有《前端架构:从入门到微前端》、《自己动手设计物联网》、《全栈应用开发:精益实践》

联系我: h@phodal.com

微信公众号: 最新技术分享

标签