创建内部包
内部软件包 是你工作区的基石,为你提供了一种在代码库中共享代码和功能的强大方法。Turborepo 会使用 package.json
中的依赖自动理解内部包之间的关系,并在后台创建 软件包图表 以优化代码库的工作流程。
¥Internal Packages are the building blocks of your workspace, giving you a powerful way to share code and functionality across your repo. Turborepo automatically understands the relationships between Internal Packages using the dependencies in package.json
, creating a Package Graph under the hood to optimize your repository's workflows.
让我们使用 软件包结构 部分中的指导和 已编译的软件包 模式,创建你的第一个内部包,以便在你的代码库中共享数学实用程序。在以下步骤中,我们假设你已经拥有 使用以下方式创建新仓库 create-turbo
或正在使用类似结构的代码库。
¥Let's create your first Internal Package to share math utilities in your repo using the guidance in the Anatomy of a package section and the Compiled Packages pattern. In the steps below, we assume you've created a new repository using create-turbo
or are using a similarly structured repository.
创建一个空目录
¥Create an empty directory
你需要一个用于放置包的目录。让我们在 ./packages/math
上创建一个。
¥You'll need a directory to put the package in. Let's create one at ./packages/math
.
添加 package.json 文件
¥Add a package.json
接下来,为包创建 package.json
。通过添加此文件,你将满足 内部包的两个要求 的要求,使其可以被 Turborepo 和你工作区的其他部分发现:
¥Next, create the package.json
for the package. By adding this file, you'll fulfill the two requirements for an Internal Package, making it discoverable to Turborepo and the rest of your Workspace:
让我们逐一分解这个 package.json
:
¥Let's break down this package.json
piece-by-piece:
-
scripts
:dev
和build
脚本使用 TypeScript 编译器 编译软件包。dev
脚本将监视源代码的更改并自动重新编译软件包。¥
scripts
: Thedev
andbuild
script compile the package using the TypeScript compiler. Thedev
script will watch for changes to source code and automatically recompile the package. -
devDependencies
:typescript
和@repo/typescript-config
都是devDependencies
,因此你可以在@repo/math
包中使用这些包。在实际软件包中,你可能会有更多devDependencies
和dependencies
。 - 但我们现在可以保持简单。¥
devDependencies
:typescript
and@repo/typescript-config
aredevDependencies
so you can use those packages in the@repo/math
package. In a real-world package, you will likely have moredevDependencies
anddependencies
- but we can keep it simple for now. -
exports
:为包定义多个入口点,以便可以在其他包(import { add } from '@repo/math'
)中使用。¥
exports
: Defines multiple entrypoints for the package so it can be used in other packages (import { add } from '@repo/math'
).
需要注意的是,此 package.json
将内部包 @repo/typescript-config
声明为依赖。Turborepo 会将 @repo/math
识别为 @repo/typescript-config
的依赖,以便对任务进行排序。
¥Notably, this package.json
declares an Internal Package, @repo/typescript-config
, as a dependency. Turborepo will recognize @repo/math
as a dependent of @repo/typescript-config
for ordering your tasks.
添加 tsconfig.json
¥Add a tsconfig.json
通过将 tsconfig.json
文件添加到包的根目录来指定此包的 TypeScript 配置。TypeScript 具有 extends
键,允许你在整个代码库中使用基本配置,并根据需要使用不同的选项进行覆盖。
¥Specify the TypeScript configuration for this package by adding a tsconfig.json
file to the root of the package. TypeScript has an extends
key, allowing you to use a base configuration throughout your repository and overwrite with different options as needed.
你在这里完成了四件重要的事情:
¥You've done four important things here:
-
./packages/typescript-config
中的@repo/typescript-config/base.json
配置包含你需要的所有配置,因此你可以从中扩展。¥The
@repo/typescript-config/base.json
configuration that lives in./packages/typescript-config
has all the configuration you need so you extend from it. -
compilerOptions
中的outDir
键 会告诉 TypeScript 将编译输出放在哪里。它与package.json
中exports
指定的目录匹配。¥The
outDir
key incompilerOptions
tells TypeScript where to put the compiled output. It matches the directory specified in yourexports
inpackage.json
. -
compilerOptions
中的rootDir
键 确保outDir
中的输出使用与src
目录相同的结构。¥The
rootDir
key incompilerOptions
ensures that the output inoutDir
uses the same structure as thesrc
directory. -
include
和exclude
键并非从基本配置 根据 TypeScript 规范 继承,因此你在此处添加了它们。¥The
include
andexclude
keys are not inherited from the base configuration, according to the TypeScript specification, so you've included them here.
关于 TypeScript 配置还有很多需要学习,但目前这是一个很好的起点。如果你想了解更多信息,请访问 TypeScript 官方文档 或 我们的 TypeScript 指南。
¥There's a lot more to learn about TypeScript configuration, but this is a good place to start for now. If you'd like to learn more, visit the official TypeScript documentation or our TypeScript guide.
添加包含源代码的 src
目录
¥Add a src
directory with source code
你现在可以为你的包编写一些代码。在 src
目录中创建两个文件:
¥You can now write some code for your package. Create two files inside a src
directory:
这些文件映射到你稍后运行 turbo build
时 tsc
将创建的输出。
¥These files map to the outputs that will be created by tsc
when you run turbo build
in a moment.
将包添加到应用
¥Add the package to an application
你已准备好在应用中使用新的包。让我们将它添加到 web
应用中。
¥You're ready to use your new package in an application. Let's add it to the web
application.
你只需更改代码库中的依赖即可。确保运行包管理器的安装命令来更新锁文件。
¥You just changed the dependencies in your repo. Make sure to run your package manager's installation command to update your lockfile.
@repo/math
现在可在 web
应用中使用,你可以在代码中使用它:
¥@repo/math
is now available in the web
application, you can use it in your code:
Edit turbo.json
将新 @repo/math
库的工件添加到 turbo.json
中 build
任务的 outputs
中。这确保了 Turborepo 会缓存其构建输出,因此当你开始运行构建时,它们可以立即恢复。
¥Add the artifacts for the new @repo/math
library to the outputs
for the build
task in turbo.json
. This ensures that its build outputs will be cached by Turborepo, so they can be restored instantly when you start running builds.


运行 turbo build
¥Run turbo build
如果你已经安装了 全局安装 turbo
,请在工作区根目录的终端中运行 turbo build
。你还可以使用包管理器从 package.json
运行 build
脚本,这将使用 turbo run build
。
¥If you've installed turbo
globally, run turbo build
in your terminal at the root of your Workspace. You can also run the build
script from package.json
with your package manager, which will use turbo run build
.
@repo/math
包在 web
应用之前构建,以便 ./packages/math/dist
中的运行时代码在 web
应用打包时可供使用。
¥The @repo/math
package built before the web
application built so that the runtime code in ./packages/math/dist
is available to the web
application when it bundles.
你可以再次运行 turbo build
,以毫秒为单位查看你的 web
应用的重建情况。我们将在 缓存指南 中详细讨论这一点。
¥You can run turbo build
again to see your web
application rebuild in
milliseconds. We'll discuss this at length in the Caching
guide.
内部软件包的最佳实践
¥Best practices for Internal Packages
每个包一个 "purpose" 文件
¥One "purpose" per package
创建内部包时,建议创建包含单个 "purpose" 的包。这并非严格的科学或规则,而是一项最佳实践,取决于你的仓库、规模、组织、团队需求等等。此策略有几个优点:
¥When you're creating Internal Packages, it's recommended to create packages that have a single "purpose". This isn't a strict science or rule, but a best practice depending on your repository, your scale, your organization, what your teams need, and more. This strategy has several advantages:
-
更易于理解:随着仓库规模的扩大,在仓库中工作的开发者将更容易找到他们需要的代码。
¥Easier to understand: As a repository scales, developers working in the repository will more easily be able to find the code they need.
-
减少每个包的依赖:每个包使用更少的依赖,使 Turborepo 能够更有效地使用 修剪软件包图的依赖。
¥Reducing dependencies per package: Using fewer dependencies per package makes it so Turborepo can more effectively prune the dependencies of your package graph.
一些示例如下:
¥Some examples include:
-
@repo/ui
:包含所有共享 UI 组件的包¥
@repo/ui
: A package containing all of your shared UI components -
@repo/tool-specific-config
:用于管理特定工具配置的包¥
@repo/tool-specific-config
: A package for managing configuration of a specific tool -
@repo/graphs
:用于创建和操作图形数据的字段特定库¥
@repo/graphs
: A domain-specific library for creating and manipulating graphical data
应用包不包含共享代码
¥Application Packages do not contain shared code
创建 应用包 时,最好避免在这些包中放置共享代码。相反,你应该为共享代码创建一个单独的包,并让应用包依赖于该包。
¥When you're creating Application Packages, it's best to avoid putting shared code in those packages. Instead, you should create a separate package for the shared code and have the application packages depend on that package.
此外,应用包不应安装到其他包中。相反,它们应该被视为 软件包图表 的入口点。
¥Additionally, Application Packages are not meant to be installed into other packages. Instead, they should be thought of as an entrypoint to your Package Graph.
后续步骤
¥Next steps
新的内部软件包到位后,你可以启动 配置任务。
¥With a new Internal Package in place, you can start configuring tasks.