新增更多工作
本節繼續從 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新增一個
"test"
區段至您的 Heft 設定檔,產生下列結果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
}
}
}注意:對於網頁專案,您可能想要使用
@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外掛程式.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"
mixin 延伸。請參閱 文件記錄,以取得關於@rushstack/eslint-config
的「個人資料」與「mixin」的詳細資訊。為進行測試,嘗試更新您的 start.ts 來源檔,以加入一個 linter 議題
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 的部分就到此結束!更多詳細資訊可於 程式碼檢查擴充功能 參考中找到。