Skip to content

Commit

Permalink
docs(builder): add project reference guide (#4691)
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjiahan authored Sep 20, 2023
1 parent 6d8cb68 commit c12a209
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,52 @@ If the sub-project uses [exports](https://nodejs.org/api/packages.html#package-e
}
```

## Configure Project Reference

In a TypeScript project, you need to use the capability provided by TypeScript called [Project Reference](https://www.typescriptlang.org/docs/handbook/project-references.html). It helps you develop source code more effectively.

### Introduction

Project reference provides the following capabilities:

- It allows TypeScript to correctly recognize the types of other sub-projects without the need to build them.
- When you navigate the code in VS Code, it automatically takes you to the corresponding source code file of the module.
- Modern.js Builder reads the project reference configuration and automatically recognizes the `tsconfig.compilerOptions.path` configuration of the sub-project, so that the use of aliases in the sub-project works correctly.

### Example

In the example mentioned earlier, since the app project references the lib sub-project, we need to configure the `composite` and `references` options in the app project's `tsconfig.json` file and point them to the corresponding relative directory of lib:

```json title="app/tsconfig.json"
{
"compilerOptions": {
"composite": true
},
"references": [
{
"path": "../lib"
}
]
}
```

After adding these two options, the project reference is already configured. You can restart VS Code to see the effects of the configuration.

Note that the above example is a simplified one. In real monorepo projects, there may be more complex dependency relationships. You need to add a complete `references` configuration for the functionality to work correctly.

:::tip
If you want to learn more about project reference, please refer to the official documentation on [TypeScript - Project References](https://www.typescriptlang.org/docs/handbook/project-references.html).
:::

## Caveat

When using source code build mode, there are a few things to keep in mind:

1. Ensure that the current project can compile the syntax or features used in the sub-project. For example, if the sub-project uses Stylus to write CSS, the current app needs to support Stylus compilation.
2. Ensure that the current project has the same code syntax and features as the sub-project, such as consistent syntax versions for decorators.
3. Source code building may have some limitations. When encountering issues, you can remove the `source` field from the sub-project's package.json and debug using the built artifacts of the sub-project.
4. When `composite: true` is enabled, TypeScript will generate `*.tsbuildinfo` temporary files. You need to add these temporary files to the `.gitignore` file.

```text title=".gitignore"
*.tsbuildinfo
```
10 changes: 7 additions & 3 deletions packages/document/builder-doc/docs/en/guide/faq/exceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,15 @@ When this happens, you can specify directories or modules that need to be compil

### Failed import other modules in Monorepo?

For the sake of compilation performance, by default, Builder will not compile files under `node_modules` through `babel-loader` or `ts-loader`, nor will it compile files outside the current project directory.
Due to considerations of compilation performance, by default, the Builder does not compile files under `node_modules` or files outside the current project directory.

Through the `source.include` configuration option, you can specify directories or modules that require additional compilation.
Therefore, when you reference the source code of other sub-projects, you may encounter an error similar to `You may need an additional loader to handle the result of these loaders.`

For details, see [source.include usage introduction](/en/api/config-source.html#sourceinclude).
There are several solutions to this problem:

1. You can enable the source code build mode to compile other sub-projects within the monorepo. Please refer to [Source Code Build Mode](/guide/advanced/source-build.html) for more information.
2. You can add the `source.include` configuration option to specify the directories or modules that need to be additionally compiled. Please refer to [Usage of source.include](/api/config-source.html#sourceinclude) for more information.
3. You can pre-build the sub-projects that need to be referenced, generate the corresponding build artifacts, and then reference the build artifacts in the current project instead of referencing the source code.

---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,52 @@ export default {
}
```

## 配置 Project Reference

在 TypeScript 项目中,你需要使用 TypeScript 提供的 [Project Reference](https://www.typescriptlang.org/docs/handbook/project-references.html) 能力,它可以帮助你更好地使用源码开发。

### 介绍

Project reference 提供了以下能力:

- 使 TypeScript 可以正确识别其他子项目的类型,而无须对子项目进行构建。
- 当你在 VS Code 内进行代码跳转时,VS Code 可以自动跳转到对应模块的源代码文件。
- Modern.js Builder 会读取 project reference 配置,并自动识别子项目的 `tsconfig.compilerOptions.path` 配置,从而让子项目的别名可以正确生效。

### 示例

在上文的例子中,由于 app 引用了 lib 子项目,我们需要在 app 的 `tsconfig.json` 内配置 `composite``references`,并指向 lib 对应的相对目录:

```json title="app/tsconfig.json"
{
"compilerOptions": {
"composite": true
},
"references": [
{
"path": "../lib"
}
]
}
```

添加以上两个选项后,project reference 就已经配置完成了,你可以重新启动 VS Code 来查看配置以后的效果。

注意以上只是一个最简单的例子,在实际的 monorepo 项目中,可能会有更复杂的依赖关系,你需要添加完整的 `references` 配置,才能使上述功能正确运作。

:::tip
如果你想了解更多关于 project reference 的内容,请阅读 [TypeScript - Project References](https://www.typescriptlang.org/docs/handbook/project-references.html) 官方文档。
:::

## 注意事项

在使用源码构建模式的时候,需要注意几点:

1. 需要保证当前项目可以编译子项目里使用的语法或特性。比如子项目使用了 Stylus 来编写 CSS 样式,那就需要当前 app 支持 Stylus 编译。
2. 需要保证当前项目与子项目使用的代码语法特性相同,例如装饰器的语法版本一致。
3. 源码构建可能存在一些限制。如果在使用中遇到问题,你可以将子项目 package.json 中的 `source` 字段移除,使用子项目的构建产物进行调试。
4. 开启 `composite: true` 后,TypeScript 会生成 `*.tsbuildinfo` 临时文件,你需要将这些临时文件加入 .gitignore 中。

```text title=".gitignore"
*.tsbuildinfo
```
10 changes: 7 additions & 3 deletions packages/document/builder-doc/docs/zh/guide/faq/exceptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,15 @@ webpack 版本问题有以下几种情况:

### 在 Monorepo 中引用其他模块,代码没有被正确编译?

出于编译性能的考虑,默认情况下,Builder 不会通过 `babel-loader``ts-loader` 来编译 `node_modules` 下的文件,也不会编译当前工程目录外部的文件。
出于编译性能的考虑,默认情况下,Builder 不会编译 `node_modules` 下的文件,也不会编译当前工程目录外部的文件。

通过 `source.include` 配置项,可以指定需要额外进行编译的目录或模块
因此,当你引用其他子项目的源代码时,可能会遇到类似 `You may need an additional loader to handle the result of these loaders.` 的报错

详见 [source.include 用法介绍](/api/config-source.html#sourceinclude)
这个问题有以下解决方法:

1. 你可以开启源码构建模式来编译 monorepo 中的其他子项目,参考[「源码构建模式」](/guide/advanced/source-build.html)
2. 你可以添加 `source.include` 配置项,指定需要额外进行编译的目录或模块,参考 [source.include 用法介绍](/api/config-source.html#sourceinclude)
3. 你可以预先构建需要引用的子项目,生成对应的构建产物,并在当前项目引用构建产物,而不是引用源代码。

---

Expand Down

0 comments on commit c12a209

Please sign in to comment.