# @adonisjs/attachment-lite 中文文档

规范地址：https://npmcn.com/package/%40adonisjs/attachment-lite/

版本：1\.0\.8
npm 元数据更新时间：2023-09-22T07:01:32.470Z
中文译文更新时间：2026-11-06T22:09:18.950Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40adonisjs/attachment-lite
原文对照：https://npmcn.com/package/%40adonisjs/attachment-lite/?lang=original
项目主页：https://github.com/adonisjs/attachment-lite#readme
源码仓库：https://github.com/adonisjs/attachment-lite

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：38.7 kB，15 个文件
- 模块格式：CommonJS
- TypeScript 类型：包内自带
- 运行依赖：1 个
- peer 依赖：@adonisjs/core ^5\.3\.0，@adonisjs/lucid ^17\.0\.0 \|\| ^18\.0\.0
- 首次发布：2021-10-01T05:52:15.377Z
- 最新版本发布：2023-09-22T07:01:32.281Z
- 近 30 天下载量：2279（2026-10-05 至 2026-11-03，npm 官方下载统计）
- 已发布版本数：9（近 12 个月 0 个）

## 中文简介

将您 Lucid 模型上的任何字段转换为附件数据类型

## 安装

```sh
npm install @adonisjs/attachment-lite
```

也可以使用：`pnpm add @adonisjs/attachment-lite`、`yarn add @adonisjs/attachment-lite`、`bun add @adonisjs/attachment-lite`

## README

# 附件字节

![](https://npmcn.com/package/%40adonisjs/attachment-lite/assets/banner.jpeg)

* * *

[![github-actions-image](https://img.shields.io/github/workflow/status/adonisjs/attachment-lite/test?style=for-the-badge)](https://github.com/adonisjs/attachment-lite/actions/workflows/test.yml "github-actions") [![npm-image](https://img.shields.io/npm/v/@adonisjs/attachment-lite.svg?style=for-the-badge&logo=npm)](https://npmjs.org/package/@adonisjs/attachment-lite "npm") [![license-image](https://img.shields.io/npm/l/@adonisjs/attachment-lite?color=blueviolet&style=for-the-badge)](https://npmcn.com/package/%40adonisjs/attachment-lite/LICENSE.md "license") [![typescript-image](https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript)](https://npmcn.com/package/%40adonisjs/attachment-lite/%22typescript%22)

一个简单,有意见的软件包,可以将您 Lucid 模型上的任何一栏转换为附件数据类型.

附件列表允许您在数据库中存储用户上传文件的引用 。 它不需要任何额外的数据库表格,并将文件元数据作为JSON存储在同一列.

## 怎么样?

这个 `attachment-lite` 软件包是 **媒体图书馆办法的替代办法**我相信媒体库在创建CMS时是很棒的.

然而,许多应用如SAAS产品或社区论坛不需要媒体图书馆.

例如,Twitter或dev.to等网站没有媒体库部分,用于上传和选择图片. 相反,这些平台上的图像与资源紧密结合.

当你在Twitter上更新你的配置图像时,旧的图像会消失,而新的图像会出现. 没有图像的中央画廊可以选择配置图片.

一个很长的故事告诉你 `attachment-lite` 软件包是管理应用程序中一次性文件上传的绝佳解决方案.

## 特征

-   将数据库中的任何一栏转换为附件数据类型.
-   不需要额外的数据库表格。 文件元数据作为JSON存储在同一列内.
-   当指定新文件时,将自动从磁盘上删除旧文件.
-   优雅地处理失败案件。 如果模型无法持续, 将不存储文件 .
-   同样,如果模型在更新过程中无法持续或删除失败,则不会删除旧文件.

## 先决条件

这个 `attachment-lite` 需要软件包 `@adonisjs/lucid >= v16.3.1` 财务报告和审定财务报表 `@adonisjs/core >= 5.3.4`。 。 。 .

而且,它依赖于 [AdonisJS 驱动器](https://docs.adonisjs.com/guides/drive) 用于在磁盘上写入文件.

## 设置

从 npm 登记册中安装软件包如下 .

```sh
npm i @adonisjs/attachment-lite
```

接下来,通过运行以下 A 命令来配置软件包.

```sh
node ace configure @adonisjs/attachment-lite
```

## 使用量

图像元数据大小往往会超过允许的 SQL 长度 `String` 数据类型。 因此,建议创建/修改将保留元数据的列,以便使用 `JSON` 数据类型.

如果您是第一次创建列, 请务必使用 JSON 数据类型 。 示例

```ts
  // Within the migration file

  protected tableName = 'users'
  
  public async up() {
    this.schema.createTable(this.tableName, (table) => {
      table.increments()
      table.json('avatar') // <-- Use a JSON data type
    })
  }
```

如果您已经拥有存储图像路径/ URL 的列, 您需要创建新的迁移并更改列定义为 JSON 数据类型 。 示例

```bash
# Create a new migration file
node ace make:migration change_avatar_column_to_json --table=users
```

```ts
  // Within the migration file
  
  protected tableName = 'users'

  public async up() {
    this.schema.alterTable(this.tableName, (table) => {
      table.json('avatar').alter() // <-- Alter the column definition
    })
  }
```

接下来,在模型中导入 `attachment` 装饰者和 `AttachmentContract` 界面.

> 确定不要使用 `@column` 使用时的装饰符 `@attachment` 装饰师.

```ts
import { BaseModel } from '@ioc:Adonis/Lucid/Orm'
import {
  attachment,
  AttachmentContract
} from '@ioc:Adonis/Addons/AttachmentLite'

class User extends BaseModel {
  @attachment()
  public avatar: AttachmentContract
}
```

现在可以从用户上传文件创建附件如下 .

```ts
import { Attachment } from '@ioc:Adonis/Addons/AttachmentLite'

class UsersController {
  public store({ request }: HttpContextContract) {
    const avatar = request.file('avatar')!
    const user = new User()

    user.avatar = Attachment.fromFile(avatar)
    await user.save()
  }
}
```

这个 `Attachment.fromFile` 从用户上传文件创建附件类实例 。 当将模型坚持到数据库时,附件-lite会将文件写入磁盘.

### 处理更新

您可以用新上传的用户文件来更新属性, 包将注意去掉旧文件并存储新文件.

```ts
import { Attachment } from '@ioc:Adonis/Addons/AttachmentLite'

class UsersController {
  public update({ request }: HttpContextContract) {
    const user = await User.firstOrFail()
    const avatar = request.file('avatar')!

    user.avatar = Attachment.fromFile(avatar)

    // Old file will be removed from the disk as well.
    await user.save()
  }
}
```

同样,指定 `null` 要删除文件,而不指定新文件的模型属性值.

另外,确保您更新模型上的属性类型 `null` 还有.

```ts
class User extends BaseModel {
  @attachment()
  public avatar: AttachmentContract | null
}
```

```ts
const user = await User.first()
user.avatar = null

// Removes the file from the disk
await user.save()
```

### 处理删除

在删除模型实例后,所有相关附件都会从磁盘中被移除.

> 注意: 要删除文件, 需要使用附件列表 `modelInstance.delete` 方法。 使用 `delete` 。查询构建器将无法工作.

```ts
const user = await User.first()

// Removes any attachments related to this user
await user.delete()
```

## 指定磁盘

默认情况下,所有文件都会从默认磁盘中写入/删除. 然而,您可以在使用自定义磁盘时指定 `attachment` 装饰师.

> 这个 `disk` 属性价值从未持续到数据库。 这意味着,如果你首先定义磁盘为 `s3`,上传一些文件,然后将磁盘值更改为 `gcs`,软件包将使用 `gcs` 磁盘.

```ts
class User extends BaseModel {
  @attachment({ disk: 's3' })
  public avatar: AttachmentContract
}
```

## 指定子文件夹

您也可以通过定义 `folder` 财产如下.

```ts
class User extends BaseModel {
  @attachment({ folder: 'avatars' })
  public avatar: AttachmentContract
}
```

## 正在生成 URL

您可以使用该附件生成给定附件的 URL `getUrl` 或者说 `getSignedUrl` 方法。 。 。 它们与 [驱动方法](https://docs.adonisjs.com/guides/drive#generating-urls),只是不需要指定文件名.

```ts
await user.avatar.getSignedUrl({ expiresIn: '30mins' })
```

## 生成 API 响应的 URL

Drive API生成URL的方法是同步的,而将一个模型序列化到JSON则是同步的. 因此,不是在序列化一个模型时创建URL.

```ts
// ❌ Does not work

const users = await User.all()
users.map((user) => {
  user.avatar.url = await user.avatar.getSignedUrl()
  return user
})
```

要处理此使用大小写, 您可以选择预计算 URL

### 预计算 URL

启用 `preComputeUrl` 在 SELECT 查询后预先计算 URL的旗帜。 例如:

```ts
class User extends BaseModel {
  @attachment({ preComputeUrl: true })
  public avatar: AttachmentContract
}
```

获取结果

```ts
const users = await User.all()
users[0].avatar.url // pre computed already 
```

查找结果

```ts
const user = await User.findOrFail(1)
user.avatar.url // pre computed already 
```

接地结果

```ts
const users = await User.query.paginate(1)
users[0].avatar.url // pre computed already 
```

这个 `preComputeUrl` 属性将生成 URL并设置在附件类实例上。 另外,当磁盘是 **私营**,当磁盘是 **公开**。 。 。 .

### 按要求预先计算

我们建议不要允许 `preComputeUrl` 选项,当您只需要一个或两个查询而不能在应用程序的其余部分使用URL时.

对于这些查询,您可以手动计算控制器内的URL. 这里有一个小的帮助方法,你可以直接在模型上放入.

```ts
class User extends BaseModel {
  public static async preComputeUrls(models: User | User[]) {
    if (Array.isArray(models)) {
      await Promise.all(models.map((model) => this.preComputeUrls(model)))
      return
    }

    await models.avatar?.computeUrl()
    await models.coverImage?.computeUrl()
  }
}
```

现用如下.

```
const users = await User.all()
await User.preComputeUrls(users)

return users
```

或者一个用户

```ts
const user = await User.findOrFail(1)
await User.preComputeUrls(user)

return user
```

## 与模范工厂使用附件升

附件 lite 首选使用多部分请求机构来坚持用户上传文件. 然而,你也可以构建一个实例: `Attachment` 手动分类并使用 AdonisJS 驱动器来粘住相应的文件.

在下面的例子中,我们创建了一个附件类的例子来代表邮报封面图像.

```ts
import Post from 'App/Models/Post'
import Drive from '@ioc:Adonis/Core/Drive'
import { file } from '@ioc:Adonis/Core/Helpers'
import Factory from '@ioc:Adonis/Lucid/Factory'
import { Attachment } from '@ioc:Adonis/Addons/AttachmentLite'

export default Factory.define(Post, async ({ faker }) => {
  /**
   * Step 1: Create an instance of attachment
   */
  const coverImage = new Attachment({
    extname: 'png',
    mimeType: 'image/png',
    size: 10 * 1000,
    name: `${faker.random.alphaNumeric(10)}.png`,
  })

  /**
   * Step 2: Mark image as persisted, this will disable the
   * functions of attachment lite that looks for multipart
   * body and attempts to write the file from the stream
   */
  coverImage.isPersisted = true

  /**
   * Step 3: Persist the file using Drive.
   */
  await Drive.put(coverImage.name, (await file.generatePng('1mb')).contents)

  return {
    title: faker.lorem.words(5),
    coverImage: coverImage,
  }
}).build()
```

## 常见问题

### @adonisjs/attachment-lite 是什么？

将您 Lucid 模型上的任何字段转换为附件数据类型

### 如何安装 @adonisjs/attachment-lite？

在项目目录运行 npm install @adonisjs/attachment-lite，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：@adonisjs/core（^5\.3\.0）、@adonisjs/lucid（^17\.0\.0 \|\| ^18\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @adonisjs/attachment-lite 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @adonisjs/attachment-lite 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @adonisjs/attachment-lite 可以商用吗？

@adonisjs/attachment-lite 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @adonisjs/attachment-lite 的下载量有多少？

根据 npm 官方下载统计，@adonisjs/attachment-lite 在 2026/10/05 – 2026/11/03 这 30 天内被下载 2,279 次，日均约 76 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @adonisjs/attachment-lite 还在维护吗？

最新版本 1\.0\.8 发布于 2023/09/22（3 年前）；至今共发布 9 个版本，其中过去 12 个月发布了 0 个；首次发布于 2021/10/01。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

