添加更多任务
本节继续介绍来自 Hello World 教程的教程项目。
Heft 的 架构 是围绕插件包设计的。Heft 附带了一系列用于最常见构建任务的 官方插件包。它们的源代码可以在 rushstack/heft-plugins 中找到,如果你想创建自己的 Heft 插件,它是一个很好的参考。
继续我们的教程,让我们启用两个最常见的插件:Jest 用于单元测试,ESlint 用于样式检查。
将单元测试添加到您的项目
首先,我们需要为 Jest 安装 TypeScript 类型定义。这些步骤继续来自 Hello World 教程的 my-app 项目。回想一下,这个项目还没有使用 Rush,因此我们将直接调用 PNPM 将依赖项添加到我们的 package.json 文件中(而不是使用 rush add)。
cd my-app
# Because @types packages don't follow SemVer, it's a good idea to use --save-exact
pnpm install --save-dev --save-exact @types/heft-jest
pnpm install --save-dev @rushstack/heft-jest-plugin在您的 Heft 配置文件中添加一个
"test"
部分,产生以下结果config/heft.json
{
"$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json",
"phasesByName": {
// Define a phase whose name is "build"
"build": {
"phaseDescription": "This phase compiles the project source code.",
// Before invoking the compiler, delete the "dist" and "lib" folders
"cleanFiles": [{ "sourcePath": "dist" }, { "sourcePath": "lib" }],
"tasksByName": {
// Define a task whose name is "typescript"
"typescript": {
"taskPlugin": {
// This task will invoke the TypeScript plugin
"pluginPackage": "@rushstack/heft-typescript-plugin"
}
}
}
},
// Define a phase whose name is "test"
"test": {
"phaseDescription": "This phase runs the project's unit tests.",
// This phase requires the "build" phase to be run first
"phaseDependencies": ["build"],
"tasksByName": {
// Define a task whose name is "jest"
"jest": {
"taskPlugin": {
// This task will invoke the Jest plugin
"pluginPackage": "@rushstack/heft-jest-plugin"
}
}
}
}
}
}有关这些设置的完整描述,请参阅 heft.json 模板。
如果您运行
heft --help
,您现在应该看到test
和test-watch
命令行操作,因为我们的第二阶段被命名为"test"
。由于 Jest 的 API 由全局变量组成,我们需要全局加载它们(而大多数其他
@types
包是通过您的源代码中的import
语句加载的)。更新您的 tsconfig.json 文件,改为"types": ["heft-jest", "node"]
,而不是"types": ["node"]
。结果应该如下所示my-app/tsconfig.json
{
"$schema": "http://json.schemastore.org/tsconfig",
"compilerOptions": {
"outDir": "lib",
"rootDirs": ["src/"],
"forceConsistentCasingInFileNames": true,
"declaration": true,
"sourceMap": true,
"declarationMap": true,
"inlineSources": true,
"experimentalDecorators": true,
"strict": true,
"useUnknownInCatchVariables": false,
"esModuleInterop": true,
"noEmitOnError": false,
"allowUnreachableCode": false,
"types": ["heft-jest", "node"],
"module": "commonjs",
"target": "es2017",
"lib": ["es2017"]
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "lib"]
}接下来,我们需要添加 jest.config.json 配置文件。此文件的存在会导致 Heft 调用 Jest 测试运行器。Heft 期望特定文件路径 config/jest.config.json。对于大多数情况,您的 Jest 配置只需扩展 Heft 的标准预设,如下所示
my-app/config/jest.config.json
{
"extends": "@rushstack/heft-jest-plugin/includes/jest-shared.config.json",
"collectCoverage": true,
"coverageThreshold": {
"global": {
"branches": 50,
"functions": 50,
"lines": 50,
"statements": 50
}
}
}注意:对于 Web 项目,您可能希望使用
@rushstack/heft-jest-plugin/includes/jest-web.config.json
而不是jest-shared.config.json
来支持lib-commonjs
和lib
文件夹的双输出。有关详细信息,请参阅 Jest 插件 文档。现在我们需要添加一个单元测试。Jest 支持很多功能,但对于本教程,我们将创建一个简单的测试文件。
.test.ts
文件扩展名会导致 Heft 在此文件中查找单元测试my-app/src/example.test.ts
describe('Example Test', () => {
it('correctly runs a test', () => {
expect(true).toBeTruthy();
});
});要运行测试,我们需要使用
heft test
操作,因为heft build
通常会跳过测试以加快开发速度。# View the command line help
heft test --help
# Build the project and run tests
heft test --verbose
# Run Jest in watch mode
heft test-watch哇,
heft test --help
有很多命令行参数!它们从哪里来?它们是由 Jest 插件的 heft-plugin.json 清单文件添加的,因为我们在阶段中加载了该插件。(如果两个不同的插件定义了相同的命令行参数会发生什么?Heft 包含一个复杂的消除歧义机制,例如,如果其他一些插件也定义了
--update-snapshots
参数,则允许您使用--jest:update-snapshots
而不是--update-snapshots
)。我们应该更新我们的 package.json 脚本,以便
pnpm run test
将运行 Jest 测试my-app/package.json
{
. . .
"scripts": {
"build": "heft build --clean",
"test": "heft test --clean",
"start": "node lib/start.js"
},
. . .
}
注意:不要直接调用
jest
命令行。这样做会运行它在lib/**/*.js
中找到的测试,但不会调用 Heft 更新这些输出文件所需的其余任务。
这就是设置 Jest 的全部内容!有关更多信息(包括测试调试说明),请参阅 Jest 插件 参考和 heft-node-jest-tutorial 示例项目。
启用代码风格检查
为了确保最佳实践并捕获常见错误,让我们也启用 @rushstack/eslint-config 标准规则集。首先,我们需要在 package.json 文件中添加一些额外的 NPM 依赖项。
cd my-app
# Add the ESLint engine
pnpm install --save-dev eslint
# Add Heft's plugin for ESLint
pnpm install --save-dev @rushstack/heft-lint-plugin
# Add Rush Stack's all-in-one lint ruleset
pnpm install --save-dev @rushstack/eslint-config更新您的 Heft 配置文件以添加一个在
heft build
阶段加载@rushstack/heft-lint-plugin
的任务config/heft.json
{
"$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json",
"phasesByName": {
// Define a phase whose name is "build"
"build": {
"phaseDescription": "Compiles the project source code",
// Before invoking the compiler, delete the "dist" and "lib" folders
"cleanFiles": [{ "sourcePath": "dist" }, { "sourcePath": "lib" }],
"tasksByName": {
// Define a task whose name is "typescript"
"typescript": {
"taskPlugin": {
// This task will invoke the TypeScript plugin
"pluginPackage": "@rushstack/heft-typescript-plugin"
}
},
// Define a task whose name is "lint"
"lint": {
// This task should run after "typescript" has completed
// because Heft optimizes ESLint by reusing the TypeScript
// compiler's AST analysis
"taskDependencies": ["typescript"],
"taskPlugin": {
// This task will invoke the ESLint plugin
"pluginPackage": "@rushstack/heft-lint-plugin"
}
}
}
},
// Define a phase whose name is "test"
"test": {
// This phase requires the "build" phase to be run first
"phaseDependencies": ["build"],
"tasksByName": {
// Define a task whose name is "jest"
"jest": {
"taskPlugin": {
// This task will invoke the Jest plugin
"pluginPackage": "@rushstack/heft-jest-plugin"
}
}
}
}
}
}有关这些设置的完整描述,请参阅 heft.json 模板。
接下来,创建 .eslintrc.js 配置文件。对于本教程,我们将只使用官方 Rush Stack 规则集
my-app/.eslintrc.js
// This is a workaround for https://github.com/eslint/eslint/issues/3458
require('@rushstack/eslint-config/patch/modern-module-resolution');
module.exports = {
extends: ['@rushstack/eslint-config/profile/node'],
parserOptions: { tsconfigRootDir: __dirname }
};注意:如果您的项目使用 React 框架,您还应该从
"@rushstack/eslint-config/mixins/react"
混入中扩展。有关@rushstack/eslint-config
"配置文件" 和 "混入" 的详细信息,请参阅 文档。为了测试它,尝试更新您的 start.ts 源文件以引入代码风格检查问题
my-app/src/start.ts
console.log('Hello, world!');
export function f() {
// <--- oops
}当您运行
pnpm run build
时,您应该看到类似以下的日志消息-------------------- Finished (3.555s) --------------------
Encountered 1 warning
[build:lint] src/start.ts:3:8 - (@typescript-eslint/explicit-function-return-type) Missing return type on function.要解决此问题,请修复代码以添加缺少的返回类型,现在它应该成功构建
my-app/src/start.ts
console.log('Hello, world!');
export function f(): void {
// <--- okay
}@rushstack/eslint-config
规则集旨在与 Prettier 代码格式化程序一起使用。要设置它,请参阅 Rush 网站上的 启用 Prettier 文章。
这就是 ESLint 的全部内容!更多详细信息可以在 Lint 插件 参考中找到。