React 产品实现 -任务管理工具“氢”

clipboard.png

原文地址:https://zhuanlan.zhihu.com/p/...,欢迎转载 :-)

? 关于

其实对于这个专栏的订阅用户感到非常抱歉,已经停更很久了,也没啥特别的理由就是懒 orz!不对,画风不能这样开头,是这样的,我觉得我应该用 React 去做点儿什么,写文章能够清晰我的思路,让我和别人有交流,但是并没有实际做产品那么性感,于是我决定要用 React 来做一些产品出来,于是就有了 “氢” http://origingroup.tech 相信我在这里对氢的介绍以及实现技术介绍也能对大家有帮助。

所以这篇文章我主要想介绍一些做这个东西的思路、想法和一些技术实现以及用到的一些工具。

? “氢” 是什么鬼

这个名字听着就很奇怪,为什么是个 H 元素作为名字,对,是这样的,先不管氢是什么东西,我的想法是我要用 React 去做一些产品出来那总得取个名字吧,“一些产品” 意味着我得费好多经历去想产品名称,好了,不如就按照元素周期表的顺序取名字吧,于是“氢”这个名字就这样定了。 :- ) (我都觉得我是天才了,hhhhhh ☞ )

好了,说正经的,其实做氢这个东西早有预谋,很久很久以前我做了一些产品,然后夭折了,eee...... 于是现在我决定把它们捡起来(感觉哪里不对。。)!

其中的一个夭折的是 “一个针对个人的项目管理工具”,本想提供 saas 的服务,结果被我改来改去最后tm很长时间没空理它不玩了,于是最终被改到现在的 “针对个人的笔记,任务,待办离线管理工具” ,于是就有了这个叫氢的家伙(当然之前给它取的名字不叫这个。。)

? 那氢提供的核心功能有哪些呢?

  • 提供 workflowy 功能的强大列表,能够将日常的琐碎的事情,用极致简单的交互去做增删改查

  • 核心目标基于任务管理来打造,所以参考了很多任务管理工具的 UX 以及自己的想法-结合 scrum 模型,让它在任务管理上也能简单极致(最开始核心目标太多,导致产品几乎难产,其实最后的氢是一个删减吧,这也让我懂得了做产品需要克制)

  • 最后我需要有一个 powerful 的编辑器,因为平时记录事情的时候总的写点儿什么呀,于是任务详情被打造成了一个 wysiwyg 编辑器,并且支持用 markdown 语法,可以直接粘贴 markdown 生成样式,后面还会提供导出 markdown 功能

  • 当然得漂亮

好了,说了辣么多,先上几个图,毕竟有句名言叫-meitushuogejb

第一张图就是我说的 列表 ,具体怎么好用可能还得自己体验过才知道,所见即所得,回车就创建一个任务,tab 一下任务就变为子任务,ctrl + command + up/down

clipboard.png

clipboard.png

clipboard.png

clipboard.png

⚒ 说一说技术实现

如你所见,上面的这个东西是一个 Desktop app ,具体实现方式是:

Electron + React

最开始的时候只是针对 web 版本的,所以技术全是围绕 React 来,后来决定该为 Desktop app ,当然第一选择是 electron,过程中也是遇到了不少坑的地方,下面分几个方便来分享一下

  1. React 技术栈的选择

  2. 项目结构与 Webpack 打包编译

  3. Electron 相关的使用细节

  4. 如何用 Electron 做 i18n
    React 技术栈选择

基本的技术使用和我在本专栏中提到的无差,具体为:

  • ES6 + JSX + Less :作为基本的语言层选择,这套路基本还是很常用的了

  • Ant.design: 使用 ant.design 作为基础库,这里感谢玉伯大大团队的贡献

  • Redux + Redux-Saga:现在熟悉了 redux 和 redux-saga 过后很难再改为其他的方式,因为感觉这种配套已经很极致了,在处理数据流转已经 UI 交互的时候,redux-saga 几乎是个 magic 的工具

  • draft.js + draft-plugin-js: 在编辑器的选择上使用了 Facebook 的 draft.js , 如果你愿意详细了解其设计和架构的话也会觉得这也是个伟大的项目,同时通过 draft-plugin-js 可以很快的将编辑器功能组件化,很容易通过 hook 定制自己的编辑器,氢中的编辑器有两个,第一个是列表项每个都是一个编辑器实例,任务详情,定制化的一个富文本编辑器

  • Immutable.js: 不可变数据,这对于列表来说真是太重要了,React 如果不进行优化的在特殊情况下会有严重的性能问题,氢种的列表就是这种特殊情况,一编辑某一个任务,处理不好会卡,会抖动。因此我在做列表的时候就决定由 immutable 重构了整个项目,同时列表的数据结构也是做了特殊的设计和优化的。(比如一个小问题,上下移动,如何确定顺序呢?)

  • React-intl:氢做了基本的国际化,也就支持英文,当然现在应该有很多语法错误还没检查,使用的是 React-intl。

  • React-vitualized:这个项目也是为了做性能优化用的,不过现在的版本因为优化了数据结构不需要了

项目结构与 Webpack 打包编译

项目的目录结构设计和 webpack 打包编译才是头痛的问题,当 webpack 遇上 electron,各种环境不一致导致的奇怪 bug 我是不会跟别人说的,☝️个人默默的承受。。。

先上个项目结构的图

clipboard.png

好长的目录,其中关键的地方是 containers 的设计,项目中 containers 目前的设计是一个 cotainer 包含

  • reducer.js

  • sagas.js

  • index.jsx

  • styles.less

  • components

当然图中的项目结构中有专门的 reducers 目录和 sagas 目录,这是因为之前的设计没改,后面的 reducer ,style,sagas 都是组件自包含的。

说说 webpack 的打包

感谢这个项目帮我解决了不少坑 chentsulin/electron-react-boilerplate 正常情况下的 Electron ,React 项目基本就按照这个 boilerplate 来就行了,不过我自己在打包上做了很多自定义的修改,所以才会出现很多 webpack 的问题。

其中的一个优化点是,不使用 dll ,无论 production 还是 dev 都会使用 vendors.js ,而这个 vendors 是预先打包压缩好了的,所以每次打包实际都是只打包了业务代码。具体方式是看图就知道了

通过定义 externals 让打包过程忽略这些模块的打包,使用 external 方式引用

clipboard.png

专门打包 vendor 的webpack 配置,一定要注意 libraryTarget

clipboard.png

Electron 相关的使用细节

这里不想列举太多细节,说说其中的一个,初始化 loading 加载,因为 electron 每次打开都几乎是打开一个浏览器,在执行大的js 上也会花很多时间,所以会出现1s到2s的停顿,显得应用很卡。

氢中解决这个问题的方式使用一个专门负责 loading 的 window ,这个页面极其简单,很快就可以加载出来了,然后这个时候打开主要的 window,当这个window 加载完了再显示出来,再关闭负责 loading 的 window, 下面我直接贴出 main.js 的代码,有需要的可以拿走

app.on('ready', createWindow);function createWindow () {locale = app.getLocale();landingWindow = new BrowserWindow({show: false,frame: false,width: 490,height: 400})landingWindow.once("show", () => {// Create the browser window.mainWindow = new BrowserWindow({width: 1000, height: 740,titleBarStyle: 'hidden',icon: `file://${__dirname}/assets/imgs/logo.png`,show: false})mainWindow.once("show", () => {landingWindow.hide()landingWindow.close()landingWindow.removeAllListeners();mainWindow.show()landingWindow = null})mainWindow.webContents.on('did-finish-load', () => {if (!mainWindow) {throw new Error('"mainWindow" is not defined');}mainWindow.show();mainWindow.focus();});// Emitted when the window is closed.mainWindow.on('closed', function () {// Dereference the window object, usually you would store windows// in an array if your app supports multi windows, this is the time// when you should delete the corresponding element.mainWindow.removeAllListeners();mainWindow = null;})// and load the index.html of the app.mainWindow.loadURL(`file://${__dirname}/app.html`);const menuBuilder = new MenuBuilder(mainWindow);menuBuilder.buildMenu(locale);})landingWindow.loadURL(`file://${__dirname}/landing.html`)landingWindow.once('ready-to-show', () => {landingWindow.show()})
}

如何用 Electron 做 i18n

在做国际化版本的时候有两种情况

main.js 主进程的国际化
window 内 renderer 进程的国际化
在 main.js 可以通过

locale = app.getLocale();
来获取当前系统的语言,不过需要注意的是,获取的地方一定要在 app.on('ready') 的注册函数中获取,不然默认会一直取到 “en-US”

在 window 中, 这就真的是前端的天下了

locale = navigator.language
和在 chrome 中无差,可以如上获取语言,然后再通过设置到 react-intl 的 provider 中,接下来就是琐碎的翻译工作了。。。

最后

氢还是花了我不少时间的,目前没打算 open source, 积累到了一定程度应该会开源,最后说一说做这个东西的收获:

  • 设计和 UX 是很重要的

  • 克制,在做产品上,在设计上一定要克制

  • linux 哲学,让产品只完成一个功能,不要想太多,想太多了什么都做不成

  • 哪怕还是个浑身 bug 的东西,也要尽快的推出来,不然你都找不到理由继续做下去

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/456210.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【R】语言第一课-----安装

安装R和Rstuido软件 R语言是用于统计分析,图形表示和报告的编程语言和软件环境;Rstudio是编辑、运行R语言的最为理想的工具之一。 1、官网下载R安装包 下载地址为:https://cran.r-project.org 进入链接,如下图所示&#xff0c…

谁说菜鸟不会数据分析--读书笔记

如果看不清可以下载下来,打开,放大。仅供参考。 转载于:https://www.cnblogs.com/sunshinewang/p/6591772.html

Thinkphp5 还有这种操作?

2019独角兽企业重金招聘Python工程师标准>>> 在 _initialize 中取出 控制器名和方法名 define(CONTROLLER_NAME,Request::instance()->controller()); define(MODULE_NAME,Request::instance()->module()); define(ACTION_NAME,Request::instance()->actio…

【R】语言第五课----画图

?plot#高级绘图函数 可以完整地绘制出一张图 ?mtcars plot(mtcars$wt) plot(mtcars[,1:2]) plot(mtcars) plot(mtcars$wt,mtcars$disp) plot(mtcars$wt,mtcars$disp,typep) plot(mtcars$wt,mtcars$disp,typel) plot(mtcars$wt,mtcars$disp,typeb) plot(mtcars$wt,mtcars$disp…

Solidworks如何将参考平面的图形投影到某曲面上

1 画好草图,点击曲线-分割线 2 选择要投影的草图和被投影的面(那个球面),最后效果如下图所示 3 为了获取连续的轨迹,我们可以再次选择这个草图,然后在投影面中选择平面,最后得到的图形如下图所示…

Series和DataFrame、相关性及NaN处理

pandas核心数据结构 pandas是以numpy为基础的,还提供了一些额外的方法 Series series用来表示一维数据结构,与python内部的数组类似,但多了一些额外的功能。 series内部由两个相互关联的数组组成:主数组用来存放数组&#xff…

pandas读写各种类型数据

read_X()通常是pandas模块下的,to_X()是dataframe的方法 CSV 读取 使用pandas.read_csv()方法,返回的是一个dataframe csv默认是以","分割的 csv文件内容 1、read_csv()默认以第一行数据作为标题 2、调用dataframe的head()方法…

python 类装饰器

1 装饰器无参数 class tracer: def __init__(self,func): self.calls 0 self.func func def __call__(self,*args): self.calls 1 print(call %s to %s %(self.calls, self.func.__name__)) self.func(*args) tracer def spam(a, b, c): print(a b c) …

【数据分析】使用pandas和numpy分析美国大选献金项目

1. 数据载入与总览 1.1 数据加载 #绘图工具 import matplotlib.pyplot as plt %matplotlib inline #数据处理工具 import numpy as np import pandas as pd from pandas import Series,DataFrame#数据路径自己指定,本案例数据路径就在当前文件夹下面子文件夹usa_e…

《容器技术系列》一1.4 Docker运行案例分析

本节书摘来华章计算机《容器技术系列》一书中的第1章 ,第1.4节,孙宏亮 著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。 1.4 Docker运行案例分析 1.3节着重介绍了Docker架构中各个模块的功能,学完后我们可以对Docker的架构有一…

3月22日AM

看了思维章节精讲视频课,并且总结了部分思维章节内容转载于:https://www.cnblogs.com/bgd140206102/p/6601440.html

阿里巴巴Dubbo实现的源码分析

Dubbo概述Dubbo是阿里巴巴开源出来的一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及作为SOA服务治理的方案。它的核心功能包括: remoting:远程通讯基础,提供对多种NIO框架抽象封装,包括“同步…

H264 CAVLC 研究

目录 1 CAVLC概念 2 CAVLC原理 3 CAVLC编码流程 4 CAVLC解码流程 展开全部 1 CAVLC概念 2 CAVLC原理 3 CAVLC编码流程 4 CAVLC解码流程 收起 摘要纠错编辑摘要 CAVLC即基于上下文的自适应变长编码。H.264标准中使用CAVLC对4*4模块的亮度和色度残差数据进行编码。 CAVLC-CAVLC…

instanceof 的运用

2019独角兽企业重金招聘Python工程师标准>>> Java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。 用法: result object i…

R 脚本读取汇总 Excel 表格数据

主要用到了 xlsx 和 rJava 包,打开 Excel 文件,读取各表格数据,再写入到汇总表。 下图为处理前的原始数据表格: 下图为处理后的数据: 代码实现 安装&加载包的函数实现。installed.packages() 函数获取所有已安装…

【大数据】最新大数据学习路线(完整详细版,含整套教程)

大数据学习路线 java(Java se,javaweb) Linux(shell,高并发架构,lucene,solr) Hadoop(Hadoop,HDFS,Mapreduce,yarn,hive,hbase,sqoop,zookeeper,flume) 机器学习(R,mahout) Storm(Storm,kafka,redis) Spark(scala,spark,spark core,spark sql,spark streaming,spark mllib,spa…

谷歌浏览器开发调试工具中Sources面板 js调试等 完全介绍

这次分享的是Chrome开发工具中最有用的面板Sources。 Sources面板几乎是我最常用到的Chrome功能面板,也是在我看来决解一般问题的主要功能面板。通常只要是开发遇到了js报错或者其他代码问题,在审视一遍自己的代码而一无所获之后,我首先就会打…

【Python】最新Python学习路线(完整详细版,含整套教程)

python目前应用最广的三个岗位:全栈开发、数据分析、运维开发,今天我们就以这三个重点的岗位来做一下自学Python的规划,希望你在学之前就能有明确的学习方向。 最近开始整理python的资料,博主建立了一个qq群,希望给大家…

程序员,软件测试知多少?

送给初级程序员的测试认知文作为开发同学,一些基本的测试岗位相关知识还是很有必要了解一下,免的某些同学在工作中和测试同学斗嘴、打架、群殴等以及被测试鄙视....。 我们常常听说的一些测试专业术语,比如白盒、黑盒、单元测试,相…

vue 入门环境搭建

公司项目要用vue.js来开发,要使用vue来开发前端框架,首先要有环境,所以给大家介绍一下如何搭建vue环境。其实很简单: 1.首先下载安装node.js。 去官网https://nodejs.org/zh-cn/下载安装包。 2.安装webpack 打开cmd命令界面&#…