如何免费部署项目到 now.sh 和野狗?

2017年7月10日

这集好多视频,有一个大新闻要公布,那就是

我们现在可以免费去发布完整的 Web 应用了

意思是,react 前端,express API ,以及数据库,都可以找到免费的解决方案了。

now 部署 React 应用

使用 now 部署是有很多优势的:

  • 自带的 https ,没有 https 现在很多事都做不了,很多 API 都不让请求了
  • 真正的一键部署,不用自己管理服务器,将 severless 进行到底
  • /about 这样的路由是可以刷新的
  • 不翻墙,访问速度很棒

create-react-app 对 now.sh 的支持时好时坏,基本上就是稍微要修改点配置,我们就不自己动手做了,直接使用

clone 下来,进入目录运行 now 即可。

一些注意点:

  • 为了节省资源,应用一段时间不用就会被 frozen (冻结),但是只要我们去敲链接去访问,就会自动 unfrozen ,只不过初次访问速度会受影响

now 部署 express API

mkdir express-now
cd express-now
npm init -y
npm i --save express

创建 index.js 如下

const express = require('express')
const app = express()

app.get('/', (req, res) => {
  res.json({msg: 'hello peter'})
})

app.post('/data', (req, res) => {
  res.json({msg: 'POST data'})
})

app.listen(3008, () => {
  console.log('running on port 3008...')
})

package.json 如下,参考 https://gist.github.com/rauchg/243c5109c793bf09c052

{
  "name": "express-now",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node index"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.15.3"
  }
}

然后运行 now:

now

这样,3008 端口问题不用管,直接 curl 就成功了。

curl -X POST https://express-now-rdlckuxyvg.now.sh/data
{"msg":"POST data"}%

注意:每次部署后, url 都会生成一个新的,但是老的 url 都还是可以用的。如果最终网站要产品化,可以很容易的绑定自己的域名。

野狗

好,前端和后端都有了,那么数据库用什么?答案是用 firebase,或者用国内的 firebase 克隆:野狗。

像野狗和 firebase 这类服务,设计的一个目标就是让开发者可以不写服务器端代码。所以直接使用 react 来跟野狗通信即可。

参考:

使用野狗的好处:

下面用 create-react-app-now 配合野狗,实现一个简单的聊天效果。

App.js

import React, { Component } from 'react';
import {
  BrowserRouter as Router,
  Route,
  Switch,
} from 'react-router-dom'
import About from './About';
import './App.css';
import Wilddog from './database'


const MsgList = ({props}) => {
  console.log(Object.keys(props))
  let listString = Object.keys(props).map((item, i) => (
    <li key={item}>{props[item].content}</li>
  ))
  return (
    <ul className="msg-list">
      {listString}
    </ul>
  )
}

class App extends Component {

  state = {
    msgList: {}
  }

  msgRef = Wilddog.sync().ref().child("messages")

  componentDidMount() {
    this.msgRef.on("value", (snapshot) => {
        let msgList = snapshot.val()
        this.setState({
          msgList
        })
    })
  }

  handleSubmit = (e) => {
    e.preventDefault()
    this.msgRef.push({
      "content" : this.msgInput.value
    })
    this.msgInput.value = ''
  }
  render() {
    return (
      <div className="app">
        <MsgList props={this.state.msgList} />
        <form onSubmit={this.handleSubmit}>
          <input type="text" ref={value => this.msgInput = value} />
          <input type="submit" />
        </form>
      </div>
    );
  }
}

const BasicApp = () => (
  <Router>
    <div>
      <Switch>
        <Route exact path="/" component={App} />
        <Route path="/about" component={About} />
      </Switch>
    </div>
  </Router>
)

export default BasicApp;

database.js

import Wilddog from 'wilddog'

const config = {
  syncURL: "https://meituandemo.wilddogio.com"
}

Wilddog.initializeApp(config)

export default Wilddog

App.css

.msg-list {
  border: 2px solid gray;
  height: 200px;
  overflow: auto;
}

input {
  border: 2px solid gray;
}

其他的代码都是 create-react-app-now 自带的代码了。、

结语

后面我可能专门录一集介绍 react+now+wilddog 的详细使用。