如何将你的 ThinkJS 项目部署到 ZEIT 上
ZEIT(https://zeit.co) 是免费的云平台,支持部署静态网站以及 Serverless 函数。Serverless 是近几年比较火的概念,简单去理解就是你只需要去实现具体的业务逻辑,而与最终服务相关的服务器、HTTP 服务等则由第三方管理。Serverless 又被称为 FaaS(函数即服务),由于业务粒度非常细,所以非常方便做动态扩容等自动化运维任务。
//一个最简单的基于 Node.js 的 Serverless 函数
module.exports = function(req, res) {
const { name = 'World' } = req.query
res.send(`Hello ${name}!`)
}
通过 ZEIT 提供的 CLI 工具 now,我们可以一条命令将 Node.js, Golang, Python, Ruby, PHP, Rust 等语言的应用部署到 ZEIT 上。如果你想了解更多关于 ZEIT 这个公司的知识也可以看这篇知乎回答(https://www.zhihu.com/question/59278159/answer/163585410)了解更多。
注册非常方便,打开 https://zeit.co 点击右上角的 "Join Free",使用 Github 或者 Gitlab 账号登录后会自动注册。当然你也可以使用邮箱注册,会发送一封确认邮件到你的邮箱。登录后会让你填写昵称、头像和唯一 ID等配置。
选择 Continue 之后如果是通过邮箱登录进来的会问你是否需要绑定 Github 账号,可以让 Github 与 ZEIT 之间的持续集成更加方便,当然你也可以选择 SKIP 跳过。最后一步则会指导你如何创建项目,它提供了很多快速创建的模板,例如 Next.js, React, Vuepress, Gatsby, Docz, Nuxt.js, Svelte, Angular。
按照示例使用npm install -g now安装 CLI 工具,初始化项目后直接使用 now 命令即可发布到 ZEIT 上,整体流程非常简单。
通过刚才的示例我们可以了解到其实它的本质就是将 HTTP 请求的 request和response传入方法中,处理后再返回给 HTTP,所以它除了 Serverless 函数之外也是完全支持 Koa.js 以及基于 Koa.js 的 ThinkJS 服务部署的。我们先来看看如果要部署一个 Koa.js 服务应该怎么做。
Fork 快速部署
由于 ZEIT 官方主推 Serverless 服务,所以把 Node.js 的脚手架模板去除掉了,所以我们只能自己创建项目了,为了方便我提供了一个 DEMO 仓库 https://github.com/lizheming/now-koa-demo。如果在刚才的注册流程中你绑定了 Github 的账号的话你可以选择直接 Fork 该仓库,等一小会儿之后就会收到 ZEIT 的 Github 通知告诉你网站已经部署成功,并在 commit 中提供部署后的地址。
命令行部署
如果没有绑定 Github 账户也没关系,我们可以通过命令行部署服务。将 DEMO 仓库克隆下来后直接使用 now命令就可以了。部署成功后 ZEIT 会给我们返回一个当前提交版本的唯一地址,比如说 https://now-koa-demo-pac7dbxrf.now.sh/ 打开之后就会见到 Hello from koa.js!的返回信息。
注意事项
我们再来看看 now.json 的内容。该 JSON 文件用于告诉 now 服务 index.js 文件需要使用 @now/node 运行时执行,而所有的请求需要转发到 index.js 文件上。听起来是不是非常像 Nginx 上的内容?
{
"version": 2,
"builds": [
{ "src": "index.js", "use": "@now/node" }
],
"routes": [
{ "src": "/(.*)", "dest": "/index.js" }
]
}
成功部署 Koa.js 服务之后,下面我们就来看看怎么给你的 ThinkJS 服务找一个免费空间部署上去吧!为了方便我也提供了一个 DEMO 仓库 https://github.com/lizheming/now-thinkjs-demo,Fork 该仓库可快速体验 Now 部署 ThinkJS 服务。Fork 成功后过一会就会收到部署成功后的提示,同时告知你部署后的唯一地址,例如
然而这只是我折腾成功后的结果,基于 ThinkJS 的服务直接部署并没有部署 Koa.js 服务那么简单,这主要是由 ThinkJS 框架本身的特性决定的。下面我将其中需要注意的点一一道来,方便其它已有服务的迁移。我们先来看看针对 ZEIT 平台的 ThinkJS 启动文件有哪些内容。然后我们基于该文件主要讲述下碰到的问题以及为什么需要这么做。
const path = require('path');
const Application = require('thinkjs');
const Loader = require('thinkjs/lib/loader');
class NowLoader extends Loader {
writeConfig() {}
}
const app = new Application({
ROOT_PATH: __dirname,
APP_PATH: path.join(__dirname, 'src'),
VIEW_PATH: path.join(__dirname, 'view'),
proxy: true, // use proxy
env: 'now',
external: {
log4js: {
stdout: path.join(__dirname, 'node_modules/log4js/lib/appenders/stdout.js'),
console: path.join(__dirname, 'node_modules/log4js/lib/appenders/console.js')
},
static: {
www: path.join(__dirname, 'www')
}
}
});
const loader = new NowLoader(app.options);
loader.loadAll('worker');
module.exports = function (req, res) {
return think.beforeStartServer().catch(err => {
think.logger.error(err);
}).then(() => {
const callback = think.app.callback();
return callback(req, res);
}).then(() => {
think.app.emit('appReady');
});
};
服务启动问题
初始化 Loader 实例,在对应的进程上加载需要的文件,包括 config, middleware, controller, logic, model, service 等。 执行beforeStartServer()启动前钩子 启动服务 启动后向全局发送 appReady 事件
实例化 Loader,使用loader.loadAll('worker')加载所有的依赖文件 在回调中执行beforeStartServer() 启动前钩子 执行 callback()启动服务 启动后向全局发送 appReady 事件
文件引用问题
项目文件相对引用
去年2月份就有用户针对这个问题提了 Commit 将所有的加载器显式依赖后再进行选择解决了这个问题。所以在新版log4js 的中已经不存在这个问题了,不过我还是在这里说明一下,是因为可能项目中引用的其它依赖会有这个问题,还是需要注意一下的。
写入权限问题
当然这是 ThinkJS 本身的文件写入操作,如果说你的项目中还有其它文件写入操作的话,也需要做对应的操作。例如 logger 日志的配置可以输出到控制台,文件上传等必须写入文件的则可以写到系统临时目录/tmp中。不同的系统临时目录可能不太一样,Node.js 中建议通过 require('os').tmpdir() 来获取。
通过 ZEIT 平台,极大的降低了部署 Node.js 服务的成本,不仅是机器成本,维护成本也极大的降低了。其实正常的 Node.js 项目部署起来还是非常方便的,主要还是 ThinkJS 的依赖引用并非显式的,导致了在打包上的一些困难,其它的都还是很方便的。如果有什么其它的问题,也欢迎大家多多交流。
参考资料
如何透過 ZEIT 方便快捷地部署免費的 Node.js 項目?
关注我们
界世的你当不
只做你的肩膀
无
360官方技术公众号
技术干货|一手资讯|精彩活动
空·
- 如何部署vuejs项目到Tomcat上
- 如何线上部署node.js项目
- Docker: 如何将node.js的项目部署到docker的swarm上面去
- 【阿里云】node.js部署项目到阿里云ECS(CentOS 7),并实现nginx域名绑定
- 如何将多个java项目同时部署在一个云端tomcat上,并开机自启动
- 如何使用百度bae部署web项目
- 如何自动化一键部署PHP项目
- 如何将javaweb项目部署到linux下
- Maven项目部署到服务器如何设置访问路径-配置虚拟目录
- 如何Vue-cli开始使用在Vue.js项目中启动TDD(测试驱动开发)
- JspStudy套件在部署java项目时,如何去掉项目名进行访问网址问题
- 用Node.js创建一个静态服务器,然后将一个项目部署在这个服务器中
- 网上商城项目,前后端分离,springboot+vue.js,有线上部署教程
- 云平台编程与开发(四):如何将已有的java Web项目部署到云平台?
- 关于在reactjs项目中如何用webpack配置组件按需加载
- 如何在tomcat上部署项目
- myesclipse的项目如何部署到esclipse上,亲测可用
- Android项目学习笔记之如何将应用部署到真机上
- 如何将Java web项目部署到服务器
- 如何在一个域名下部署多个rails项目之一