空手套白狼-個人互聯網草根創業親身經歷

和大多數人同樣,我出生寒門學子,沒錢沒勢,全部的一切都是從零開始,只能空手套白狼,本文章主要是爲了分享下我我的的創業經歷以及一個產品從無到有的過程,後面也會聊到我作H5工具的相關技術方案,但願能幫助讀者在將來的工做或者是創業路上有所幫助。

2010年第一次創業

務實的人都不甘於平庸,我亦如此,也許越是有挑戰的東西,我越是感興趣,創業的想法就像一顆毒瘤一直在我腦中去不掉,大學第一天上學,我把全部的生活費在阿里巴巴上進了一堆跳舞毯,開始了人生的第一次創業,我記得那是2010年上大一的事情了,雖然沒有賺回本錢,可是我意外的認識了生產跳舞毯的老闆。在學校裏賣不完跳舞毯,因而我開了個淘寶店鋪在網上賣,雖然網上也沒賣完,卻陰差陽錯的成爲了跳舞毯公司的網店兼職設計師(精通美圖秀秀),再後面就自學了PS,成爲了一個UI設計師,我大學學的是java,由於學習了PS,也就瓜熟蒂落的成了前端工程師。也爲接下來的創業奠基了技術的基礎。javascript

2012年第一個工做室

大學2年期間,個人前端技術逐漸成熟了,能夠作一些官網站了,因而我打算在樂山本地找一家網絡公司作兼職,很快我成功的拿到了他們的網站訂單,創意的設計風格加上物美價廉,很快成爲了這家公司穩定的合做方,因而我在學校裏面創立了本身的工做室(饅頭工做室)。個人頭像也是M這個LOGO也一直沿用至今。css

image

2014年人生第一家公司

14年,咱們都被大學老師趕出去找工做,剛剛出來的我找了一家公司,可是很快就按耐不住想要創業的想法,因而彙集了幾個同窗,咱們一塊兒創辦了一家公司,受到了「雲來場景應用」的啓發,當時咱們就在想,要是能批量生產H5就行了,咱們提出了「即見即所得」的概念,很快在14年發佈了第一款產品"酷APP",我這裏還保留了幾張珍貴的截圖:html

image
image

可是當時缺少商業經驗以及面臨公司生存的問題,沒有拿到融資的咱們很快就堅持不下去了,而後項目以失敗了結!團隊也各奔東西。前端

小知識:什麼是H5?微信掃描如下二維碼便可查看H5

image

H5DS v1.x 版本

雖然第一款自主研發的產品失敗了,可是我依然以爲這個產品是個好東西,因而賊心不死的我在15年團隊解散後發佈了另一個編輯器產品(H5DS)也就是如今的1.x版本。界面是參考PhotoShop來作的,是否是感受很像PS?vue

image

H5DS v2.x 版本

有了1.x版本,那就有2.x是吧?期間我去了一家創業公司,在那家公司我用下班的業餘時間,在H5DS的基礎上又重構了一個版本,2.x的編輯器。界面清爽了不少,並且功能也更多了。java

image

H5DS v3.x 版本

16年的時候,大多數創業公司都輸給了資本,我所在的創業公司也沒法避免,隨着上家創業公司的倒閉,我沒有立刻找工做,回到家裏,我繼續搗鼓個人編輯器,因而很快發佈了3.x版本。界面從白變黑,整個代碼也重寫了。能夠說3.x版本徹底是重構的。mysql

image

H5DS v4.x 版本

到如今3年了,由於兼職的緣由,因此進度很慢,後來在一次技術分享會上面,我認識了個人技術合夥人,基於3.x版本,咱們一塊兒發佈了4.0版本,3.0版本是jquery的版本,那麼4.x就是react的版本。react

image

H5DS v5.x 版本

4.x版本的生命週期是很短的,在屢次討論後,咱們在4.x之上,咱們很快就發佈了5.x版本。5.x版本在界面上沒有作任何改動,可是代碼徹底重構了,5.x也就是如今的版本。今後選擇了擁抱react生態,海量react組件庫在H5DS中均可以使用。jquery

image

產品版本總結

任何產品都非一來就完美的,若是是那樣,我也不用重構那麼多版本了,慢慢改進打磨迭代升級,產品就會愈來愈完善,愈來愈強大。能夠看到產品的進步,也能夠看到咱們想法的轉變,任何一次升級都是爲了更好的迎合市場的需求,若是但願本身的產品能走的更遠,那就不要停下來!創業也是同樣,並不是一開始就什麼都會,什麼都有,也是慢慢積累起來的經驗和知識,而後學以至用。感受有點像玩遊戲打怪升級,一開始在新手村混,而後到普通玩家區,再到高玩(高端玩家)區,一開始就到高玩區,確定死翹翹了!es6

H5DS產品概述

H5DS(HTML5 design software)h5ds.com 是一款真正意義上的HTML5頁面製做工具,很是可貴是這個項目我作了5年,版本也換了好幾個,依舊初心不改!將來還有不少個五年,我也但願本身的工具會越作越好,下面就來聊聊這個花了我無數心血作的產品。

準確的產品定位

相似的競品也比較多。好比易企秀,maka,兔展,人人秀,wps秀堂,凡科H5等。咱們的產品究竟有何不一樣?

普通用戶而言:H5是手機上用於營銷的滑動頁面。

專業技術人員:H5是HTML5的簡稱,是一門技術方案,滑動頁面只是H5的一小塊應用領域。

很明顯,其餘競品的定位是作營銷滑動頁面,而咱們的定位是HTML5的編輯器。能夠作滑動頁面,網站,3D虛擬現實,數據報表,PC網站,小程序,在線PS,在線動畫製做等應用。

從一個技術到產品再到銷售

任何成熟穩定的產品都不是一朝一夕就能完成的,從1.x到5.x,我從一個技術慢慢也有了產品的思惟,這個項目讓我學到了太多的東西,我以爲是任何公司都給不了一個技術的東西,作了這個項目,讓我有了和可客戶坐在咖啡廳脣槍舌戰的經歷,同時我也有了產品經理的經驗,我規劃的功能也曾遭受用戶的質疑,甚至有用戶專門發了一個word文檔給我,裏面羅列了40多個編輯器改進意見,作一個產品是一件很是有意義的事情,我也兼職了UI的工做,玩起了PS,如何設計交互讓用戶感受更友好,讓我掉了很多頭髮!這個項目讓我體驗了設計師,技術,產品,銷售,至少哪天不寫代碼了,還能夠去跑下業務!

創業九十九死一輩子

一路走來,我感受本身創業以來什麼都缺,缺人才,缺資金,缺資源,的確,創業是很是艱難的,若是說九死一輩子是其餘行業的創業,那IT行業真的是99死一輩子。14年在風口的創業公司有多少能活到如今?14年咱們創業的時候也是衝着融資去的,可是如今不是了,我以爲首先要活下去,而後再想如何發展壯大,如何賺錢。我所知道的不少IT公司都須要靠融資才能夠活下去,一旦資金鍊斷裂了,公司立馬倒閉,H5DS在發佈4.x版本的時候就已經能作到自負盈虧了,因此目前咱們不須要融資,不用考慮生存的問題,雖然節奏慢了點,可是不至於倒閉作不下去了,先解決溫飽,才能夠創造價值。我但願咱們的產品能走的很遠,只要活着,就有但願!雖然看上去比較悲觀,可是創業真的很是殘酷!我很是慶幸本身沒有放棄,一直堅持作本身的產品,算下來,今年是5年了,正好是v5版本。產品也比較接近個人預期。

將來會走的更遠

很是慶幸,咱們在第一個5年活下來了,將來咱們會站在巨人的肩膀上,走的更遠!至於將來五年的規劃,雖然我已經作好了,可是市場永遠是變化不可測的,咱們也會不斷的更新產品,推出新鮮的功能,只但願能在這條道路上走的更遠!

技術乾貨分享

聊了太多和技術不掛邊的東西,差點忘記本身是一個技術了,接下來會聊一些技術相關的東西,也算是分享一些乾貨給給位技術同僚!就編輯器技術部分,這裏給你們作個分享。

技術選型

技術選型咱們採用react + mobx + koa2 + mysql 總體都是JS技術棧,至於爲何要這樣選型,由於咱們人少,技術保持統一,方便維護!另一方面緣由是由於咱們是一個創業團隊,技術資源很是寶貴,必須儘量的節約開發成本,也是爲何咱們會選擇純JS的技術棧,這樣咱們每一個人均可以作前端也能夠作後端。

mobx 最最核心的概念只有2個。 @observable 和 @observer ,它們分別對應的是被觀察者和觀察者。這是你們常見的觀察者模式,這裏使用了ES7 中的 裝飾器。參數發生變化時自動觸發render更新視圖,這個和vue是同樣的原理。

之因此沒有使用vue是由於咱們也須要react的state配合起來作性能優化以及靈活的數據處理。咱們能夠結合防抖函數去作性能優化,控制或者選擇性的去更新視圖。下面舉個例子:

import React, { Component } from 'react';
import { inject, observer } from 'mobx-react';
import debounce from 'lodash/debounce';

@inject('h5ds')
@observer
class Demo extends Component {
  constructor(props) {
    super(props);
    this.state = {
        count: props.h5ds.count  // 默認是1
    }
  }
  
  // 防抖函數控制性能
  updateOtherRender = debounce(() => {
      const { count } = this.state;
      // 若是大於10纔會去更新其餘地方的視圖
      if(count > 10) {
        this.props.h5ds.count = this.state.count
      }
  }, 500)
  
  changeValue = e => {
      this.setState({count: e.target.value}, this.updateOtherRender)
  }
  
  render() {
      return <input type="number" value={this.state.count} onChange={this.changeValue}/>
  }
}

咱們在不少地方都有用到上面這種寫法,react提倡的最小模塊化,咱們也但願模塊之間的影響會最小,若是一個參數在多個模塊中被使用,在快速輸入的時候務必會變的很慢。

總體架構

咱們把項目總體劃分紅了多個子項目api,editor(編輯器),web(前端管理),admin(後端管理),app-preview(H5預覽),plugins(H5插件部分)。既要拆分,又要作到很小的耦合性是很是困難的,因此咱們作了最大可能性的解耦,架構圖以下。

image

若是想下降耦合度,web,app-preview,plugins都可獨立打包,獨立部署!若是考慮到部署的便利性,能夠打包後合併代碼進行部署。
  1. 插件說明

咱們把H5裏面的元素統必定義爲插件,好比圖片,文字,音頻,形狀等元素,這些插件都有一些共同的屬性,如寬高,位置,動畫效果,交互事件等,因此咱們把非共性抽離出來作成插件,並且插件能夠獨立開發和維護,完整的插件包括了渲染引擎和數據編輯器,渲染引擎在預覽頁面和可視化編輯的時候使用,編輯器部分在編輯器中選中對應的圖層後使用。

  1. 預覽頁面說明

預覽是獨立的頁面,由於咱們要確保這個頁面能夠移植,區別於編輯器頁面,渲染原理:編輯器輸出是一個json數據,這個數據包含了H5頁面的全部配置信息,好比每一個插件的大小位置,頁面的顏色高度背景等。在獨立的預覽頁面裏面只須要解析這個json數據,而後根據json數據渲染頁面便可,這裏就須要h5ds的頁面渲染引擎進行解析渲染。

  1. 編輯器內核說明

咱們把editor作成了一個React組件包。能夠像下面這樣使用:

a. 引入必須的資源包。

<link rel="stylesheet" href="//at.alicdn.com/t/font_1160472_ybl2xl0ao8.css">
<link rel="stylesheet" href="//at.alicdn.com/t/font_157397_ze6q8vjbeme.css">
<link href="//cdn.bootcss.com/Swiper/4.5.0/css/swiper.min.css" rel="stylesheet">
<link href="//cdn.bootcss.com/antd/3.23.0-beta.0/antd.min.css" rel="stylesheet">
<script src="//cdn.h5ds.com/lib/plugins/swiper.min.js"></script>
<script src="//cdn.h5ds.com/lib/plugins/jquery.min.js"></script>
<script src="//cdn.h5ds.com/lib/plugins/h5ds-vendor-0.0.1.min.js"></script>
<script src="//cdn.bootcss.com/pubsub-js/1.7.0/pubsub.min.js"></script>
<script src="//cdn.bootcss.com/moment.js/2.24.0/moment.min.js"></script>
<script src="//cdn.bootcss.com/antd/3.23.0-beta.0/antd.min.js"></script>

b. 安裝使用H5DS

npm install h5ds --save
import 'h5ds/editor/style.css';

import React, { Component } from 'react';
import H5dsEditor from 'h5ds/editor';

class Editor extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: null
    };
  }

  /**
   * 保存APP
   */
  saveApp = async data => {
    console.log('saveApp ->', data);
  };
  
  /**
   * 發佈 app
   */
  publishApp = async data => {
    console.log('publishApp ->', data);
  };

  componentDidMount() {
    // 模擬異步加載數,設置 defaultData 會默認加載一個初始化數據
    setTimeout(() => {
      this.setState({ data: 'defaultData' });
    }, 100);
  }

  /**
   * 使用編輯器部分
   */
  render() {
    const { data } = this.state;
    return (
      <H5dsEditor
        plugins={['demo']} // 第三方插件包
        data={data}
        debugger={false} // debugger=true用於調試插件
        options={{ 
          publishApp: this.publishApp,
          saveApp: this.saveApp, // 保存應用
          appId: 'test_app_id' // 當前appId
        }}
      />
    );
  }
}
export default Editor;

從插件加載到插件掛載

最初咱們的插件都是打成umd包,而後使用requirejs加載,可是requirejs會判斷是否瀏覽器已經實現了require和define方法。若是瀏覽器已經自帶require和define方法,或者以前已經有一個requirejs腳本執行,那麼這個requirejs就會馬上中止執行,可能和有些包衝突起來!而後咱們決定取消AMD的加載模式,採用掛載的方式,把插件模塊掛載到一個全局變量下面!同時也兼容UMD模式!去掉了requirejs採用掛載的模式代碼更少,更快,更靈活!

加入咱們

QQ羣:549856478

image

官方網站:www.h5ds.com

相關文章
相關標籤/搜索