环境变量
AdonisJS 不是为每个环境维护单独的配置文件,而是使用 环境变量 来获取经常在本地环境和生产环境之间变化的值。例如:数据库凭据、用于切换模板缓存的布尔标记等等。
访问环境变量#
Node.js 本地允许你使用 process.env
对象访问环境变量。例如:
process.env.NODE_ENV
process.env.HOST
process.env.PORT
但是,我们建议使用 AdonisJS Env 工具,因为它通过添加对验证的支持并提供静态类型信息来进一步改进 API 以配合使用环境变量。
import Env from '@ioc:Adonis/Core/Env'
Env.get('NODE_ENV')
// 用默认值
Env.get('HOST', '0.0.0.0')
Env.get('PORT', 3333)
为什么要验证环境变量?#
环境变量从外向内注入到你的应用程序中,你在代码库中几乎无法控制它们。
例如,你的代码库的有一部分依赖于 SESSION_DRIVER
环境变量的存在。
const driver = process.env.SESSION_DRIVER
// 虚拟代码
await Session.use(driver).read()
无法保证在运行程序时 SESSION_DRIVER
环境变量存在并且具有正确的值。因此,你必须对其进行验证,而不是在程序运行出现错误后抱怨 「undefined」 值。
const driver = process.env.SESSION_DRIVER
if (!driver) {
throw new Error('Missing env variable "SESSION_DRIVER"')
}
if (!['memory', 'file', 'redis'].includes(driver)) {
throw new Error('Invalid value for env variable "SESSION_DRIVER"')
}
现在想象一下需要在你的代码库中到处写这些条件? 显然,这不是很好的开发体验。
验证环境变量#
AdonisJS 允许你在启动应用程序的生命周期的早期可选地验证环境变量,如果任何验证失败,则拒绝启动。
你可以先在 env.ts
文件中定义验证规则。
import Env from '@ioc:Adonis/Core/Env'
export default Env.rules({
HOST: Env.schema.string({ format: 'host' }),
PORT: Env.schema.number(),
APP_KEY: Env.schema.string(),
APP_NAME: Env.schema.string(),
CACHE_VIEWS: Env.schema.boolean(),
SESSION_DRIVER: Env.schema.string(),
NODE_ENV: Env.schema.enum(['development', 'production', 'test'] as const),
})
同样,AdonisJS 将从验证规则中提取静态类型信息,并为验证的属性提供 IntelliSense。
Schema API#
以下是验证环境变量的可用方法列表。
Env.schema.string#
验证值以检查它是否存在以及它是否为有效字符串。空字符串无法通过验证,你必须使用其他可选项来允许空字符串。
{
APP_KEY: Env.schema.string()
}
// 将其标记为可选
{
APP_KEY: Env.schema.string.optional()
}
你还可以强制该值具有一种预定义格式。
// 必须是有效的主机 (url or ip)
Env.schema.string({ format: 'host' })
// 必须是有效的 URL
Env.schema.string({ format: 'url' })
// 必须是有效的邮件地址
Env.schema.string({ format: 'email' })
在验证 url
格式时,你还可以定义其他选项来强制 / 忽略 tld
和 protocol
。
Env.schema.string({ format: 'url', tld: false, protocol: false })
Env.schema.boolean#
转化该值为布尔值的有效字符串表示形式。以下值被视为有效布尔值,并将被转换为 true
或 false
。
'1', 'true'
are casted toBoolean(true)
'0', 'false'
are casted toBoolean(false)
{
CACHE_VIEWS: Env.schema.boolean()
}
// 将其标记为可选
{
CACHE_VIEWS: Env.schema.boolean.optional()
}
Env.schema.number#
转化该值为数字的有效字符串表示形式。
{
PORT: Env.schema.number()
}
// 将其标记为可选
{
PORT: Env.schema.number.optional()
}
Env.schema.enum#
转化该值为预定义值之一。
{
NODE_ENV: Env
.schema
.enum(['development', 'production'] as const)
}
// 将其标记为可选
{
NODE_ENV: Env
.schema
.enum
.optional(['development', 'production'] as const)
}
自定义函数#
对于所有其他验证用例,你可以定义自定义函数。
{
PORT: (key, value) => {
if (!value) {
throw new Error('Value for PORT is required')
}
if (isNaN(Number(value))) {
throw new Error('Value for PORT must be a valid number')
}
return Number(value)
}
}
- 确保在验证后始终返回该值。
- 返回值可以不同于初始输入值。
- 我们从返回值推断静态类型。在这种情况下,
Env.get('PORT')
是一个数字。
在开发中定义变量#
在开发过程中,你可以在项目根目录下的 .env
文件中定义环境变量,AdonisJS 会自动处理它。
// 文件名:.env
PORT=3333
HOST=0.0.0.0
NODE_ENV=development
APP_KEY=sH2k88gojcp3PdAJiGDxof54kjtTXa3g
SESSION_DRIVER=cookie
CACHE_VIEWS=false
变量替换#
除了对解析 .env
文件的标准支持外,AdonisJS 还允许变量替换。
HOST=localhost
PORT=3333
// 高亮开始
URL=$HOST:$PORT
// 高亮结束
所有 letter
、numbers
和美元 ($
) 符号后面的下划线 (_
) 都被解析为变量。如果你的变量包含任何其他字符,那么你必须将其包裹在花括号 {}
内。
REDIS-USER=foo
// 高亮开始
REDIS-URL=localhost@${REDIS-USER}
// 高亮结束
转义 $
符号#
如果变量的值包含 $
符号,则必须对其进行转义以防止变量替换。
PASSWORD=pa\$\$word
不要提交 .env
文件#
.env
文件不可移植。这意味着,你本地和生产环境上的数据库凭据将始终不同,因此将 .env
推送到版本控制是没有意义的。
你必须将 .env
文件视为本地环境的个人文件,并在生产服务器或登台服务器上创建单独的 .env
文件 (并确保其安全)。
.env
文件可以位于服务器上的任何位置。例如,你可以将其存储在 /etc/myapp/.env
中,然后按如下方式通知 AdonisJS。
ENV_PATH=/etc/myapp/.env node server.js
在测试期间定义变量#
当应用程序使用 NODE_ENV=test
环境变量启动时,AdonisJS 将查找 .env.test
文件。
.env.test
文件中定义的变量会自动与 .env
文件合并。这允许你在编写测试时使用不同的数据库或不同的会话驱动程序。
在生产环境中定义变量#
大多数现代托管服务提供商都为在其 Web 控制台中定义环境变量提供一流的支持。在部署你的 AdonisJS 应用程序之前,请确保你阅读了托管服务提供商的文档并定义了环境变量。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。