# 插件介绍与意义

URL: https://caijiao.org/fastify/plugins/introduction
Source: docs/fastify/plugins/introduction.md
Description: 探索 Fastify 插件系统的设计理念、使用方式及其在项目模块化中的重要意义。

Fastify 的插件系统是其核心设计理念之一，支持高度模块化、可复用和可组合的服务开发方式。

## 什么是插件？

在 [Fastify](/fastify/) 中，插件本质上是一个封装了功能的函数，它接受 `fastify` 实例作为参数，并可以注册路由、装饰器、钩子等功能：

```js
async function myPlugin(fastify, options) {
  fastify.get('/ping', async () => 'pong');
}

module.exports = myPlugin;
```

注册插件：

```js
const fastify = require('fastify')();

fastify.register(require('./my-plugin'));
```

## 插件的作用

- **逻辑拆分**：将不同功能划分为多个模块，增强可维护性。
- **功能复用**：公共功能如认证、数据库连接、日志系统等可在多个项目间共享。
- **隔离作用域**：插件内部注册的路由、装饰器默认不会污染全局实例。
- **插件链式组合**：可通过注册顺序灵活组合多个插件。

## 插件注册参数

注册插件时可以传递配置选项：

```js
fastify.register(require('./auth-plugin'), { secret: 'abc123' });
```

插件内部可通过 `options` 参数接收配置。

## 可选择作用域封闭

通过 `{ encapsulate: true/false }` 控制作用域：

- 默认封装作用域，插件中的内容不会暴露给其他插件。
- 使用 `fastify-plugin` 可以显式定义为全局插件。

## 使用 fastify-plugin

使用 [`fastify-plugin`](https://github.com/fastify/fastify-plugin) 可以：

- 控制插件的封装行为
- 定义依赖关系
- 确保插件只注册一次

示例：

```js
const fp = require('fastify-plugin');

async function dbConnector(fastify, opts) {
  fastify.decorate('db', { query: () => 'mock result' });
}

module.exports = fp(dbConnector);
```

## 示例：数据库插件

```js
async function dbPlugin(fastify, options) {
  const db = await connectToDatabase();
  fastify.decorate('db', db);
}

fastify.register(dbPlugin);
```

在其他路由中使用：

```js
fastify.get('/users', async (request, reply) => {
  const users = await fastify.db.query('SELECT * FROM users');
  return users;
});
```

## 插件体系下的开发模式

- 项目可按功能模块（如用户、文章、支付）组织为多个插件
- 插件可以包含路由、schema、服务逻辑、钩子
- 利于团队协作和大规模系统开发

```plaintext
src/
├── plugins/
│   ├── auth.js
│   └── db.js
├── routes/
│   ├── user.js
│   └── article.js
```

每个模块都是插件，只需通过 `register` 注册即可。

```js
fastify.register(require('./plugins/db'));
fastify.register(require('./routes/user'));
```
