应用

本指南涵盖 AdonisJS 中的 Application 类。你将学习如何:

  • 访问运行时环境(web、console、repl、test)
  • 检查 Node.js 环境与应用状态
  • 监听进程信号并通知父进程
  • 生成指向项目目录与文件的绝对路径
  • 使用生成器以获得一致的命名约定

概述

Application 类负责将 AdonisJS 应用组装在一起的重活。它管理应用生命周期、提供对环境信息的访问、跟踪当前状态,并提供用于生成各种项目目录路径的辅助方法。

你可以通过 app 服务访问 Application 实例,该服务在你的应用中随处可用。

另请参阅: 应用生命周期

app/services/some_service.ts
import app from '@adonisjs/core/services/app'

环境

环境指的是你的应用运行所在的运行时上下文。AdonisJS 识别四种不同的环境:

环境描述
web为 HTTP 服务器启动的进程
consoleAce 命令(REPL 命令除外)
repl使用 node ace repl 启动的进程
test使用 node ace test 启动的进程

你可以使用 getEnvironment 方法访问当前环境。

app/services/some_service.ts
import app from '@adonisjs/core/services/app'

console.log(app.getEnvironment())

切换环境

你可以在应用启动之前切换应用环境。当一个命令需要以不同于其启动时的上下文运行时,这会很有用。例如,node ace repl 命令以 console 环境启动,但在显示提示符之前会切换到 repl

commands/my_command.ts
import app from '@adonisjs/core/services/app'

if (!app.isBooted) {
  app.setEnvironment('repl')
}

Node 环境

nodeEnvironment 属性提供对 Node.js 环境的访问,该环境派生自 NODE_ENV 环境变量。AdonisJS 会对常见变体进行规范化,以确保跨不同部署配置的一致性。

app/services/some_service.ts
import app from '@adonisjs/core/services/app'

console.log(app.nodeEnvironment)
NODE_ENV规范化后为
devdevelopment
developdevelopment
stagestaging
prodproduction
testingtest

简写属性

你无需比较字符串,可以使用这些布尔属性来检查当前环境。

app/services/some_service.ts
import app from '@adonisjs/core/services/app'

/**
 * Check if running in production
 */
app.inProduction
app.nodeEnvironment === 'production'

/**
 * Check if running in development
 */
app.inDev
app.nodeEnvironment === 'development'

/**
 * Check if running tests
 */
app.inTest
app.nodeEnvironment === 'test'

状态

状态表示应用在其生命周期中所处的位置。你可访问的功能取决于当前状态——例如,在应用达到 booted 状态之前,你无法访问 容器绑定容器服务

状态描述
createdApplication 实例创建时的默认状态
initiated环境变量已解析且 adonisrc.ts 已处理
booted服务提供者已注册并启动
ready应用已准备好处理请求(含义因环境而异)
terminated应用已终止,进程即将退出
app/services/some_service.ts
import app from '@adonisjs/core/services/app'

console.log(app.getState())

简写属性

app/services/some_service.ts
import app from '@adonisjs/core/services/app'

/**
 * True when state is past 'initiated'
 */
app.isBooted

/**
 * True when state is 'ready'
 */
app.isReady

/**
 * True when gracefully attempting to terminate
 */
app.isTerminating

/**
 * True when state is 'terminated'
 */
app.isTerminated

监听进程信号

你可以使用 app.listenapp.listenOnce 方法监听 POSIX 信号 。这些方法会向 Node.js 的 process 对象注册监听器。

start/events.ts
import app from '@adonisjs/core/services/app'

app.listen('SIGTERM', () => {
  // Handle SIGTERM
})

app.listenOnce('SIGTERM', () => {
  // Handle SIGTERM once
})

条件监听器

使用 listenIflistenOnceIf 仅在满足条件时注册监听器。仅当第一个参数为真时,监听器才会被注册。

start/events.ts
import app from '@adonisjs/core/services/app'

/**
 * Only listen for SIGINT when running under pm2
 */
app.listenIf(app.managedByPm2, 'SIGINT', () => {
  // Handle SIGINT in pm2
})

app.listenOnceIf(app.managedByPm2, 'SIGINT', () => {
  // Handle SIGINT once in pm2
})

通知父进程

当你的应用作为子进程运行时,你可以使用 app.notify 方法向父进程发送消息。它封装了 process.send 方法。

start/events.ts
import app from '@adonisjs/core/services/app'

app.notify('ready')

app.notify({
  isReady: true,
  port: 3333,
  host: 'localhost'
})

生成项目文件的路径

Application 类提供了辅助方法,用于生成指向项目内文件与目录的绝对路径。这些辅助方法会尊重你在 adonisrc.ts 文件中配置的目录结构,即使你自定义了目录位置,路径也能保持正确。

makePath

返回指向项目根目录下某个文件或目录的绝对路径。

app/services/some_service.ts
import app from '@adonisjs/core/services/app'

app.makePath('app/middleware/auth.ts')
// /project_root/app/middleware/auth.ts

makeURL

返回指向项目根目录下某个文件或目录的文件 URL。这在动态导入文件时很有用。

app/services/test_runner.ts
import app from '@adonisjs/core/services/app'

const files = [
  './tests/welcome.spec.ts',
  './tests/maths.spec.ts'
]

await Promise.all(files.map((file) => {
  return import(app.makeURL(file).href)
}))

tmpPath

返回指向项目根目录下 tmp 目录内某个文件的路径。

app/services/some_service.ts
app.tmpPath('logs/mail.txt')
// /project_root/tmp/logs/mail.txt

app.tmpPath()
// /project_root/tmp

configPath

app/services/some_service.ts
app.configPath('shield.ts')
// /project_root/config/shield.ts

app.configPath()
// /project_root/config

publicPath

app/services/some_service.ts
app.publicPath('style.css')
// /project_root/public/style.css

app.publicPath()
// /project_root/public

viewsPath

app/services/some_service.ts
app.viewsPath('welcome.edge')
// /project_root/resources/views/welcome.edge

app.viewsPath()
// /project_root/resources/views

languageFilesPath

app/services/some_service.ts
app.languageFilesPath('en/messages.json')
// /project_root/resources/lang/en/messages.json

app.languageFilesPath()
// /project_root/resources/lang

httpControllersPath

app/services/some_service.ts
app.httpControllersPath('users_controller.ts')
// /project_root/app/controllers/users_controller.ts

app.httpControllersPath()
// /project_root/app/controllers

modelsPath

app/services/some_service.ts
app.modelsPath('user.ts')
// /project_root/app/models/user.ts

app.modelsPath()
// /project_root/app/models

servicesPath

app/services/some_service.ts
app.servicesPath('user_service.ts')
// /project_root/app/services/user_service.ts

app.servicesPath()
// /project_root/app/services

middlewarePath

app/services/some_service.ts
app.middlewarePath('auth.ts')
// /project_root/app/middleware/auth.ts

app.middlewarePath()
// /project_root/app/middleware

validatorsPath

app/services/some_service.ts
app.validatorsPath('create_user.ts')
// /project_root/app/validators/create_user.ts

app.validatorsPath()
// /project_root/app/validators

policiesPath

app/services/some_service.ts
app.policiesPath('post_policy.ts')
// /project_root/app/policies/post_policy.ts

app.policiesPath()
// /project_root/app/policies

exceptionsPath

app/services/some_service.ts
app.exceptionsPath('handler.ts')
// /project_root/app/exceptions/handler.ts

app.exceptionsPath()
// /project_root/app/exceptions

transformersPath

app/services/some_service.ts
app.transformersPath('user.ts')
// /project_root/app/transformers/user.ts

app.transformersPath()
// /project_root/app/transformers

eventsPath

app/services/some_service.ts
app.eventsPath('user_created.ts')
// /project_root/app/events/user_created.ts

app.eventsPath()
// /project_root/app/events

listenersPath

app/services/some_service.ts
app.listenersPath('send_invoice.ts')
// /project_root/app/listeners/send_invoice.ts

app.listenersPath()
// /project_root/app/listeners

mailsPath

app/services/some_service.ts
app.mailsPath('verify_email.ts')
// /project_root/app/mails/verify_email.ts

app.mailsPath()
// /project_root/app/mails

migrationsPath

app/services/some_service.ts
app.migrationsPath('create_users_table.ts')
// /project_root/database/migrations/create_users_table.ts

app.migrationsPath()
// /project_root/database/migrations

seedersPath

app/services/some_service.ts
app.seedersPath('user_seeder.ts')
// /project_root/database/seeders/user_seeder.ts

app.seedersPath()
// /project_root/database/seeders

factoriesPath

app/services/some_service.ts
app.factoriesPath('user_factory.ts')
// /project_root/database/factories/user_factory.ts

app.factoriesPath()
// /project_root/database/factories

generatedServerPath

返回指向 .adonisjs/server 目录内某个文件的路径,该目录包含服务端 barrel 文件(如控制器导入)。

app/services/some_service.ts
app.generatedServerPath('controllers.ts')
// /project_root/.adonisjs/server/controllers.ts

app.generatedServerPath()
// /project_root/.adonisjs/server

generatedClientPath

返回指向 .adonisjs/client 目录内某个文件的路径,该目录包含客户端生成的文件。

app/services/some_service.ts
app.generatedClientPath('manifest.json')
// /project_root/.adonisjs/client/manifest.json

app.generatedClientPath()
// /project_root/.adonisjs/client

startPath

app/services/some_service.ts
app.startPath('routes.ts')
// /project_root/start/routes.ts

app.startPath()
// /project_root/start

providersPath

app/services/some_service.ts
app.providersPath('app_provider.ts')
// /project_root/providers/app_provider.ts

app.providersPath()
// /project_root/providers

commandsPath

app/services/some_service.ts
app.commandsPath('greet.ts')
// /project_root/commands/greet.ts

app.commandsPath()
// /project_root/commands

生成器

生成器为应用中不同的实体创建一致的类名和文件名。它们确保在以编程方式创建新文件时遵循命名约定。

commands/make_resource.ts
import app from '@adonisjs/core/services/app'

app.generators.controllerFileName('user')
// users_controller.ts

app.generators.controllerName('user')
// UsersController

查看 generators.ts 源代码 以获取可用生成器的完整列表。