在 now.sh部署 nodejs 项目
今天在 now.sh 部署 Google Play restful API, 遇到了一些坑和新手容易错过的细节,在此做些记录。
0. now 能干啥?
now.sh 文档是全英文,阅读起来虽然障碍不大,可仍旧会错过很多细节。
比如 now 能干啥?
这是官网介绍图:
看图片演示,很当然地以为 now 可以自动判断项目类型,然后按需自动化部署。
也就是说,你可以简单地使用命令now
, 一键部署任意一个已存在的项目(当然,now 已支持的项目类型)。
实则不是。
当你有了一个完整可运行的项目,你还要做这些事情使你的项目能正确地在 now.sh 上运行:
- 根目录新建
now.json
配置文件 - 指定所使用的
now
版本 - 对不同目录指定你所使用的
build
脚本 - 如果你的项目重定向了路由,你需要重新定向以使
now
能理解 - 输入
now
开始运行
0.5 简单地对你的项目下使用now命令
你已经有了一个可运行的项目,但你现在希望它能在now.sh
上跑起来,所以你打开项目根目录,然后输入一行命令:
now
然后你会惊喜地发现部署成功,然后得到了一个可访问的地址。
可是当你在浏览器里输入网址访问时,却傻眼了。它并没有如你所愿地返回接口内容,而是显示了文件列表。
如果根目录没有 now.json 配置文件,now 会以静态方式部署项目
也就是说,你刚刚部署了一个纯静态网站,和部署到 github pages 效果一样。(即便这样,它也比部署到 github pages 方便多了,不是吗?)
如果你需要告诉 now 你要部署一个动态服务,那你需要定制你自己的配置文件了。
1. 关于 now.json 配置文件
在 github 找个了范例,大概长这样:
{
"name": "melfina",
"alias": "melfina.network",
"builds": [
{ "src": "public/**/*", "use": "@now/static" },
{ "src": "api/**/*.js", "use": "@now/node-server" }
],
"routes": [
{ "src": "/", "dest": "public/index.html" },
{ "src": "/notarize", "dest": "api/index.js" },
{ "src": "/verify", "dest": "api/index.js" }
],
"version": 2
}
配置非常简单易懂,你看完应该就理解的八九成了。
builds 对不同的文件使用不同的编译脚本
routes 重定向路由
2. 让你的项目与众(github pages 们)不同
问题来了,怎么部署一个动态后台的项目呢?
now 预设了很多主流项目的 build 脚本。
如果没有支持,你也可以自己定制。所以第一步,你要为你的项目选择合适的 build 脚本。
写完大概长这样:
{
"builds": [
{ "src": "www/", "use": "@now/static" },
{ "src": "api/**/*.js", "use": "@now/node-server" }
],
"version": 2
}
now/static 静态项目
now/node-server node 后台项目
为你的项目选择合适的 build 脚本,你会发现你的项目一下子活起来了。
3. 解决 now.sh 的路由问题
你写了下面的脚本:
app.get('/hello', (req, res) => {
res.send('Welcome!')
})
app.get('/', (req, res) => {
res.send('Hello from Express.js!')
})
运行后却发现 /
正常运行,/hello
却显示错误:
这是因为now
会优先把path
作为路径进行寻址,那我们写的路由就无法生效了。
解决方法是你把指定的路由重定向到入口文件就好了。
{
"builds": [{"src": "*.js", "use": "@now/node-server"}],
"routes": [{"src": "/.*", "dest": "index.js"}]
}
这时访问/hello
就能得到正确的结果啦。
4. now.sh 希望你摒弃框架原有的编写和部署方式
专注编写业务相关的方法,因为那是真正重要的东西。
now.sh
推荐你摒弃框架原有的编写和部署方式。相对的,它们的美丽设想是,你只需要编写你的业务代码,然后便能通过网址进行访问。
一切服务器运行相关的代码你都不必操心。
做个对比:
框架方式:
// index.js
const app = require('express')()
app.get('/hello', (req, res) => {
res.send('Welcome!')
})
app.listen()
// now.json
{
"builds": [{"src": "*.js", "use": "@now/node-server"}],
"routes": [{"src": "/.*", "dest": "index.js"}]
}
now.sh 推荐方式
// hello.js
module.exports = (req, res) => {
res.end('Hello, World');
}
// now.json
{
"builds": [{"src": "*.js", "use": "@now/node"}],
}