diff --git a/websites/api-extractor.com/docs/pages/configs/api-extractor_json.md b/websites/api-extractor.com/docs/pages/configs/api-extractor_json.md index a37b466c3..873f4d0c9 100644 --- a/websites/api-extractor.com/docs/pages/configs/api-extractor_json.md +++ b/websites/api-extractor.com/docs/pages/configs/api-extractor_json.md @@ -353,6 +353,52 @@ Example: Whether "forgotten exports" should be included in the API report file. Forgotten exports are declarations flagged with [ae-forgotten-export](../messages/ae-forgotten-export.md) warnings. +### apiReport.tagsToReport + +Example: + +```js + "apiReport": { + . . . + "tagsToReport": { + "@sealed": true, + "@virtual": true, + "@override": true, + "@eventProperty": true, + "@deprecated": true, + "@myCustomTag": true + }, + . . . + } +``` + +**Default value:** + +```js +{ + "@sealed": true, + "@virtual": true, + "@override": true, + "@eventProperty": true, + "@deprecated": true +} +``` + +Specifies a list of TSDoc tags that should be reported in the API report file for items whose documentation +contains them. This can be used to include standard TSDoc tags or custom ones. Specified tag names must +begin with `@`. + +Tags will appear in the order they are specified in this list. Note that an item's release tag will +always be reported; this behavior cannot be overridden. + +To disable a default tag, set its value to `false`: + +```js + "tagsToReport": { + "@sealed": false + } +``` + ## Doc Model Section Configures how the doc model file (\*.api.json) will be generated. @@ -433,6 +479,27 @@ item's file path is `api/ExtractorConfig.ts`, the full URL file path would be This setting can be omitted if you don't need source code links in your API documentation reference. +### docModel.releaseTagsToTrim + +Example: + +```js + "docModel": { + . . . + "releaseTagsToTrim": ["@internal", "@alpha"] + } +``` + +**Default value:** `["@internal"]` + +Specifies a list of release tags that will be trimmed from the doc model. Declarations with these +release tags will be excluded from the generated `.api.json` file. + +The default value trims `@internal` declarations. You can extend this to also trim `@alpha` or `@beta` +declarations by adding them to the list. + +**Possible values:** `"@internal"`, `"@alpha"`, `"@beta"`, `"@public"` + ## .d.ts Rollup Section Configures how the .d.ts rollup file will be generated. @@ -746,6 +813,13 @@ for the complete up-to-date table.)_ "logLevel": "warning", "addToApiReportFile": true }, + "ae-internal-mixed-release-tag": { + "logLevel": "warning", + "addToApiReportFile": true + }, + "ae-undocumented": { + "logLevel": "none" + }, "ae-unresolved-inheritdoc-reference": { "logLevel": "warning", "addToApiReportFile": true @@ -753,6 +827,9 @@ for the complete up-to-date table.)_ "ae-unresolved-inheritdoc-base": { "logLevel": "warning", "addToApiReportFile": true + }, + "ae-wrong-input-file-type": { + "logLevel": "error" } }, . . . diff --git a/websites/api-extractor.com/docs/pages/messages/ae-undocumented.md b/websites/api-extractor.com/docs/pages/messages/ae-undocumented.md new file mode 100644 index 000000000..231c57f4f --- /dev/null +++ b/websites/api-extractor.com/docs/pages/messages/ae-undocumented.md @@ -0,0 +1,64 @@ +--- +title: ae-undocumented +--- + +_"Missing documentation for \_\_\_."_ + +## Remarks + +This message is reported when an exported API item does not have a TSDoc doc comment. This helps ensure +that every public API has proper documentation. + +The `ae-undocumented` message is only generated if the API report feature is enabled +(`apiReport.enabled` is `true`). + +Because the API report file already annotates undocumented items with `// (undocumented)`, +the `ae-undocumented` message is not logged by default (its default `logLevel` is `"none"`). + +## How to fix + +Add a TSDoc doc comment to the declaration. For example: + +```ts +/** + * Represents the application state. + * @public + */ +export interface IAppState { + /** + * The current user name. + */ + userName: string; +} +``` + +If you want to see these warnings during your build, add a section like this to your +**api-extractor.json** file: + +```js + "messages": { + "extractorMessageReporting": { + "ae-undocumented": { + "logLevel": "warning" + } + } + } +``` + +To add the messages to your API report file for tracking purposes instead: + +```js + "messages": { + "extractorMessageReporting": { + "ae-undocumented": { + "logLevel": "warning", + "addToApiReportFile": true + } + } + } +``` + +## See also + +- [api-extractor.json config file](../configs/api-extractor_json.md#message-reporting-section) +- [Doc comment syntax](../tsdoc/doc_comment_syntax.md) diff --git a/websites/api-extractor.com/docs/pages/setup/custom_docs.md b/websites/api-extractor.com/docs/pages/setup/custom_docs.md index 60ede997d..4be299abc 100644 --- a/websites/api-extractor.com/docs/pages/setup/custom_docs.md +++ b/websites/api-extractor.com/docs/pages/setup/custom_docs.md @@ -25,7 +25,7 @@ you can simply fork it and modify the code. Here's the basic files you'd want to - [MarkdownDocumenter.ts](https://github.com/microsoft/rushstack/blob/main/apps/api-documenter/src/documenters/MarkdownDocumenter.ts) - This is the main documentation generator that you'd want to study. It illustrates how to traverse the tree of declarations and render each TypeScript construct. Since the - [TSDoc library](https://github.com/microsoft/tsdoc/tree/master/tsdoc) already provides a nice API for representing + [TSDoc library](https://github.com/microsoft/tsdoc/tree/main/tsdoc) already provides a nice API for representing a tree of rich text elements, the `MarkdownDocumenter` class takes the approach of producing a huge TSDoc "comment" representing each page on the web site. It's an unusual approach, but generating TSDoc output from TSDoc input avoids having to transform all the inner content. @@ -56,7 +56,7 @@ and the individual classes such as `ApiClass`, `ApiEnum`, `ApiInterface` have pr One aspect that may not be entirely obvious is how to render TSDoc into some other format besides Markdown. For an example of rendering HTML using React, you might also want to look at -[DocHtmlView.tsx](https://github.com/microsoft/tsdoc/blob/master/playground/src/DocHtmlView.tsx) +[DocHtmlView.tsx](https://github.com/microsoft/tsdoc/blob/main/playground/src/DocHtmlView.tsx) which renders the "HTML" tab for the [TSDoc Playground](https://microsoft.github.io/tsdoc/). If you get stuck or have questions, the API Extractor developers are usually reachable diff --git a/websites/api-extractor.com/docs/pages/setup/generating_docs.md b/websites/api-extractor.com/docs/pages/setup/generating_docs.md index dc23daf92..198b57476 100644 --- a/websites/api-extractor.com/docs/pages/setup/generating_docs.md +++ b/websites/api-extractor.com/docs/pages/setup/generating_docs.md @@ -59,7 +59,7 @@ Here's a typical usage scenario: What do we do with these generated Markdown files? There are various options: -- **GitHub**: If you're using GitHub, you can simply commit them to your master branch in +- **GitHub**: If you're using GitHub, you can simply commit them to your main branch in a "docs" folder, and they will be rendered using GitHub's markdown previewer. Here's an example of how it looks: [node-core-library.md](https://github.com/microsoft/rushstack-websites/blob/main/websites/api.rushstack.io/docs/pages/node-core-library.md) diff --git a/websites/api-extractor.com/docs/pages/tsdoc/declaration_references.md b/websites/api-extractor.com/docs/pages/tsdoc/declaration_references.md index fd7ef1b62..f33dbe318 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/declaration_references.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/declaration_references.md @@ -9,7 +9,7 @@ It could be part of a merged declaration or an overloaded function. The TSDoc syntax provides a special "**declaration reference**" notation for unambiguously identifying declarations in all these situations. (This aspect of TSDoc is still evolving; it is tracked by [RFC #9](https://github.com/microsoft/tsdoc/issues/9). The current spec is outlined in -[code-snippets/DeclarationReferences.ts](https://github.com/microsoft/tsdoc/blob/master/spec/code-snippets/DeclarationReferences.ts).) +[code-snippets/DeclarationReferences.ts](https://github.com/microsoft/tsdoc/blob/main/spec/code-snippets/DeclarationReferences.ts).) ## Syntax Examples diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_alpha.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_alpha.md index a22c78a83..15a5b6bbf 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_alpha.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_alpha.md @@ -4,7 +4,7 @@ title: '@alpha' **Tag type:** modifier -**TSDoc standardization:** [discretionary](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [discretionary](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) The `@alpha` modifier is one of the four **release tags**. It indicates that an API item is eventually intended to be public, but currently is in an early stage of development. Third parties should not use "alpha" APIs. diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_beta.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_beta.md index 5f8c2b3de..25b1bbfb3 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_beta.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_beta.md @@ -4,7 +4,7 @@ title: '@beta' **Tag type:** modifier -**TSDoc standardization:** [discretionary](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [discretionary](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) The `@beta` modifier is one of the four **release tags**. It indicates that an API item has been released as a preview or for experimental purposes. Third parties are encouraged to try it and provide feedback. However, diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_defaultvalue.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_defaultvalue.md index d46c763bd..6b1394e14 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_defaultvalue.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_defaultvalue.md @@ -4,7 +4,7 @@ title: '@defaultValue' **Tag type:** block tag -**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) This tag is used to document the default value for a field or property, if a value is not assigned explicitly. This tag should only be used with fields or properties that are members of a class or interface. diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_deprecated.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_deprecated.md index a5f871ca5..254374041 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_deprecated.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_deprecated.md @@ -4,7 +4,7 @@ title: '@deprecated' **Tag type:** block tag -**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) The `@deprecated` tag indicates that an API item is no longer supported and may be removed in a future release. It should be followed by a sentence describing the recommended alternative. (This is optional in JSDoc, diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_eventproperty.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_eventproperty.md index 9e8a4b20b..7bc5bddcd 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_eventproperty.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_eventproperty.md @@ -4,7 +4,7 @@ title: '@eventProperty' **Tag type:** modifier -**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) When applied to a class or interface property, this indicates that the property returns an event object that event handlers can be attached to. The event-handling diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_example.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_example.md index 65b10048a..26fd8f334 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_example.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_example.md @@ -4,7 +4,7 @@ title: '@example' **Tag type:** block tag -**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) Indicates a documentation section that should be presented as an example illustrating how to use the API. It may include a code sample. diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_inheritdoc.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_inheritdoc.md index 6c49912d7..35cf78d21 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_inheritdoc.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_inheritdoc.md @@ -4,7 +4,7 @@ title: '{@inheritDoc}' **Tag type:** inline tag -**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) **Syntax:** diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_internal.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_internal.md index 7d7586c4c..3c9210af2 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_internal.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_internal.md @@ -4,7 +4,7 @@ title: '@internal' **Tag type:** modifier -**TSDoc standardization:** [discretionary](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [discretionary](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) The `@internal` modifier is one of the four **release tags**. It indicates that an API item is meant only for usage by other NPM packages from the same maintainer. Third parties should never use "internal" APIs. To emphasize this, diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_link.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_link.md index ee8b72204..1e83a7057 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_link.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_link.md @@ -4,7 +4,7 @@ title: '{@link}' **Tag type:** inline tag -**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) **Syntax:** diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_override.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_override.md index 7e622f145..c5a541592 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_override.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_override.md @@ -4,7 +4,7 @@ title: '@override' **Tag type:** modifier -**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) The `@override` modifier has similar semantics to the `override` keyword in C#. It should only be applied to a member of a class. The `@override` modifier indicates that the member is overriding (i.e. redefining) diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_packagedocumentation.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_packagedocumentation.md index 541dd1b2c..c881a30d4 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_packagedocumentation.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_packagedocumentation.md @@ -4,7 +4,7 @@ title: '@packageDocumentation' **Tag type:** modifier -**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) This tag identifies the doc comment that describes an entire NPM package (as opposed to an individual declaration that is exported by the package). API Documenter will display the `@packageDocumentation` content on the page diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_param.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_param.md index 5537d82cb..08e565321 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_param.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_param.md @@ -4,7 +4,7 @@ title: '@param' **Tag type:** block tag -**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) **Syntax:** diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_privateremarks.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_privateremarks.md index e464ae870..b0642e3b5 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_privateremarks.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_privateremarks.md @@ -4,7 +4,7 @@ title: '@privateRemarks' **Tag type:** block tag -**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) The `@privateRemarks` tag designates additional documentation content that is not intended for a public audience. Being a block tag, `@privateRemarks` introduces a TSDoc section that contains all comment text up until the diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_public.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_public.md index 26c7477af..b19f380a4 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_public.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_public.md @@ -4,7 +4,7 @@ title: '@public' **Tag type:** modifier -**TSDoc standardization:** [discretionary](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [discretionary](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) The `@public` modifier is one of the four **release tags**. It indicates that an API item has been officially released, and is now part of the supported contract for a package. If the [SemVer](https://semver.org/) versioning diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_readonly.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_readonly.md index 8855ac0cc..f8555aa0e 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_readonly.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_readonly.md @@ -4,7 +4,7 @@ title: '@readonly' **Tag type:** modifier -**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) This modifier tag is used with a property of a class or interface. It indicates that the property should be documented as being read-only, even if the type signature indicates otherwise. diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_remarks.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_remarks.md index 43111e8b1..bfb15ecc1 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_remarks.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_remarks.md @@ -4,7 +4,7 @@ title: '@remarks' **Tag type:** block tag -**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) The main documentation for an API item is separated into a brief "summary" section, optionally followed by a more detailed "remarks" section. On a documentation web site, index pages (e.g. showing members of a class) diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_returns.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_returns.md index a31653f00..2e66f2e9f 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_returns.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_returns.md @@ -4,7 +4,7 @@ title: '@returns' **Tag type:** block tag -**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) The `@returns` tag is used to document the return value of a function or method parameter. Being a block tag, `@returns` introduces a TSDoc section that contains all comment text up until the next block tag. diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_sealed.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_sealed.md index 58825a3e0..e4851d82a 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_sealed.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_sealed.md @@ -4,7 +4,7 @@ title: '@sealed' **Tag type:** modifier -**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) The `@sealed` modifier has similar semantics to the `sealed` keyword in C# or `final` keyword in Java. It should only be applied to a class or a member of a class. diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_typeparam.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_typeparam.md index d976ed12e..4f2b6a30b 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_typeparam.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_typeparam.md @@ -4,7 +4,7 @@ title: '@typeParam' **Tag type:** block tag -**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [core](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) **Syntax:** diff --git a/websites/api-extractor.com/docs/pages/tsdoc/tag_virtual.md b/websites/api-extractor.com/docs/pages/tsdoc/tag_virtual.md index c87fe5064..afcc9d8da 100644 --- a/websites/api-extractor.com/docs/pages/tsdoc/tag_virtual.md +++ b/websites/api-extractor.com/docs/pages/tsdoc/tag_virtual.md @@ -4,7 +4,7 @@ title: '@virtual' **Tag type:** modifier -**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/master/tsdoc/src/details/Standardization.ts) +**TSDoc standardization:** [extended](https://github.com/microsoft/tsdoc/blob/main/tsdoc/src/details/Standardization.ts) The `@virtual` modifier has similar semantics to the `virtual` keyword in C#. It should only be applied to a member of a class. It indicates that the member may be overridden (i.e. redefined) by a corresponding member diff --git a/websites/api-extractor.com/sidebars.js b/websites/api-extractor.com/sidebars.js index 205a23625..5afc6659c 100644 --- a/websites/api-extractor.com/sidebars.js +++ b/websites/api-extractor.com/sidebars.js @@ -87,6 +87,7 @@ const sidebars = { 'pages/messages/ae-preapproved-bad-release-tag', 'pages/messages/ae-preapproved-unsupported-type', 'pages/messages/ae-setter-with-docs', + 'pages/messages/ae-undocumented', 'pages/messages/ae-unresolved-inheritdoc-base', 'pages/messages/ae-unresolved-inheritdoc-reference', 'pages/messages/ae-unresolved-link', diff --git a/websites/heft.rushstack.io/docs/pages/advanced/authoring-plugins.md b/websites/heft.rushstack.io/docs/pages/advanced/authoring-plugins.md new file mode 100644 index 000000000..48ecc0298 --- /dev/null +++ b/websites/heft.rushstack.io/docs/pages/advanced/authoring-plugins.md @@ -0,0 +1,343 @@ +--- +title: Authoring plugins +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Heft is designed to be extensible. If the [official plugins](../plugins/package_index.md) don't cover your +needs, you can create your own Heft plugin package. This page explains how to create a task plugin, which +is the most common kind of plugin. + +> For quick prototyping, you may want to start with the [Run script plugin](../plugins/run-script.md) instead. +> That approach lets you run an arbitrary script as a Heft task without creating a full plugin package. However, +> for production use, a proper plugin package is recommended because it provides TypeScript type safety, proper +> ESLint validation, and a better developer experience. + +## Plugin concepts + +Before you begin, make sure you're familiar with the key concepts from the +[Heft architecture](../intro/architecture.md) page: + +- A **task plugin** implements `IHeftTaskPlugin` and provides its behavior via the task session hooks +- A **lifecycle plugin** implements `IHeftLifecyclePlugin` and provides general functionality not specific to any task +- A **plugin manifest** (`heft-plugin.json`) describes available plugins, their options, and CLI parameters +- Plugin packages use the NPM naming pattern `heft-____-plugin` or `heft-____-plugins` + +## Step 1: Create the package + +Create a new NPM package for your plugin. The key requirements are: + +- Add `@rushstack/heft` as a `peerDependency` (not a regular dependency) +- Export a `heft-plugin.json` manifest file from the package root + +**package.json** + +```json +{ + "name": "heft-my-plugin", + "version": "1.0.0", + "description": "A Heft plugin for ...", + "main": "./lib-commonjs/index.js", + "peerDependencies": { + "@rushstack/heft": "^1.2.2" + }, + "devDependencies": { + "@rushstack/heft": "^1.2.2" + }, + "exports": { + "./lib/*": { + "types": "./lib-dts/*.d.ts", + "node": "./lib-commonjs/*.js", + "import": "./lib-esm/*.js", + "require": "./lib-commonjs/*.js" + }, + "./heft-plugin.json": "./heft-plugin.json", + "./package.json": "./package.json" + } +} +``` + +> **Important:** It is essential that `"./heft-plugin.json": "./heft-plugin.json"` is included in +> the `"exports"` field so that Heft can locate the plugin manifest. + +## Step 2: Create the plugin manifest + +Create a **heft-plugin.json** file in your package root. This manifest tells Heft about the plugins +provided by your package. The file must conform to the +[heft-plugin.schema.json](https://developer.microsoft.com/json-schemas/heft/v0/heft-plugin.schema.json) schema. + +**heft-plugin.json** + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft-plugin.schema.json", + + "taskPlugins": [ + { + "pluginName": "my-plugin", + "entryPoint": "./lib-commonjs/MyPlugin" + } + ] +} +``` + +### Manifest fields + +The plugin manifest supports these fields for each plugin: + +| Field | Required | Description | +| :---- | :------: | :---------- | +| `pluginName` | yes | A unique kebab-case name for the plugin (e.g. `"my-plugin"`) | +| `entryPoint` | yes | Path to the compiled JS module that exports the plugin class (resolved relative to the package folder) | +| `optionsSchema` | no | Path to a JSON Schema file that validates `options` provided in **heft.json** | +| `parameterScope` | no | A scope prefix for CLI parameters (defaults to the plugin name). If multiple plugins define a `--verbose` parameter, they can be disambiguated as `--my-scope:verbose`. | +| `parameters` | no | An array of CLI parameter definitions (see [Defining CLI parameters](#defining-cli-parameters) below) | + +## Step 3: Implement the plugin class + +Create a TypeScript file that exports a class implementing `IHeftTaskPlugin`. The class must have an +`apply()` method that receives the task session and Heft configuration. + +**src/MyPlugin.ts** + +```ts +import type { + HeftConfiguration, + IHeftTaskSession, + IHeftTaskPlugin, + IHeftTaskRunHookOptions +} from '@rushstack/heft'; + +const PLUGIN_NAME: 'my-plugin' = 'my-plugin'; + +export default class MyPlugin implements IHeftTaskPlugin { + public apply(taskSession: IHeftTaskSession, heftConfiguration: HeftConfiguration): void { + taskSession.hooks.run.tapPromise(PLUGIN_NAME, async (runOptions: IHeftTaskRunHookOptions) => { + const { logger } = taskSession; + + logger.terminal.writeLine('My plugin is running!'); + + // Your plugin logic here... + }); + } +} +``` + +The `apply()` method is called once when the plugin is loaded. Inside it, you "tap" into one or more +hooks to register your callbacks. + +### Available task hooks + +The `taskSession.hooks` object provides these hooks: + +| Hook | Description | +| :--- | :---------- | +| `run` | Called when the task executes during a normal build. Use `run.tapPromise(name, callback)` to register. | +| `runIncremental` | Called instead of `run` during watch mode, if provided. Receives additional APIs for incremental builds. | +| `registerFileOperations` | Called once before the first `run` or `runIncremental` to register dynamic file copy/delete operations. | + +### Using the task session + +The `IHeftTaskSession` provides access to several useful properties: + +| Property | Description | +| :------- | :---------- | +| `taskName` | The name of the task as defined in **heft.json** | +| `hooks` | The hooks available for the plugin to tap (described above) | +| `parameters` | CLI parameters (including custom ones defined in the manifest) | +| `parsedCommandLine` | The command line used to invoke Heft | +| `tempFolderPath` | A unique temp folder for the task, cleaned with `--clean` | +| `logger` | A scoped logger prefixed with `[:]` | + +### Watch mode support + +To support Heft's watch mode, tap the `runIncremental` hook. This hook provides additional APIs +for efficient incremental builds: + +```ts +taskSession.hooks.runIncremental.tapPromise( + PLUGIN_NAME, + async (options: IHeftTaskRunIncrementalHookOptions) => { + // Watch for changes to specific files + const changedFiles = await options.watchGlobAsync('src/**/*.json'); + + // Process only changed files + for (const [filePath, changeInfo] of changedFiles) { + logger.terminal.writeLine(`Processing changed file: ${filePath}`); + } + } +); +``` + +## Step 4: Use the plugin + +Once your plugin is published (or linked locally), consumers can load it in their **heft.json** config file: + +**config/heft.json** + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "phasesByName": { + "build": { + "tasksByName": { + "my-task": { + "taskPlugin": { + "pluginPackage": "heft-my-plugin", + "pluginName": "my-plugin" + } + } + } + } + } +} +``` + +If the package only provides a single task plugin, the `"pluginName"` can be omitted. + +## Accepting plugin options + +Plugins can accept user-defined options via **heft.json**. To enable this: + +1. Create a JSON Schema file for your options: + + **src/schemas/my-plugin-options.schema.json** + + ```json + { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "additionalProperties": false, + "properties": { + "outputFolder": { + "type": "string", + "description": "The output folder for generated files." + } + }, + "required": ["outputFolder"] + } + ``` + +2. Reference the schema from your plugin manifest: + + **heft-plugin.json** + + ```json + { + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft-plugin.schema.json", + "taskPlugins": [ + { + "pluginName": "my-plugin", + "entryPoint": "./lib-commonjs/MyPlugin", + "optionsSchema": "./lib-commonjs/schemas/my-plugin-options.schema.json" + } + ] + } + ``` + +3. Consumers specify the options in **heft.json**: + + ```json + { + "tasksByName": { + "my-task": { + "taskPlugin": { + "pluginPackage": "heft-my-plugin", + "options": { + "outputFolder": "dist/generated" + } + } + } + } + } + ``` + +The options are validated against your schema at load time, providing clear error messages for +invalid configurations. + +## Defining CLI parameters + +Plugins can define CLI parameters by adding a `parameters` array to the plugin manifest. +These parameters are automatically added to Heft's command line when the plugin is loaded. + +**heft-plugin.json** + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft-plugin.schema.json", + "taskPlugins": [ + { + "pluginName": "my-plugin", + "entryPoint": "./lib-commonjs/MyPlugin", + "parameterScope": "my-plugin", + "parameters": [ + { + "longName": "--output-format", + "parameterKind": "choice", + "description": "Specifies the output format.", + "alternatives": [ + { "name": "json", "description": "Output as JSON" }, + { "name": "yaml", "description": "Output as YAML" } + ], + "defaultValue": "json" + }, + { + "longName": "--verbose", + "parameterKind": "flag", + "description": "Enable verbose logging." + } + ] + } + ] +} +``` + +The supported parameter kinds are: `flag`, `string`, `stringList`, `integer`, `integerList`, +`choice`, and `choiceList`. + +To read the parameter values in your plugin, use `taskSession.parameters`: + +```ts +public apply(taskSession: IHeftTaskSession, heftConfiguration: HeftConfiguration): void { + taskSession.hooks.run.tapPromise(PLUGIN_NAME, async () => { + const verbose = taskSession.parameters.getFlagParameter('--verbose'); + if (verbose.value) { + taskSession.logger.terminal.writeLine('Verbose mode enabled'); + } + }); +} +``` + +## Interacting with other plugins + +A plugin can request access to another plugin within the same phase using the +`requestAccessToPluginByName()` API. This enables plugins to share data via custom accessor hooks. + +```ts +taskSession.requestAccessToPluginByName( + '@rushstack/heft-typescript-plugin', // the package containing the plugin + 'typescript-plugin', // the plugin name + (accessor) => { + // Access hooks or data exposed by the TypeScript plugin + } +); +``` + +## Reference examples + +The best way to learn plugin development is to study the official plugin implementations: + +- [heft-dev-cert-plugin](https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-dev-cert-plugin) — A simple task plugin example +- [heft-jest-plugin](https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-jest-plugin) — A complex plugin with many CLI parameters +- [heft-typescript-plugin](https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-typescript-plugin) — The TypeScript compiler plugin +- [heft-rspack-plugin](https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-rspack-plugin) — A plugin with watch mode support + +## See also + +- [Heft architecture](../intro/architecture.md) — Key concepts and terminology +- [heft.json](../configs/heft_json.md) — Config file reference for loading plugins +- [Run script plugin](../plugins/run-script.md) — A simpler alternative for quick prototyping +- [Plugin package index](../plugins/package_index.md) — List of official plugins +- [API Reference](https://api.rushstack.io/pages/heft/) — Complete Heft API documentation diff --git a/websites/heft.rushstack.io/docs/pages/plugins/isolated-transpile.md b/websites/heft.rushstack.io/docs/pages/plugins/isolated-transpile.md new file mode 100644 index 000000000..988a79270 --- /dev/null +++ b/websites/heft.rushstack.io/docs/pages/plugins/isolated-transpile.md @@ -0,0 +1,162 @@ +--- +title: Isolated transpile plugin (SWC) +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + +| | | +| --- | --- | +| **Plugin package:** | [@rushstack/heft-isolated-typescript-transpile-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-isolated-typescript-transpile-plugin) | +| **Plugin name:** | [swc-isolated-transpile-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-isolated-typescript-transpile-plugin/heft-plugin.json) implemented by [SwcIsolatedTranspilePlugin.ts](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-isolated-typescript-transpile-plugin/src/SwcIsolatedTranspilePlugin.ts) | +| **Plugin config file:** | (none) | +| **heft.json options:** | [swc-isolated-transpile-plugin.schema.json](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-isolated-typescript-transpile-plugin/src/schemas/swc-isolated-transpile-plugin.schema.json) | + + +This plugin uses [SWC](https://swc.rs/) to transpile TypeScript source files into JavaScript, as an +alternative to the standard [TypeScript plugin](./typescript.md). SWC is a high-performance transpiler +written in Rust that can be significantly faster than the TypeScript compiler for the transpilation step. + +## When to use it + +The isolated transpile plugin is useful when you want to speed up the JavaScript emit step of your build. +In a typical TypeScript build, the TypeScript compiler both type-checks your code _and_ transpiles it to +JavaScript. These two tasks can be separated: + +- **Type checking** remains handled by the standard [TypeScript plugin](./typescript.md) with + `emitDeclarationOnly: true` in your **tsconfig.json** +- **Transpilation** is handled by this plugin using SWC, which processes each file independently + (hence "isolated transpile") + +Because SWC processes files in isolation, it cannot perform cross-file type checking or certain +TypeScript-specific emit transformations that require type information. However, for many projects +the performance benefit is substantial. + +> **Note:** This plugin requires `@rushstack/heft-typescript-plugin` as a peer dependency, since it +> reuses the TypeScript plugin's tsconfig loading infrastructure. + +## package.json dependencies + +You'll need to add the plugin package to your project: + + + + +```bash +# If you are using Rush, run this shell command in your project folder: +rush add --package @rushstack/heft-isolated-typescript-transpile-plugin --dev +``` + + + + +```bash +# If you are using vanilla NPM, run this shell command in your project folder: +npm install @rushstack/heft-isolated-typescript-transpile-plugin --save-dev +``` + + + + +You must also have `@rushstack/heft-typescript-plugin` installed, since it is a peer dependency. + +## Configuration + +Your [heft.json config file](../configs/heft_json.md) should invoke both the TypeScript plugin +(for type checking and declaration emit) and this plugin (for JavaScript transpilation): + +**<project folder>/config/heft.json** + +```js +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "phasesByName": { + "build": { + "cleanFiles": [ + { "sourcePath": "dist" }, + { "sourcePath": "lib" }, + { "sourcePath": "lib-commonjs" } + ], + "tasksByName": { + "typescript": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft-typescript-plugin" + } + }, + "swc-transpile": { + "taskDependencies": ["typescript"], + "taskPlugin": { + "pluginPackage": "@rushstack/heft-isolated-typescript-transpile-plugin", + "options": { + "emitKinds": [ + { + "outDir": "lib-commonjs", + "formatOverride": "CommonJS", + "targetOverride": "ES2017" + }, + { + "outDir": "lib", + "formatOverride": "ESNext", + "targetOverride": "ES2017" + } + ] + } + } + } + } + } + } +} +``` + +When using this plugin, you should configure the TypeScript plugin to only emit declarations by setting +`"emitDeclarationOnly": true` in your **tsconfig.json**, since the JavaScript output will be produced +by SWC instead. + +## heft.json plugin options + +```js +// JSON Schema: swc-isolated-transpile-plugin.schema.json +"options": { + /** + * (Optional) The path to the tsconfig.json file. If not specified, the default + * tsconfig.json resolution is used. + */ + // "tsConfigPath": "./tsconfig.json", + + /** + * (REQUIRED) An array of emit configurations. Each entry specifies an output + * directory, module format, and target. + */ + "emitKinds": [ + { + /** + * The output directory for the transpiled files, relative to the project folder. + */ + "outDir": "lib-commonjs", + + /** + * The module format for transpiled files. Uses TypeScript's ModuleKind names. + * Supported values: "CommonJS", "ES2015", "ES2020", "ES2022", "ESNext", + * "Node16", "NodeNext", "AMD", "UMD" + */ + "formatOverride": "CommonJS", + + /** + * The target ECMAScript version for transpiled files. Uses TypeScript's + * ScriptTarget names. + * Supported values: "ES3", "ES5", "ES2015", "ES2016", "ES2017", "ES2018", + * "ES2019", "ES2020", "ES2021", "ES2022", "ES2023", "ES2024", "ESNext" + */ + "targetOverride": "ES2017" + } + ] +} +``` + +## See also + +- [TypeScript plugin](./typescript.md) - The standard TypeScript compiler plugin +- [SWC documentation](https://swc.rs/) diff --git a/websites/heft.rushstack.io/docs/pages/plugins/package_index.md b/websites/heft.rushstack.io/docs/pages/plugins/package_index.md index 88d2673ce..96ea5652e 100644 --- a/websites/heft.rushstack.io/docs/pages/plugins/package_index.md +++ b/websites/heft.rushstack.io/docs/pages/plugins/package_index.md @@ -9,7 +9,9 @@ title: Plugin package index | [@rushstack/heft-api-extractor-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-api-extractor-plugin) | [api-extractor-plugin](./api-extractor.md) | | [@rushstack/heft-jest-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-jest-plugin) | [jest-plugin](./jest.md) | | [@rushstack/heft-dev-cert-plugin](https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-dev-cert-plugin) | [trust-dev-certificate-plugin](./dev-cert.md)
[untrust-dev-certificate-plugin](./dev-cert.md) | +| [@rushstack/heft-isolated-typescript-transpile-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-isolated-typescript-transpile-plugin) | [swc-isolated-transpile-plugin](./isolated-transpile.md) | | [@rushstack/heft-lint-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-lint-plugin) | [lint-plugin](./lint.md) | +| [@rushstack/heft-rspack-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-rspack-plugin) | [rspack-plugin](./rspack.md) | | [@rushstack/heft-sass-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-sass-plugin) | [sass-plugin](./sass.md) | | [@rushstack/heft-serverless-stack-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-serverless-stack-plugin) | [serverless-stack-plugin](./serverless-stack.md) | | [@rushstack/heft-storybook-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-storybook-plugin) | [storybook-plugin](./storybook.md) | diff --git a/websites/heft.rushstack.io/docs/pages/plugins/rspack.md b/websites/heft.rushstack.io/docs/pages/plugins/rspack.md new file mode 100644 index 000000000..0b9705d05 --- /dev/null +++ b/websites/heft.rushstack.io/docs/pages/plugins/rspack.md @@ -0,0 +1,183 @@ +--- +title: Rspack plugin +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + +| | | +| --- | --- | +| **Plugin package:** | [@rushstack/heft-rspack-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-rspack-plugin) | +| **Plugin name:** | [rspack-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-rspack-plugin/heft-plugin.json) implemented by [RspackPlugin.ts](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-rspack-plugin/src/RspackPlugin.ts) | +| **Plugin config file:** | (none) | +| **heft.json options:** | [IRspackPluginOptions](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-rspack-plugin/src/RspackPlugin.ts) | + + +This task invokes [Rspack](https://rspack.dev/) to produce application bundles. Rspack is a high-performance +JavaScript bundler written in Rust that is designed to be largely compatible with the Webpack ecosystem. It +provides features such as: + +- Combining many small .js files into one large file for faster downloads +- Improving performance by applying various compiler optimizations such as inlining and dead code elimination ("tree shaking") +- Compressing and obfuscating code by shortening identifiers, using built-in minification by default +- Converting assets such as .css or even images into embedded JavaScript objects +- Significantly faster build times compared to Webpack, thanks to its Rust-based implementation + +Like the [Webpack plugin](./webpack.md), Heft invokes the TypeScript compiler to produce intermediate .js files +which become the inputs for the Rspack bundler. This reduces the number of compiler passes, and avoids the +need for compiler optimizations to be reimplemented multiple times for different contexts. + +## When to use it + +Rspack should be used for projects whose output is a web application bundle, particularly when build +performance is a priority. Because Rspack is designed to be compatible with most Webpack loaders and +plugins, it can often be adopted as a drop-in replacement for Webpack with minimal configuration changes. + +Rspack can also be used to bundle Node.js tools or services, however this is less common. + +## package.json dependencies + +You'll need to add the plugin package to your project: + + + + +```bash +# If you are using Rush, run this shell command in your project folder: +rush add --package @rushstack/heft-rspack-plugin --dev +``` + + + + +```bash +# If you are using vanilla NPM, run this shell command in your project folder: +npm install @rushstack/heft-rspack-plugin --save-dev +``` + + + + +The `@rushstack/heft-rspack-plugin` package has a peer dependency on `@rspack/core`. You must add this +dependency as well: + + + + +```bash +# If you are using Rush, run this shell command in your project folder: +rush add --package @rspack/core --dev +``` + + + + +```bash +# If you are using vanilla NPM, run this shell command in your project folder: +npm install @rspack/core --save-dev +``` + + + + +## Configuration + +Your [heft.json config file](../configs/heft_json.md) could invoke Rspack like in this example: + +**<project folder>/config/heft.json** + +```js +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "aliasesByName": { + "start": { + "actionName": "build-watch", + "defaultParameters": ["--serve"] + } + }, + + "phasesByName": { + "build": { + "cleanFiles": [ + { "sourcePath": "dist" }, + { "sourcePath": "lib" }, + { "sourcePath": "lib-commonjs" } + ], + "tasksByName": { + "typescript": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft-typescript-plugin" + } + }, + "rspack": { + "taskDependencies": ["typescript"], + "taskPlugin": { + "pluginPackage": "@rushstack/heft-rspack-plugin" + } + } + } + } + } +} +``` + +Next, create an **rspack.config.mjs** file in your project folder. Here is a rudimentary example: + +**<project folder>/rspack.config.mjs** + +```js +import * as path from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +/** @type {import('@rspack/core').Configuration} */ +const rspackConfig = { + mode: 'development', + resolve: { + // Note: Do not specify '.ts' or '.tsx' here. Heft invokes Rspack as a post-process after the compiler. + extensions: ['.js', '.jsx', '.json'] + }, + entry: { + app: path.join(__dirname, 'lib', 'index.js') + }, + output: { + path: path.join(__dirname, 'dist'), + filename: '[name]_[contenthash].js' + } +}; + +export default rspackConfig; +``` + +If you want to use a slightly different configuration when developing using the localhost dev server, +you can optionally create a second file called **rspack.dev.config.js**. + +To start the localhost dev server, use the `heft start` command, which conventionally is defined as an alias +for `heft build-watch --serve` (see `aliasesByName` above). Whenever you save a change to a source file, +Heft's watch mode will recompile your project, then Rspack's dev server should refresh your +web browser with the latest build of the app. + +### Interaction with Jest + +Rspack works best with the `esnext` module format, whereas Jest must use the `commonjs` module format because +its tests are executed by the Node.js runtime. In order to use Rspack and Jest together, you will need +to emit both module formats. This is described in the [Jest plugin](../plugins/jest.md) section. + +## CLI parameters + +[heft-rspack-plugin/heft-plugin.json](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-rspack-plugin/heft-plugin.json) defines these parameters: + +``` + --serve + Start a local web server for testing purposes using + @rspack/dev-server. This parameter is only available + when running in watch mode. +``` + +## See also + +- [Rspack documentation](https://rspack.dev/) +- [Webpack plugin](./webpack.md) - the equivalent plugin for Webpack diff --git a/websites/heft.rushstack.io/i18n/zh-cn/docusaurus-plugin-content-docs/current/pages/advanced/authoring-plugins.md b/websites/heft.rushstack.io/i18n/zh-cn/docusaurus-plugin-content-docs/current/pages/advanced/authoring-plugins.md new file mode 100644 index 000000000..d6824752b --- /dev/null +++ b/websites/heft.rushstack.io/i18n/zh-cn/docusaurus-plugin-content-docs/current/pages/advanced/authoring-plugins.md @@ -0,0 +1,343 @@ +--- +title: Authoring plugins +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +Heft is designed to be extensible. If the [official plugins](../plugins/package_index.md) don't cover your +needs, you can create your own Heft plugin package. This page explains how to create a task plugin, which +is the most common kind of plugin. + +> For quick prototyping, you may want to start with the [Run script plugin](../plugins/run-script.md) instead. +> That approach lets you run an arbitrary script as a Heft task without creating a full plugin package. However, +> for production use, a proper plugin package is recommended because it provides TypeScript type safety, proper +> ESLint validation, and a better developer experience. + +## Plugin concepts + +Before you begin, make sure you're familiar with the key concepts from the +[Heft architecture](../intro/architecture.md) page: + +- A **task plugin** implements `IHeftTaskPlugin` and provides its behavior via the task session hooks +- A **lifecycle plugin** implements `IHeftLifecyclePlugin` and provides general functionality not specific to any task +- A **plugin manifest** (`heft-plugin.json`) describes available plugins, their options, and CLI parameters +- Plugin packages use the NPM naming pattern `heft-____-plugin` or `heft-____-plugins` + +## Step 1: Create the package + +Create a new NPM package for your plugin. The key requirements are: + +- Add `@rushstack/heft` as a `peerDependency` (not a regular dependency) +- Export a `heft-plugin.json` manifest file from the package root + +**package.json** + +```json +{ + "name": "heft-my-plugin", + "version": "1.0.0", + "description": "A Heft plugin for ...", + "main": "./lib-commonjs/index.js", + "peerDependencies": { + "@rushstack/heft": "^1.2.2" + }, + "devDependencies": { + "@rushstack/heft": "^1.2.2" + }, + "exports": { + "./lib/*": { + "types": "./lib-dts/*.d.ts", + "node": "./lib-commonjs/*.js", + "import": "./lib-esm/*.js", + "require": "./lib-commonjs/*.js" + }, + "./heft-plugin.json": "./heft-plugin.json", + "./package.json": "./package.json" + } +} +``` + +> **Important:** It is essential that `"./heft-plugin.json": "./heft-plugin.json"` is included in +> the `"exports"` field so that Heft can locate the plugin manifest. + +## Step 2: Create the plugin manifest + +Create a **heft-plugin.json** file in your package root. This manifest tells Heft about the plugins +provided by your package. The file must conform to the +[heft-plugin.schema.json](https://developer.microsoft.com/json-schemas/heft/v0/heft-plugin.schema.json) schema. + +**heft-plugin.json** + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft-plugin.schema.json", + + "taskPlugins": [ + { + "pluginName": "my-plugin", + "entryPoint": "./lib-commonjs/MyPlugin" + } + ] +} +``` + +### Manifest fields + +The plugin manifest supports these fields for each plugin: + +| Field | Required | Description | +| :--------------- | :------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `pluginName` | yes | A unique kebab-case name for the plugin (e.g. `"my-plugin"`) | +| `entryPoint` | yes | Path to the compiled JS module that exports the plugin class (resolved relative to the package folder) | +| `optionsSchema` | no | Path to a JSON Schema file that validates `options` provided in **heft.json** | +| `parameterScope` | no | A scope prefix for CLI parameters (defaults to the plugin name). If multiple plugins define a `--verbose` parameter, they can be disambiguated as `--my-scope:verbose`. | +| `parameters` | no | An array of CLI parameter definitions (see [Defining CLI parameters](#defining-cli-parameters) below) | + +## Step 3: Implement the plugin class + +Create a TypeScript file that exports a class implementing `IHeftTaskPlugin`. The class must have an +`apply()` method that receives the task session and Heft configuration. + +**src/MyPlugin.ts** + +```ts +import type { + HeftConfiguration, + IHeftTaskSession, + IHeftTaskPlugin, + IHeftTaskRunHookOptions +} from '@rushstack/heft'; + +const PLUGIN_NAME: 'my-plugin' = 'my-plugin'; + +export default class MyPlugin implements IHeftTaskPlugin { + public apply(taskSession: IHeftTaskSession, heftConfiguration: HeftConfiguration): void { + taskSession.hooks.run.tapPromise(PLUGIN_NAME, async (runOptions: IHeftTaskRunHookOptions) => { + const { logger } = taskSession; + + logger.terminal.writeLine('My plugin is running!'); + + // Your plugin logic here... + }); + } +} +``` + +The `apply()` method is called once when the plugin is loaded. Inside it, you "tap" into one or more +hooks to register your callbacks. + +### Available task hooks + +The `taskSession.hooks` object provides these hooks: + +| Hook | Description | +| :----------------------- | :------------------------------------------------------------------------------------------------------- | +| `run` | Called when the task executes during a normal build. Use `run.tapPromise(name, callback)` to register. | +| `runIncremental` | Called instead of `run` during watch mode, if provided. Receives additional APIs for incremental builds. | +| `registerFileOperations` | Called once before the first `run` or `runIncremental` to register dynamic file copy/delete operations. | + +### Using the task session + +The `IHeftTaskSession` provides access to several useful properties: + +| Property | Description | +| :------------------ | :------------------------------------------------------------- | +| `taskName` | The name of the task as defined in **heft.json** | +| `hooks` | The hooks available for the plugin to tap (described above) | +| `parameters` | CLI parameters (including custom ones defined in the manifest) | +| `parsedCommandLine` | The command line used to invoke Heft | +| `tempFolderPath` | A unique temp folder for the task, cleaned with `--clean` | +| `logger` | A scoped logger prefixed with `[:]` | + +### Watch mode support + +To support Heft's watch mode, tap the `runIncremental` hook. This hook provides additional APIs +for efficient incremental builds: + +```ts +taskSession.hooks.runIncremental.tapPromise( + PLUGIN_NAME, + async (options: IHeftTaskRunIncrementalHookOptions) => { + // Watch for changes to specific files + const changedFiles = await options.watchGlobAsync('src/**/*.json'); + + // Process only changed files + for (const [filePath, changeInfo] of changedFiles) { + logger.terminal.writeLine(`Processing changed file: ${filePath}`); + } + } +); +``` + +## Step 4: Use the plugin + +Once your plugin is published (or linked locally), consumers can load it in their **heft.json** config file: + +**config/heft.json** + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "phasesByName": { + "build": { + "tasksByName": { + "my-task": { + "taskPlugin": { + "pluginPackage": "heft-my-plugin", + "pluginName": "my-plugin" + } + } + } + } + } +} +``` + +If the package only provides a single task plugin, the `"pluginName"` can be omitted. + +## Accepting plugin options + +Plugins can accept user-defined options via **heft.json**. To enable this: + +1. Create a JSON Schema file for your options: + + **src/schemas/my-plugin-options.schema.json** + + ```json + { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "additionalProperties": false, + "properties": { + "outputFolder": { + "type": "string", + "description": "The output folder for generated files." + } + }, + "required": ["outputFolder"] + } + ``` + +2. Reference the schema from your plugin manifest: + + **heft-plugin.json** + + ```json + { + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft-plugin.schema.json", + "taskPlugins": [ + { + "pluginName": "my-plugin", + "entryPoint": "./lib-commonjs/MyPlugin", + "optionsSchema": "./lib-commonjs/schemas/my-plugin-options.schema.json" + } + ] + } + ``` + +3. Consumers specify the options in **heft.json**: + + ```json + { + "tasksByName": { + "my-task": { + "taskPlugin": { + "pluginPackage": "heft-my-plugin", + "options": { + "outputFolder": "dist/generated" + } + } + } + } + } + ``` + +The options are validated against your schema at load time, providing clear error messages for +invalid configurations. + +## Defining CLI parameters + +Plugins can define CLI parameters by adding a `parameters` array to the plugin manifest. +These parameters are automatically added to Heft's command line when the plugin is loaded. + +**heft-plugin.json** + +```json +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft-plugin.schema.json", + "taskPlugins": [ + { + "pluginName": "my-plugin", + "entryPoint": "./lib-commonjs/MyPlugin", + "parameterScope": "my-plugin", + "parameters": [ + { + "longName": "--output-format", + "parameterKind": "choice", + "description": "Specifies the output format.", + "alternatives": [ + { "name": "json", "description": "Output as JSON" }, + { "name": "yaml", "description": "Output as YAML" } + ], + "defaultValue": "json" + }, + { + "longName": "--verbose", + "parameterKind": "flag", + "description": "Enable verbose logging." + } + ] + } + ] +} +``` + +The supported parameter kinds are: `flag`, `string`, `stringList`, `integer`, `integerList`, +`choice`, and `choiceList`. + +To read the parameter values in your plugin, use `taskSession.parameters`: + +```ts +public apply(taskSession: IHeftTaskSession, heftConfiguration: HeftConfiguration): void { + taskSession.hooks.run.tapPromise(PLUGIN_NAME, async () => { + const verbose = taskSession.parameters.getFlagParameter('--verbose'); + if (verbose.value) { + taskSession.logger.terminal.writeLine('Verbose mode enabled'); + } + }); +} +``` + +## Interacting with other plugins + +A plugin can request access to another plugin within the same phase using the +`requestAccessToPluginByName()` API. This enables plugins to share data via custom accessor hooks. + +```ts +taskSession.requestAccessToPluginByName( + '@rushstack/heft-typescript-plugin', // the package containing the plugin + 'typescript-plugin', // the plugin name + (accessor) => { + // Access hooks or data exposed by the TypeScript plugin + } +); +``` + +## Reference examples + +The best way to learn plugin development is to study the official plugin implementations: + +- [heft-dev-cert-plugin](https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-dev-cert-plugin) — A simple task plugin example +- [heft-jest-plugin](https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-jest-plugin) — A complex plugin with many CLI parameters +- [heft-typescript-plugin](https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-typescript-plugin) — The TypeScript compiler plugin +- [heft-rspack-plugin](https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-rspack-plugin) — A plugin with watch mode support + +## See also + +- [Heft architecture](../intro/architecture.md) — Key concepts and terminology +- [heft.json](../configs/heft_json.md) — Config file reference for loading plugins +- [Run script plugin](../plugins/run-script.md) — A simpler alternative for quick prototyping +- [Plugin package index](../plugins/package_index.md) — List of official plugins +- [API Reference](https://api.rushstack.io/pages/heft/) — Complete Heft API documentation diff --git a/websites/heft.rushstack.io/i18n/zh-cn/docusaurus-plugin-content-docs/current/pages/plugins/isolated-transpile.md b/websites/heft.rushstack.io/i18n/zh-cn/docusaurus-plugin-content-docs/current/pages/plugins/isolated-transpile.md new file mode 100644 index 000000000..988a79270 --- /dev/null +++ b/websites/heft.rushstack.io/i18n/zh-cn/docusaurus-plugin-content-docs/current/pages/plugins/isolated-transpile.md @@ -0,0 +1,162 @@ +--- +title: Isolated transpile plugin (SWC) +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + +| | | +| --- | --- | +| **Plugin package:** | [@rushstack/heft-isolated-typescript-transpile-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-isolated-typescript-transpile-plugin) | +| **Plugin name:** | [swc-isolated-transpile-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-isolated-typescript-transpile-plugin/heft-plugin.json) implemented by [SwcIsolatedTranspilePlugin.ts](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-isolated-typescript-transpile-plugin/src/SwcIsolatedTranspilePlugin.ts) | +| **Plugin config file:** | (none) | +| **heft.json options:** | [swc-isolated-transpile-plugin.schema.json](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-isolated-typescript-transpile-plugin/src/schemas/swc-isolated-transpile-plugin.schema.json) | + + +This plugin uses [SWC](https://swc.rs/) to transpile TypeScript source files into JavaScript, as an +alternative to the standard [TypeScript plugin](./typescript.md). SWC is a high-performance transpiler +written in Rust that can be significantly faster than the TypeScript compiler for the transpilation step. + +## When to use it + +The isolated transpile plugin is useful when you want to speed up the JavaScript emit step of your build. +In a typical TypeScript build, the TypeScript compiler both type-checks your code _and_ transpiles it to +JavaScript. These two tasks can be separated: + +- **Type checking** remains handled by the standard [TypeScript plugin](./typescript.md) with + `emitDeclarationOnly: true` in your **tsconfig.json** +- **Transpilation** is handled by this plugin using SWC, which processes each file independently + (hence "isolated transpile") + +Because SWC processes files in isolation, it cannot perform cross-file type checking or certain +TypeScript-specific emit transformations that require type information. However, for many projects +the performance benefit is substantial. + +> **Note:** This plugin requires `@rushstack/heft-typescript-plugin` as a peer dependency, since it +> reuses the TypeScript plugin's tsconfig loading infrastructure. + +## package.json dependencies + +You'll need to add the plugin package to your project: + + + + +```bash +# If you are using Rush, run this shell command in your project folder: +rush add --package @rushstack/heft-isolated-typescript-transpile-plugin --dev +``` + + + + +```bash +# If you are using vanilla NPM, run this shell command in your project folder: +npm install @rushstack/heft-isolated-typescript-transpile-plugin --save-dev +``` + + + + +You must also have `@rushstack/heft-typescript-plugin` installed, since it is a peer dependency. + +## Configuration + +Your [heft.json config file](../configs/heft_json.md) should invoke both the TypeScript plugin +(for type checking and declaration emit) and this plugin (for JavaScript transpilation): + +**<project folder>/config/heft.json** + +```js +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "phasesByName": { + "build": { + "cleanFiles": [ + { "sourcePath": "dist" }, + { "sourcePath": "lib" }, + { "sourcePath": "lib-commonjs" } + ], + "tasksByName": { + "typescript": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft-typescript-plugin" + } + }, + "swc-transpile": { + "taskDependencies": ["typescript"], + "taskPlugin": { + "pluginPackage": "@rushstack/heft-isolated-typescript-transpile-plugin", + "options": { + "emitKinds": [ + { + "outDir": "lib-commonjs", + "formatOverride": "CommonJS", + "targetOverride": "ES2017" + }, + { + "outDir": "lib", + "formatOverride": "ESNext", + "targetOverride": "ES2017" + } + ] + } + } + } + } + } + } +} +``` + +When using this plugin, you should configure the TypeScript plugin to only emit declarations by setting +`"emitDeclarationOnly": true` in your **tsconfig.json**, since the JavaScript output will be produced +by SWC instead. + +## heft.json plugin options + +```js +// JSON Schema: swc-isolated-transpile-plugin.schema.json +"options": { + /** + * (Optional) The path to the tsconfig.json file. If not specified, the default + * tsconfig.json resolution is used. + */ + // "tsConfigPath": "./tsconfig.json", + + /** + * (REQUIRED) An array of emit configurations. Each entry specifies an output + * directory, module format, and target. + */ + "emitKinds": [ + { + /** + * The output directory for the transpiled files, relative to the project folder. + */ + "outDir": "lib-commonjs", + + /** + * The module format for transpiled files. Uses TypeScript's ModuleKind names. + * Supported values: "CommonJS", "ES2015", "ES2020", "ES2022", "ESNext", + * "Node16", "NodeNext", "AMD", "UMD" + */ + "formatOverride": "CommonJS", + + /** + * The target ECMAScript version for transpiled files. Uses TypeScript's + * ScriptTarget names. + * Supported values: "ES3", "ES5", "ES2015", "ES2016", "ES2017", "ES2018", + * "ES2019", "ES2020", "ES2021", "ES2022", "ES2023", "ES2024", "ESNext" + */ + "targetOverride": "ES2017" + } + ] +} +``` + +## See also + +- [TypeScript plugin](./typescript.md) - The standard TypeScript compiler plugin +- [SWC documentation](https://swc.rs/) diff --git a/websites/heft.rushstack.io/i18n/zh-cn/docusaurus-plugin-content-docs/current/pages/plugins/rspack.md b/websites/heft.rushstack.io/i18n/zh-cn/docusaurus-plugin-content-docs/current/pages/plugins/rspack.md new file mode 100644 index 000000000..0b9705d05 --- /dev/null +++ b/websites/heft.rushstack.io/i18n/zh-cn/docusaurus-plugin-content-docs/current/pages/plugins/rspack.md @@ -0,0 +1,183 @@ +--- +title: Rspack plugin +--- + +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + + +| | | +| --- | --- | +| **Plugin package:** | [@rushstack/heft-rspack-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-rspack-plugin) | +| **Plugin name:** | [rspack-plugin](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-rspack-plugin/heft-plugin.json) implemented by [RspackPlugin.ts](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-rspack-plugin/src/RspackPlugin.ts) | +| **Plugin config file:** | (none) | +| **heft.json options:** | [IRspackPluginOptions](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-rspack-plugin/src/RspackPlugin.ts) | + + +This task invokes [Rspack](https://rspack.dev/) to produce application bundles. Rspack is a high-performance +JavaScript bundler written in Rust that is designed to be largely compatible with the Webpack ecosystem. It +provides features such as: + +- Combining many small .js files into one large file for faster downloads +- Improving performance by applying various compiler optimizations such as inlining and dead code elimination ("tree shaking") +- Compressing and obfuscating code by shortening identifiers, using built-in minification by default +- Converting assets such as .css or even images into embedded JavaScript objects +- Significantly faster build times compared to Webpack, thanks to its Rust-based implementation + +Like the [Webpack plugin](./webpack.md), Heft invokes the TypeScript compiler to produce intermediate .js files +which become the inputs for the Rspack bundler. This reduces the number of compiler passes, and avoids the +need for compiler optimizations to be reimplemented multiple times for different contexts. + +## When to use it + +Rspack should be used for projects whose output is a web application bundle, particularly when build +performance is a priority. Because Rspack is designed to be compatible with most Webpack loaders and +plugins, it can often be adopted as a drop-in replacement for Webpack with minimal configuration changes. + +Rspack can also be used to bundle Node.js tools or services, however this is less common. + +## package.json dependencies + +You'll need to add the plugin package to your project: + + + + +```bash +# If you are using Rush, run this shell command in your project folder: +rush add --package @rushstack/heft-rspack-plugin --dev +``` + + + + +```bash +# If you are using vanilla NPM, run this shell command in your project folder: +npm install @rushstack/heft-rspack-plugin --save-dev +``` + + + + +The `@rushstack/heft-rspack-plugin` package has a peer dependency on `@rspack/core`. You must add this +dependency as well: + + + + +```bash +# If you are using Rush, run this shell command in your project folder: +rush add --package @rspack/core --dev +``` + + + + +```bash +# If you are using vanilla NPM, run this shell command in your project folder: +npm install @rspack/core --save-dev +``` + + + + +## Configuration + +Your [heft.json config file](../configs/heft_json.md) could invoke Rspack like in this example: + +**<project folder>/config/heft.json** + +```js +{ + "$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json", + + "aliasesByName": { + "start": { + "actionName": "build-watch", + "defaultParameters": ["--serve"] + } + }, + + "phasesByName": { + "build": { + "cleanFiles": [ + { "sourcePath": "dist" }, + { "sourcePath": "lib" }, + { "sourcePath": "lib-commonjs" } + ], + "tasksByName": { + "typescript": { + "taskPlugin": { + "pluginPackage": "@rushstack/heft-typescript-plugin" + } + }, + "rspack": { + "taskDependencies": ["typescript"], + "taskPlugin": { + "pluginPackage": "@rushstack/heft-rspack-plugin" + } + } + } + } + } +} +``` + +Next, create an **rspack.config.mjs** file in your project folder. Here is a rudimentary example: + +**<project folder>/rspack.config.mjs** + +```js +import * as path from 'path'; +import { fileURLToPath } from 'url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +/** @type {import('@rspack/core').Configuration} */ +const rspackConfig = { + mode: 'development', + resolve: { + // Note: Do not specify '.ts' or '.tsx' here. Heft invokes Rspack as a post-process after the compiler. + extensions: ['.js', '.jsx', '.json'] + }, + entry: { + app: path.join(__dirname, 'lib', 'index.js') + }, + output: { + path: path.join(__dirname, 'dist'), + filename: '[name]_[contenthash].js' + } +}; + +export default rspackConfig; +``` + +If you want to use a slightly different configuration when developing using the localhost dev server, +you can optionally create a second file called **rspack.dev.config.js**. + +To start the localhost dev server, use the `heft start` command, which conventionally is defined as an alias +for `heft build-watch --serve` (see `aliasesByName` above). Whenever you save a change to a source file, +Heft's watch mode will recompile your project, then Rspack's dev server should refresh your +web browser with the latest build of the app. + +### Interaction with Jest + +Rspack works best with the `esnext` module format, whereas Jest must use the `commonjs` module format because +its tests are executed by the Node.js runtime. In order to use Rspack and Jest together, you will need +to emit both module formats. This is described in the [Jest plugin](../plugins/jest.md) section. + +## CLI parameters + +[heft-rspack-plugin/heft-plugin.json](https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-rspack-plugin/heft-plugin.json) defines these parameters: + +``` + --serve + Start a local web server for testing purposes using + @rspack/dev-server. This parameter is only available + when running in watch mode. +``` + +## See also + +- [Rspack documentation](https://rspack.dev/) +- [Webpack plugin](./webpack.md) - the equivalent plugin for Webpack diff --git a/websites/heft.rushstack.io/sidebars.js b/websites/heft.rushstack.io/sidebars.js index 0e3039ffa..0dfc85242 100644 --- a/websites/heft.rushstack.io/sidebars.js +++ b/websites/heft.rushstack.io/sidebars.js @@ -41,7 +41,7 @@ const sidebars = { type: 'category', label: 'Advanced topics', collapsible: false, - items: ['pages/advanced/heft-config-file'] + items: ['pages/advanced/heft-config-file', 'pages/advanced/authoring-plugins'] }, { type: 'category', @@ -83,11 +83,21 @@ const sidebars = { label: 'ESlint / TSLint', id: 'pages/plugins/lint' }, + { + type: 'doc', + label: 'Isolated transpile (SWC)', + id: 'pages/plugins/isolated-transpile' + }, { type: 'doc', label: 'Node.js service', id: 'pages/plugins/node-service' }, + { + type: 'doc', + label: 'Rspack', + id: 'pages/plugins/rspack' + }, { type: 'doc', label: 'Run script', diff --git a/websites/rushjs.io/docs/pages/configs/rush-plugin-manifest_json.md b/websites/rushjs.io/docs/pages/configs/rush-plugin-manifest_json.md index 82b58f3e2..01eb4d3f4 100644 --- a/websites/rushjs.io/docs/pages/configs/rush-plugin-manifest_json.md +++ b/websites/rushjs.io/docs/pages/configs/rush-plugin-manifest_json.md @@ -1,5 +1,5 @@ --- -title: rush-plugin-manifest.json (experimental) +title: rush-plugin-manifest.json --- This is the template for the **rush-plugin-manifest.json** file that is used when diff --git a/websites/rushjs.io/docs/pages/extensibility/creating_plugins.md b/websites/rushjs.io/docs/pages/extensibility/creating_plugins.md index 0cd5e23c4..3a294cc8c 100644 --- a/websites/rushjs.io/docs/pages/extensibility/creating_plugins.md +++ b/websites/rushjs.io/docs/pages/extensibility/creating_plugins.md @@ -1,5 +1,5 @@ --- -title: Creating Rush plugins (experimental) +title: Creating Rush plugins --- Rush plugins enable repository maintainers to: @@ -136,6 +136,51 @@ Example project for this scenario: > use the `"associatedCommands"` setting to improve performance by > avoiding loading the module when it is not needed. +### Available lifecycle hooks + +The [RushSession.hooks](https://api.rushstack.io/pages/rush-lib.rushsession/) object exposes +[lifecycle hooks](https://api.rushstack.io/pages/rush-lib.rushlifecyclehooks/) that your plugin can +use to register its handlers. The hook system is based on the +[tapable](https://www.npmjs.com/package/tapable) framework familiar from Webpack. + +| Hook | Type | Description | +| :--- | :--- | :---------- | +| `initialize` | `AsyncSeriesHook` | Called before executing any Rush CLI command. | +| `runAnyGlobalCustomCommand` | `AsyncSeriesHook` | Called before executing any global custom command (defined in command-line.json). | +| `runGlobalCustomCommand` | `HookMap` | A hook map to target specific named global commands before execution. | +| `runAnyPhasedCommand` | `AsyncSeriesHook` | Called before executing any phased command (including the default `build` and `rebuild`). | +| `runPhasedCommand` | `HookMap` | A hook map to target specific named phased commands before execution. | +| `beforeInstall` | `AsyncSeriesHook` | Called between preparing the common/temp folder and invoking the package manager during `rush install` or `rush update`. | +| `afterInstall` | `AsyncSeriesHook` | Called after a successful install. | +| `flushTelemetry` | `AsyncParallelHook` | Allows plugins to process telemetry data. | + +For example, to tap a specific phased command: + +```ts +public apply(rushSession: RushSession, rushConfiguration: RushConfiguration): void { + rushSession.hooks.runPhasedCommand.for('build').tapPromise( + this.pluginName, + async (command: IPhasedCommand) => { + const logger: ILogger = rushSession.getLogger(this.pluginName); + logger.terminal.writeLine('The "rush build" command is about to run!'); + } + ); +} +``` + +### Registering service providers + +The `RushSession` object also provides methods for plugins that implement build cache or cobuild +lock providers: + +| Method | Description | +| :----- | :---------- | +| `registerCloudBuildCacheProviderFactory(name, factory)` | Registers a factory that creates a cloud build cache provider for the given provider name. | +| `registerCobuildLockProviderFactory(name, factory)` | Registers a factory that creates a cobuild lock provider for the given provider name. | + +These are used by plugins such as `@rushstack/rush-amazon-s3-build-cache-plugin` and +`@rushstack/rush-redis-cobuild-plugin` to integrate with Rush's build cache and cobuild systems. + ### Defining a config file for your plugin Often a plugin will need to be configured using its own custom settings. Rush's convention diff --git a/websites/rushjs.io/docs/pages/maintainer/publishing.md b/websites/rushjs.io/docs/pages/maintainer/publishing.md index 4101c60c2..deb56dd0b 100644 --- a/websites/rushjs.io/docs/pages/maintainer/publishing.md +++ b/websites/rushjs.io/docs/pages/maintainer/publishing.md @@ -80,7 +80,7 @@ Version policy is a new concept introduced into Rush to solve the problem of how ### What is a version policy? -A version policy is set of rules that define how the version should be increased. It is defined in **common/config/rush/version-policies.json**. An example can be found in [here](https://github.com/microsoft/rushstack/blob/master/common/config/rush/version-policies.json). A public package specifies what version policy it is associated with by providing `versionPolicyName` in **rush.json**. An example can be found in [Rush and Rush-lib configuration](https://github.com/microsoft/rushstack/blob/master/rush.json#L46). Multiple packages can use one version policy if they all follow the same rules. When a package is associated with a version policy, it becomes public and can be published when `rush publish` runs. +A version policy is set of rules that define how the version should be increased. It is defined in **common/config/rush/version-policies.json**. An example can be found in [here](https://github.com/microsoft/rushstack/blob/main/common/config/rush/version-policies.json). A public package specifies what version policy it is associated with by providing `versionPolicyName` in **rush.json**. An example can be found in [Rush and Rush-lib configuration](https://github.com/microsoft/rushstack/blob/main/rush.json#L46). Multiple packages can use one version policy if they all follow the same rules. When a package is associated with a version policy, it becomes public and can be published when `rush publish` runs. The schema of **version-policies.json** is defined [here](https://github.com/microsoft/rushstack/blob/main/libraries/rush-lib/src/schemas/version-policies.schema.json). diff --git a/websites/rushjs.io/docs/pages/maintainer/using_rush_plugins.md b/websites/rushjs.io/docs/pages/maintainer/using_rush_plugins.md index 464e4c51c..68818f20d 100644 --- a/websites/rushjs.io/docs/pages/maintainer/using_rush_plugins.md +++ b/websites/rushjs.io/docs/pages/maintainer/using_rush_plugins.md @@ -1,5 +1,5 @@ --- -title: Using Rush plugins (experimental) +title: Using Rush plugins --- Rush plugins enable you to: @@ -108,13 +108,18 @@ The config filename will have the same as the `pluginName`, for example: | NPM Package | Description | | :------------------------------------------------------------------------------------------------------------------------------------------------------ | :---------------------------------------------------------------------------------------------------------------- | -| [@rushstack/rush-amazon-s3-build-cache-plugin](https://github.com/microsoft/rushstack/tree/main/rush-plugins/rush-amazon-s3-build-cache-plugin) | Cloud build cache provider for Amazon S3 | -| [@rushstack/rush-azure-storage-build-cache-plugin](https://github.com/microsoft/rushstack/tree/main/rush-plugins/rush-azure-storage-build-cache-plugin) | Cloud build cache provider for Azure Storage | -| [@rushstack/rush-serve-plugin](https://github.com/microsoft/rushstack/tree/main/rush-plugins/rush-serve-plugin) | (Experimental) A Rush plugin that hooks into action execution and runs an express server to serve project outputs | - -> **NOTE:** The `@rushstack/rush-amazon-s3-build-cache-plugin` and `@rushstack/rush-azure-storage-build-cache-plugin` -> packages are currently built-in to Rush and enabled automatically. For now, you should NOT register them -> in **rush-plugins.json**. +| [@rushstack/rush-amazon-s3-build-cache-plugin](https://github.com/microsoft/rushstack/tree/main/rush-plugins/rush-amazon-s3-build-cache-plugin) | Cloud build cache provider for Amazon S3 (ships built-in) | +| [@rushstack/rush-azure-storage-build-cache-plugin](https://github.com/microsoft/rushstack/tree/main/rush-plugins/rush-azure-storage-build-cache-plugin) | Cloud build cache provider for Azure Storage (ships built-in); also provides `rush-azure-interactive-auth-plugin` | +| [@rushstack/rush-bridge-cache-plugin](https://github.com/microsoft/rushstack/tree/main/rush-plugins/rush-bridge-cache-plugin) | Bypasses command execution to populate or restore the build cache from an external orchestrator | +| [@rushstack/rush-buildxl-graph-plugin](https://github.com/microsoft/rushstack/tree/main/rush-plugins/rush-buildxl-graph-plugin) | Provides access to the Rush build graph for BuildXL integration | +| [@rushstack/rush-http-build-cache-plugin](https://github.com/microsoft/rushstack/tree/main/rush-plugins/rush-http-build-cache-plugin) | Cloud build cache provider using a generic HTTP endpoint (ships built-in) | +| [@rushstack/rush-redis-cobuild-plugin](https://github.com/microsoft/rushstack/tree/main/rush-plugins/rush-redis-cobuild-plugin) | Cobuild lock provider using Redis for distributed builds | +| [@rushstack/rush-resolver-cache-plugin](https://github.com/microsoft/rushstack/tree/main/rush-plugins/rush-resolver-cache-plugin) | Generates a resolver cache file to optimize Node.js module resolution | +| [@rushstack/rush-serve-plugin](https://github.com/microsoft/rushstack/tree/main/rush-plugins/rush-serve-plugin) | Hooks into action execution and runs an Express server to serve project outputs in watch mode | + +> **NOTE:** The `@rushstack/rush-amazon-s3-build-cache-plugin`, `@rushstack/rush-azure-storage-build-cache-plugin`, +> and `@rushstack/rush-http-build-cache-plugin` packages currently ship built-in to Rush and are enabled +> automatically. For now, you should NOT register them in **rush-plugins.json**. > > This is a temporary accommodation while the plugin framework is still experimental. > In the next major release of Rush, the build cache packages will need to be configured in standard way.