手上没活不太行,所以我想整个活。
整个小网站吧,要有路由,要有域名,要有接口,要有数据库。还要 不花钱
。
我看中了 vercel
天下没有免费的午餐,vercel 有,不花钱的 Hobby Plan
足够整活用了,但是不要效仿"Java之父"把自己的站点交给网友压测。
Feature | Hobby | Pro |
---|---|---|
Projects | 200 | Unlimited |
Bandwidth | 100 GB | 1 TB |
Edge Functions execution units | 500,000 | 1 million |
Edge Middleware invocations | 1 million | 2 million |
Serverless Function maximum duration | 10 seconds | 15s (default) - configurable up to 300s |
Serverless Function execution | 100 GB-hours | 1,000 GB-hours |
Build execution minutes | 6,000 | 24,000 |
Image Optimization source images | 1,000 | 5,000 |
Team collaboration features | - | Yes |
Remote Cache artifact downloads | 10 GB | 20 GB |
Domains per project | 50 | Unlimited |
Deployments per day | 100 | 6,000 |
Analytics | - | Limited |
Email support | - | Yes |
它提供了 templates
各种用途
、风格
、框架
的项目模板都有
点进去可以预览 demo,也可以一键部署
支持多种 Git Provider
后面就是傻瓜式操作,选个 Provider,选个账号,选个项目名,Create
就完了,你会得到一个代码仓库和 vercel 白给的域名,点进去就可以预览你的网站了。
它支持了 serverless function
vercel 支持用 Node.js, Go, Python, Ruby
写 serverless function,具体请参考文档。
同时还提供了一些模板
它集成了 storage
在这里选个喜欢的,连接到项目就行了,文档在这里 👉🏻 vercel.com/docs/storag...
它连接了 GitHub
在 dashboard 里 create new project,会被引导创建项目,可以轻松地连接到 GitHub 项目并部署
它还整了 持续集成
当你 project settings 中监听的分支有变更时,vercel 会自动构建,这里可以查看构建历史
我遇到了 坑
看了文档和模板示例,我说快整吧,我感觉我现在强得不行。然而,事情并不顺利,最简单的起步,让我踩了仿佛两年半的坑。
线上非默认路由刷新 404 了
我用的 React 的 BrowserRouter,想必开发过 spa 的鸽鸽们都遇到过,本地没问题,到线上刷新非默认路由 404.
这种情况如果没有 nginx 反向代理之类的配置,通常访问默认路由没问题,跳转非默认路由也没问题,但是当在非默认路由页面刷新时就会 404,是因为请求不到资源,spa 中就一个 html,没其他页面,请求不到也正常。
我们要想办法把这个请求定向到 index.html,这就妥了。
Stack Overflow 和 vercel 文档上都有方法,不赘述了,直接贴解决办法
在项目根目录中创建 vercel.json
,甚至可以在这个配置文件里设置反向代理。然后部署项目就好了
json
{
"rewrites": [
{
"source": "/(.*)",
"destination": "/index.html"
}
]
}
本地调接口进到路由里了
到这里先说怎么加接口,整个最简单的 Hello World
接口,参考 👉🏻 Quickstart 和 example 原来加个接口这么简单。
加了接口之后,为什么线上能访问,本地接口一访问就进路由了呢?
原来不能用 pnpm dev
启动服务,需要用 vercel dev
,它才会把 serverless function 跑起来,同时还要改造下 vercel.json
,用负向前行断言或叫否定前瞻断言 告诉 vercel 把别的路由定向到 /index.html
得了,api
开头的是接口,不要这么处理。
json
{
"rewrites": [
{
"source": "/((?!api\/.*).*)",
"destination": "/index.html"
}
]
}
这么一来在本地也把 api
开头的请求当做接口处理了。
调接口 FUNCTION_INVOCATION_FAILED 了
但是,为啥一调用接口就报错了呢?
查了一大圈,Stack Overflow、GitHub issues、discussions、vercel 文档都看遍了,配置也是一顿改,没用。然后问了 GPT
,它最没用,说你看日志去吧,问题是根本没日志。
然后我想,既然本地和线上环境是有差异的,保不齐线上能行呢?发了下线上,调接口,还不行。但是,不同的是线上有日志,在这个地方
没想到从最没用的回答中找到了最朴素的解决方法。按照日志提示,在 package.json
中设置 type: module
解决问题。
调接口返回内容异常了
此时应该没有什么幺蛾子了,继续调试,发现线上好的,本地访问接口也能访问,但是返回的响应有点不对劲。
仔细一看,没有返回 Hello World
,而是把 api/hello.ts
中的 file content 返回出来了,这也没用啊,肯定是配置问题。
配置改来改去,用过 rewrites
, redirects
, functions
等等都没用。
又找来找去,找到个方法,说在 vercel.json
中用 routes
字段替换 rewrites
字段,虽说文档不建议使用这个字段,但是没办法,试试吧
json
{
"routes": [
{
"src": "/((?!api\/.*).*)",
"dest": "/index.html"
}
]
}
结果改成这样还真行,欢欢喜喜部署到线上。
本地好了,线上不行了
又出问题了,本地行了,线上不行了,访问页面加载不出来了,一看是加载 js
资源文件出问题了,响应头 Content-Type
变成 text/html
了,怪不得不行了,记得文档上有在 vercel.json
中设置 headers
的选项。
针对 dist/assets/**/*.js
资源设置了正确的响应头,线上倒是能访问页面了,但是样式没了,项目中用了 unocss
。这怎么行?
我们已经知道用 vercel
运行项目时需要 vercel.json
配置文件,能不能像加载 .env
文件似的在不同环境加载不同的配置?查了下没有这种写法,但是从 vercel help dev
命令中找到了希望。
bash
➜ ~ vercel help dev
Vercel CLI 33.4.1
▲ vercel dev [dir] [options]
Starts the `vercel dev` server.
Options:
--listen <uri> Specify a URI endpoint on which to listen [0.0.0.0:3000]
Global Options:
--cwd <DIR> Sets the current working directory for a
single run of a command
-d, --debug Debug mode (default off)
-Q, --global-config <DIR> Path to the global `.vercel` directory
-h, --help Output usage information
-A, --local-config <FILE> Path to the local `vercel.json` file
--no-color No color mode (default off)
-S, --scope Set a custom scope
-t, --token <TOKEN> Login token
-v, --version Output the version number
Examples:
- Start the `vercel dev` server on port 8080
$ vercel dev --listen 8080
- Make the `vercel dev` server bind to localhost on port 5000
$ vercel dev --listen 127.0.0.1:5000
可以看到我们能使用 -A
参数指定配置文件,默认是 vercel.json
,那好,我在项目根目录准备了两个文件:
vercel.json
json
{
"rewrites": [
{
"source": "/((?!api\/.*).*)",
"destination": "/index.html"
}
]
}
vercel.local.json
json
{
"routes": [
{
"src": "/((?!api\/.*).*)",
"dest": "/index.html"
}
]
}
在本地启动时用命令 vercel -A vercel.local.json dev
,本地没问题了。
部署到线上,测试也没问题。
问题解决了
到现在问题是解决了,我明白,虽然这么整有点丑,但是我还没找到更体面的方法,先这么地吧。
希望能帮大家在整活路上踩坑时间少一点,有经验一起分享。