项目
版本

Uppy 迁移指南

这些涵盖了所有主要的 Uppy 版本以及如何迁移至它们。

从 Robodog 迁移到 Uppy 插件

Uppy 通过插件实现灵活和可扩展。但集成代码有时可能令人望而生畏。这就是 Robodog 诞生的原因。它提供了相同的功能,但具有更人性化和简洁的 API。

但是,它也带来了一些新的问题:

  • 它试图做同样的事情,但它看起来像是一个不同的产品。
  • 用户不清楚他们应该使用 Robodog 还是直接使用 Uppy
  • Robodog 因为其限制而更易于使用。当你达到这样的限制时,你需要重构一切以使用带有插件的 Uppy

这导致我们弃用 Robodog,并拥抱 Uppy 的强项:模块化和灵活性。同时,我们也引入了一种方法来减少重复的集成代码:@uppy/remote-sources

要模仿具有所有功能的 Robodog 实现,你可以使用以下代码片段。但很可能 Robodog 做的比你所需的更多,所以请随意删除不需要的部分,或者查看 插件列表 并安装和使用你需要的插件。

你也可以查看我们在 这个提交 中如何自己迁移 Robodog 示例。

import Uppy from "@uppy/core";
import Dashboard from "@uppy/dashboard";
import RemoteSources from "@uppy/remote-sources";
import Webcam from "@uppy/webcam";
import ScreenCapture from "@uppy/screen-capture";
import GoldenRetriever from "@uppy/golden-retriever";
import ImageEditor from "@uppy/image-editor";
import Audio from "@uppy/audio";
import Transloadit, {
  COMPANION_URL,
  COMPANION_ALLOWED_HOSTS,
} from "@uppy/transloadit";

import "@uppy/core/dist/style.css";
import "@uppy/dashboard/dist/style.css";
import "@uppy/audio/dist/style.css";
import "@uppy/screen-capture/dist/style.css";
import "@uppy/image-editor/dist/style.css";

new Uppy()
  .use(Dashboard, {
    inline: true,
    target: "#app",
    showProgressDetails: true,
    proudlyDisplayPoweredByUppy: true,
  })
  .use(RemoteSources, {
    companionUrl: COMPANION_URL,
    companionAllowedHosts: COMPANION_ALLOWED_HOSTS,
  })
  .use(Webcam, {
    showVideoSourceDropdown: true,
    showRecordingLength: true,
  })
  .use(Audio, {
    showRecordingLength: true,
  })
  .use(ScreenCapture)
  .use(ImageEditor)
  .use(Transloadit, {
    service: "https://api2.transloadit.com",
    async getAssemblyOptions(file) {
      // 在这里配置你的认证密钥、密钥秘密和模板ID
      // /uppy/docs/transloadit/#getAssemblyOptions-file
      //
      // 在生产环境中设置秘密很重要:
      // https://transloadit.com/docs/topics/signature-authentication/
      const response = await fetch("/some-endpoint");
      return response.json();
    },
  });

从 Uppy 2.x 迁移到 3.x

Uppy 是纯 ESM

遵循许多包的脚步,我们现在只将 Uppy 核心及其插件作为 ECMAScript 模块(ESM)发布。在 Uppy 2.x 中,我们发布了 CommonJS。

如果你已经在使用 ESM,或者使用了 CDN 构建,对你来说没有任何变化!

如果你正在使用 CommonJS,你可能需要添加一些工具以使所有内容正常工作,或者你可能希望将你的代码库重构为 ESM - 参考 纯 ESM 包 gists 获取更多信息和如何做到这一点的帮助。

Robodog 已被弃用

参见 从 Robodog 迁移到 Uppy 插件 的迁移指南。

@uppy/core

移除 AggregateError 补丁。

它已被大多数现代浏览器支持,并且 可以在需要时由用户填充

要迁移:安装一个 AggregateError 补丁或使用 core-js

移除 reset() 方法。

它的名称不如 cancelAll 具有明确的意图。

要迁移:使用 cancelAll

移除向后兼容的导出( Uppy 上的静态属性)

UppyUIPluginBasePlugindebugLogger 过去也可以在 Uppy 导出上访问。由于转向 ESM,这现在已被删除。

要迁移:默认导入 Uppy 类,并/或使用其他所有内容的命名导出。

uppy.validateRestrictions() 现在返回 RestrictionError

此方法过去返回 {result: false, reason: err.message},但这感觉很奇怪,因为它试图模仿错误。现在,它返回一个 RestrictionError ,这是一个扩展的 Error 类。

要迁移:检查返回值,如果定义了则表示有错误,否则一切正常。注意错误是 return 的,不是 throw 的,所以你不必 catch 它 。

@uppy/transloadit

移除 ALLOWED_COMPANION_PATTERNCOMPANIONCOMPANION_PATTERN 的导出,以支持 COMPANION_URLCOMPANION_ALLOWED_HOSTS 。这是为了拥有更具描述性的名称,COMPANION 听起来像是 Companion 实例,而 COMPANION_URL 使其更清晰地表示 URL。

这些属性现在可以导入并用于使用 Transloadit 时的远程源插件:

import { COMPANION_URL, COMPANION_ALLOWED_HOSTS } from "@uppy/transloadit";

// ...
uppy.use(Dropbox, {
  companionUrl: COMPANION_URL,
  companionAllowedHosts: COMPANION_ALLOWED_HOSTS,
});

@uppy/aws-s3-multipart

prepareUploadParts 返回值中的 headers 也按部分索引。

这是为了允许为每个部分设置自定义头部。详细信息请参阅此 问题

要迁移:使头部像 presignedUrls 一样按部分索引:{ "headers": { "1": { "Content-MD5": "foo" } }}

移除 client 获取器和设置器。

它仅用于内部使用。

要迁移:仅使用公开的选项。

@uppy/tus/@uppy/aws-s3@uppy/xhr-upload

metaFields 选项重命名为 allowedMetaFields 。反直觉的是,metaFields 用于过滤要随请求发送的 metaFields ,而不是向请求添加额外的元数据字段。由于很多人对此感到困惑,且该名称与 Dashboard 的metaFields选项 重叠,我们将其重命名。

要迁移:使用 allowedMetaFields

@uppy/react

将 Uppy 依赖项更改为同行依赖项

@uppy/dashboard@uppy/drag-drop@uppy/file-input@uppy/progress-bar,和 @uppy/status-bar 现在是同行依赖项。这意味着如果您只需要其中一个,您就不需要安装所有这些包。

要迁移:只安装您需要的包。如果您使用 Dashboard 组件,您需要 @uppy/dashboard ,依此类推。

不将导出组件上的 validProps 公开。

它仅用于内部使用。

要迁移:仅使用公开的选项。

@uppy/svelte

@uppy/dashboard@uppy/drag-drop@uppy/progress-bar,和 @uppy/status-bar 现在是同行依赖项。这意味着如果您只需要其中一个,您就不需要安装所有这些包。

要迁移:只安装您需要的包。如果您使用 Dashboard 组件,您需要 @uppy/dashboard ,依此类推。

@uppy/vue

@uppy/dashboard@uppy/drag-drop@uppy/file-input@uppy/progress-bar,和 @uppy/status-bar 现在是同行依赖项。这意味着如果您只需要其中一个,您就不需要安装所有这些包。

要迁移:只安装您需要的包。如果您使用 Dashboard 组件,您需要 @uppy/dashboard ,依此类推。

@uppy/store-redux

移除向后兼容的导出( ReduxStore 上的静态属性)。如 reducer 这样的导出过去也可以在 ReduxStore 导出上访问。由于转向 ESM,这已删除。

要迁移:使用命名导入。

@uppy/thumbnail-generator

从插件原型中移除rotateImageprotectcanvasToBlob。它们仅用于内部使用。

要迁移:仅使用公开的选项。

已知问题

从 Companion 3.x 迁移到 4.x

最低要求的 Node.js 版本为 v14.20.0

与 Node.js 长期支持(LTS)时间表 对齐,并使用现代语法特性。

companion.app() 返回 { app, emitter } 而不是 app

在 3.x 中,Companion 通过 app.companionEmitter 提供 emitter。在 4.x 中,返回一个具有 app 属性(Express 中间件)和 emitter 属性(事件发射器)的对象。这为未来提供了更多灵活性,并遵循最佳实践。

移除了 providerOptions 内的 searchProviders 包装对象

为了使用 @uppy/unsplash ,您需要在 Companion 内配置 Unsplash 的 providerOptions.searchProviders 。这是多余的,因为 Unsplash 本身就是一个提供商,所以我们移除了包装对象。

s3 选项移出了 providerOptions

要使用 AWS S3 进行存储,您需要在 providerOptions 中配置 s3 对象。但 S3 不是一个提供商,而是一个目的地。为了避免混淆,我们将 s3 设置移动到了根设置对象。

删除了对旧版自定义提供商实现的兼容性

自定义提供商实现必须使用 Promise API。回调 API 不再受支持。

AWS S3 默认无 ACL

默认情况下,对于 S3 上传,无 ACL 。以前的默认值是 public-read ,但现在 AWS 不推荐使用 ACL。环境变量 COMPANION_AWS_DISABLE_ACL 也被移除,取而代之的是 Companion 仅使用 COMPANION_AWS_ACL

Uppy 在任何 GET 请求中发送的 protocol 现在是必需的(之前默认为 Multipart)。

如果您使用任何官方 Uppy 插件,则无需迁移。对于与 Companion 通信的自定义插件,请确保发送 protocol 头,其值为 multiparts3Multiparttus

emitSuccessemitError 现在是 Uploader 类上的私有方法。

您可能没有使用这个,但从技术上讲这是一个破坏性更改。通常,不要依赖隐式内部方法,而是使用公开的 API。

移除了 AWS S3 多部分的 chunkSize 向后兼容性

chunkSize 选项现在将用作 AWS 多部分的 partSize 。以前,只有有效的值才会被尊重。无效的值会被忽略。现在,任何值都会传递给 AWS SDK,可能在无效值上抛出错误。

移除了 /metrics 端点的向后兼容性

metrics 选项是一个布尔标志,告诉 Companion 是否提供具有 Prometheus 指标的 /metrics 端点。指标现在始终在 options.server.path 下提供。在 v4.x 之前,它总是在根目录下提供。

例如:如果 { options: { metrics: true, server: { path: '/companion' }}} ,指标现在将在 /companion/metrics 下提供。在 v3.x 中,指标会在 /metrics 下提供。

从 Uppy 1.x 迁移到 2.x

新捆绑包需要手动填充

随着 2.0 的发布,我们跟随 Microsoft 的脚步,放弃了对 IE11 的支持。因此,我们能够删除所有内置的填充,新的捆绑包大小减少了 25%!如果您希望您的应用仍能支持较旧的浏览器(如 IE11),您可能需要向您的捆绑包中添加以下填充:

如果你使用的是打包工具,需要在引入 Uppy 之前导入以下内容:

import "core-js";
import "whatwg-fetch";
import "abortcontroller-polyfill/dist/polyfill-patch-fetch";
// 这里顺序很重要:AbortController需要fetch,而fetch需要Promise(由core-js提供)。

import "md-gum-polyfill";
import ResizeObserver from "resize-observer-polyfill";

window.ResizeObserver ??= ResizeObserver;

export { default } from "@uppy/core";
export * from "@uppy/core";

如果你从 CDN 使用 Uppy,我们现在提供了两个捆绑包:一个适用于现代浏览器(不包含 polyfill 并使用现代语法),另一个适用于旧版浏览器。迁移时,请注意你想要支持的浏览器类型:

<!-- 现代浏览器(推荐) -->
<script src="https://releases.transloadit.com/uppy/v3.17.0/uppy.min.js"></script>

<!-- 旧版浏览器(IE11+) -->
<script
  nomodule
  src="https://releases.transloadit.com/uppy/v3.17.0/uppy.legacy.min.js"
></script>
<script type="module">
  import "https://releases.transloadit.com/uppy/v3.17.0/uppy.min.js";
</script>

请注意,虽然你可能可以通过这种方式使 2.0 版本在 IE11 中工作,但我们不再正式支持它。

使用 BasePluginUIPlugin 代替 Plugin

@uppy/core 以前提供了一个用于创建插件的 Plugin 类。这被用于所有官方插件,但也可以用于想要创建自定义插件的用户。但是,即使插件本身没有添加任何 UI 元素,Plugin 也总是捆绑了 Preact。

Plugin 已被 BasePluginUIPlugin 取代。BasePlugin 是创建插件所需的最小内容,而 UIPlugin 则添加了用于渲染用户界面的 Preact。

你可以从 @uppy/core 导入它们:

import { BasePlugin, UIPlugin } from "@uppy/core";

**注意:**某些打包工具可能会在从 @uppy/core 导入时包含 UIPlugin(以及 Preact)。为了确保不会发生这种情况,你可以直接导入 UppyBasePlugin

import Uppy from "@uppy/core/lib/Uppy.js";
import BasePlugin from "@uppy/core/lib/BasePlugin.js";

为你的 Uppy 插件使用最新版 Preact

官方插件已经升级。如果你使用任何自定义插件,请将 Preact 升级到最新版本。目前是 10.5.13

从本地化设置插件标题

插件的标题以前是通过插件选项中的 title 属性设置的,而其他字符串是在 locale 中设置的。现在已对齐。你应该从 locale 属性设置插件标题。

以前

import Webcam from "@uppy/webcam";

uppy.use(Webcam, {
  title: "Some title",
});

以后

import Webcam from "@uppy/webcam";

uppy.use(Webcam, {
  locale: {
    strings: {
      title: "Some title",
    },
  },
});

使用 new 关键字初始化 Uppy

默认导出 Uppy 不再可作为函数调用。这意味着你需要使用 new 关键字构造 Uppy 实例。

import Uppy from "@uppy/core";

const uppy = new Uppy(); // 正确。

const otherUppy = Uppy(); // 错误,会抛出异常。

allowMultipleUploads 重命名为 allowMultipleUploadBatches

allowMultipleUploadBatches 意味着允许多次调用 .upload(),换句话说,用户可以在已经上传了一些文件后添加更多文件。

我们已经将其重命名以更清楚地表明这是关于上传的,而不是用户是否可以为一次上传选择多个文件。

const uppy = new Uppy({
  allowMultipleUploadBatches: true,
});

@uppy/xhr-upload@uppy/tus 的新默认限制

默认限制已从 0 更改为 5 。将此设置为 0 表示并发上传无限制。

你可以在 Tus 和 XHR 插件选项中更改此限制。

uppy.use(Tus, {
  // ...
  limit: 10,
});
uppy.use(XHRUpload, {
  // ...
  limit: 10,
});

TypeScript 更改

Uppy 以前默认具有宽松类型,并且严格类型是可选的。默认导出是一个返回 Uppy 类的函数,类型与默认导出一起捆绑( Uppy.SomeType )。

import Uppy from "@uppy/core";
import Tus from "@uppy/tus";

const uppy = Uppy<Uppy.StrictTypes>();

uppy.use(Tus, {
  invalidOption: null, // 这将导致编译失败!
});

从现在起,Uppy 默认严格类型化,并移除了宽松类型。

// ...

const uppy = new Uppy();

uppy.use(Tus, {
  invalidOption: null, // 这将导致编译失败!
});

Uppy 的类型现在是单独导出的,应分别导入。

import type { PluginOptions, UIPlugin, PluginTarget } from "@uppy/core";

事件类型

@uppy/core 提供了一个 .on 方法来监听 事件 。这些事件的类型比较宽松,允许传递无效的事件,例如 uppy.on('upload-errrOOOoooOOOOOrrrr')

// Before:

type Meta = { myCustomMetadata: string };

// 无效的事件
uppy.on<Meta>("upload-errrOOOoooOOOOOrrrr", () => {
  // ...
});

// After:

// 正常的事件签名
uppy.on("complete", (result) => {
  const successResults = result.successful;
});

// 自定义签名
type Meta = { myCustomMetadata: string };

// 注意自定义类型现在变成了第二个参数
uppy.on<"complete", Meta>("complete", (result) => {
  // 传递的类型现在合并到了 `meta` 类型中。
  const meta = result.successful[0].meta.myCustomMetadata;
});

添加自定义事件的插件可以通过 declare module '@uppy/core' { ... }@uppy/core 中的现有事件合并。这是一种 TypeScript 的模式,称为 模块扩展。例如,使用 @uppy/dashboard

uppy.on("dashboard:file-edit-start", (file) => {
  const fileName = file.name;
});

对于 @uppy/aws-s3-multipart 的预签名 URL 的更改

参见 Uppy 2.0.0 发布公告中关于批处理 预签名 URL 更改 的部分。

prepareUploadPart 已重命名为 prepareUploadParts(复数形式)。请参阅文档链接以了解如何使用此函数。

移除了 @uppy/core.run 方法

Uppy 实例上的 .run 方法已被移除。此方法已过时,只会发出警告。从这个主要版本开始,它不再存在。

@uppy/tus 移除了 resumeremoveFingerprintOnSuccess 选项

Tus 现在默认会尝试恢复过去已经开始的上传。

这也意味着 Tus 将为每个上传在 localStorage 中存储一些数据,成功后会自动删除。这使得 removeFingerprintOnSuccess 也变得过时。

完毕!

Uppy 1.0 将在未来三个月内(直到 2021 年 12 月 1 日)继续接收错误修复,在接下来的一年内(直到 2022 年 9 月 1 日)接收安全修复,但今天之后不再有新功能。例外情况不太可能发生,但 可以 考虑——例如,为了满足那些拥有商业支持合同的用户。

希望你不会浪费时间,立即尝试 Uppy 2.0。当你这样做时,请在 RedditHN、ProductHunt 或 Twitter 上告诉我们你的想法。我们渴望听到你的声音!

从 Companion 1.x 迁移到 2.x

先决条件

从 v2 开始,你现在需要运行 node.js >= v10.20.1 来使用 Companion。

ProviderOptions

在 v2 中,googlemicrosoft ProviderOptions 已更改为 driveonedrive

OAuth 重定向 URI

在你的提供商各自的开发人员平台上,你应该提供的 OAuth 重定向 URI 现在已从:

http(s)://$COMPANION_HOST_NAME/connect/$AUTH_PROVIDER/callback(v1)

变更为:

http(s)://$COMPANION_HOST_NAME/$PROVIDER_NAME/redirect(v2)

新的重定向 URI

提供商 新的重定向 URI
Dropbox https://$COMPANION_HOST_NAME/dropbox/redirect
Google Drive https://$COMPANION_HOST_NAME/drive/redirect
Google Photos https://$COMPANION_HOST_NAME/googlephotos/redirect
OneDrive https://$COMPANION_HOST_NAME/onedrive/redirect
Box https://$YOUR_COMPANION_HOST_NAME/box/redirect
Facebook https://$COMPANION_HOST_NAME/facebook/redirect
Instagram https://$COMPANION_HOST_NAME/instagram/redirect
在本文档中