库中的框架绑定

库软件包 中的框架绑定通过在库中直接利用框架的 API,将你的库代码与框架更深入地集成。

¥Framework bindings in a Library Package integrate your library's code more deeply with a framework by leveraging APIs from the framework directly in the library.

为此,请在库的 package.json 中使用 peerDependencies 字段,这使得框架 API 在你的库中可用,而无需将其直接安装在包中。

¥To do this, use the peerDependencies field in package.json of the library, which makes the framework APIs available in your library without installing it directly in the package.

Good to know: 

在本页面中,我们将使用 Next.js 作为示例,但以下概念适用于任何框架或其他依赖。

¥On this page, we'll be using Next.js for examples, but the concepts below apply to any framework or other dependency.

示例

¥Example

peerDependency 添加到你要为其创建绑定的依赖的库中。

¥Add a peerDependency to your library for the dependency that you intend to create bindings for.

./packages/ui/package.json
{
  "name": "@repo/ui",
  "peerDependencies": {
    "next": "*"
  }
}

Good to know: 

在上面的示例中,nextpeerDependency 接受任何版本。你可能需要根据需要指定一个范围(例如,">=15")。此外,对于较旧的包管理器,你可能需要指示包管理器使用配置安装对等依赖,或者将依赖添加到 devDependencies 作为解决方法。

¥In the example above, the peerDependency for next accepts any version. You may want to specify a range (for example, ">=15") according to your needs. Additionally, for older package managers, you may need to instruct your package manager to install peer dependencies with configuration, or add the dependency to devDependencies as a workaround.

这将使依赖在你的库中可用,允许你编写如下所示的代码。注意 className 属性,它为 monorepo 中的组件设置了默认样式,并且可以在 props 对象中覆盖它。

¥This will make the dependency available in your library, allowing you to write code like below. Note the className prop, which sets a default styling for this component in the monorepo and can be overridden in the props object.

./packages/ui/src/link.tsx
import Link from 'next/link';
import type { ComponentProps } from 'react';
 
type CustomLinkProps = ComponentProps<typeof Link>;
 
export function CustomLink({ children, ...props }: CustomLinkProps) {
  return (
    <Link className="text-underline hover:text-green-400" {...props}>
      {children}
    </Link>
  );
}

将为包解析的 next 版本将来自库的使用者。例如,如果你的应用中安装了 Next.js 15,则 next 的 TypeScript 类型和 API 也将是 Next.js 15。

¥The version of next that will be resolved for the package will come from the consumers of the library. For example, if Next.js 15 is installed in your applications, the TypeScript types and APIs for next will also be Next.js 15.

使用入口点拆分框架绑定

¥Splitting framework bindings using entrypoints

使用导出路径将包拆分为特定于框架的入口点是向旨在支持多个框架的库添加绑定的最简单方法。通过拆分入口点,打包工具可以更轻松地理解你计划定位的框架,并且你不太可能看到奇怪的打包错误。

¥Using export paths to split a package into framework-specific entrypoints is the simplest way to add bindings to a library that aims to support multiple frameworks. By splitting entrypoints, bundlers have an easier time understanding the framework you intend to target and you're less likely to see strange bundling errors.

下面的示例展示了一个包含两个入口点的库,每个入口点对应不同类型的链接组件。这些抽象可能包含你自己的样式、API 以及它们所封装元素之上的其他调整。

¥The example below shows a library with two entrypoints, each for a different type of link component. These abstractions likely contain your own styles, APIs, and other adjustments on top of the element they're wrapping.

  • ./link:一个 <a> HTML 标签,其中包含一些来自你的设计系统的默认样式。

    ¥./link: An <a> HTML tag with some default styles from your design system

  • ./next-js/linkNext.js Link 组件 的定制版本,其 props 已根据你组织的偏好进行预设。

    ¥./next-js/link: A customized version of the Next.js Link component with props that are preset to your organization's preferences

  • ./svelte/link:带有预设的 Svelte 的 a 标签 的定制版本。

    ¥./svelte/link: A customized version of an a tag for Svelte with presets.

./packages/ui/package.json
{
  "exports": {
    "./link": "./dist/link.js",
    "./next-js/link": "./dist/next-js/link.js"
  },
  "peerDependencies": {
    "next": "*"
  }
}

Good to know: 

在上面的示例中,nextpeerDependency 接受任何版本。你可能需要根据需要指定一个范围(例如,">=15")。

¥In the example above, the peerDependency for next accepts any version. You may want to specify a range (for example, ">=15") according to your needs.

此概念可应用于你想要提供绑定的任意数量的框架或其他依赖。

¥This concept can be applied to any number of frameworks or other dependencies that you'd like to provide bindings for.