<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Rush Stack Blog</title>
        <link>https://rushstack.io/blog</link>
        <description>Rush Stack Blog</description>
        <lastBuildDate>Fri, 16 Jun 2023 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Heft 0.51 Migration Guide]]></title>
            <link>https://rushstack.io/blog/2023/06/16/heft-migration-guide</link>
            <guid>https://rushstack.io/blog/2023/06/16/heft-migration-guide</guid>
            <pubDate>Fri, 16 Jun 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[The Heft 0.51.0 release introduces a "multi-phase" feature that brings some significant architectural changes. If you've been using an older version, upgrading will require making some changes to your Heft config files and also any custom plugins that you may have authored. In this post, we'll summarize what changed and how to migrate your projects. This is probably the last major breaking change before the 1.0.0 release of Heft.]]></description>
            <content:encoded><![CDATA[<p>The Heft <strong>0.51.0</strong> release introduces a "multi-phase" feature that brings some significant architectural changes. If you've been using an older version, upgrading will require making some changes to your <strong>Heft config files</strong> and also any <strong>custom plugins</strong> that you may have authored. In this post, we'll summarize what changed and how to migrate your projects. This is probably the last major breaking change before the 1.0.0 release of Heft.</p><blockquote><p>For a deeper dive into the multi-phase design and its underlying motivation, please see our other post <a href="/blog/2023/06/15/heft-whats-new/">What's New in Heft 0.51</a>.</p></blockquote><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="version-timeline">Version timeline<a href="#version-timeline" class="hash-link" aria-label="Direct link to Version timeline" title="Direct link to Version timeline">​</a></h2><p>Although most of the breaking changes are in Heft <strong>0.51.0</strong>, other significant changes were made in several subsequent versions:</p><ul><li>Heft <strong>0.51.0</strong>: The big architecture change for multi-phase support, with breaking changes for config file schemas and plugin APIs</li><li>Heft <strong>0.52.0</strong>: Restored support for the <code>heft start</code> alias (which had been removed in 0.51.0); added the ability to define custom aliases; <code>@rushstack/heft-node-rig</code> now launches its dev server using the same <code>heft start</code> alias as <code>@rushstack/heft-web-rig</code></li><li>Heft <strong>0.53.0</strong>: Removed the <code>taskEvents</code> config setting; built-in tasks like <code>copy-files-plugin</code> and <code>node-service-plugin</code> now use identical configuration as third-party plugins (simply specifying <code>@rushstack/heft</code> as their plugin package name)</li><li>Heft <strong>0.54.0</strong>: Restored support for short parameter names such as <code>-u</code> in <code>heft test -u</code> (which had been removed in 0.51.0)</li><li>Heft <strong>0.55.0</strong>: Removed <code>cacheFolderPath</code> from plugin API's session object, since the <code>.cache</code> folder is no longer used</li></ul><p>To simplify these migration notes, in this article we'll assume you're upgrading to <strong>0.55.0 or newer</strong>, and that you're coming from <strong>0.50.x or older</strong>.</p><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="migrating-heftjson-files">Migrating heft.json files<a href="#migrating-heftjson-files" class="hash-link" aria-label="Direct link to Migrating heft.json files" title="Direct link to Migrating heft.json files">​</a></h2><h3 class="anchor anchorWithStickyNavbar_Cwtr" id="json-schema-url-changes">JSON Schema URL changes<a href="#json-schema-url-changes" class="hash-link" aria-label="Direct link to JSON Schema URL changes" title="Direct link to JSON Schema URL changes">​</a></h3><p>In order to have correct VS Code IntelliSense when editing config files, update the <code>"$schema"</code> field in each Heft config file. Simply replace <code>json-schemas/heft/</code> with <code>json-schemas/heft/v0</code>.</p><p>For example:</p><ul><li>Old: <code>"$schema": "https://developer.microsoft.com/json-schemas/heft/heft.schema.json"</code></li><li>New: <code>"$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json"</code></li></ul><p>The full list of JSON schema names can be found <a href="https://github.com/microsoft/json-schemas/tree/main/heft/v0" target="_blank" rel="noopener noreferrer">in this GitHub folder</a>. These names are the last part of the URL shown above.</p><h3 class="anchor anchorWithStickyNavbar_Cwtr" id="plugins-must-be-explicitly-loaded">Plugins must be explicitly loaded<a href="#plugins-must-be-explicitly-loaded" class="hash-link" aria-label="Direct link to Plugins must be explicitly loaded" title="Direct link to Plugins must be explicitly loaded">​</a></h3><p>In the old design, a number of plugins were built-in to <code>@rushstack/heft</code> and did not need to be explicitly loaded using <strong>heft.json</strong> settings. If their associated config file was not found, then their task would be silently skipped.</p><p><strong>OLD:</strong> Plugins that were implicitly loaded:</p><ul><li>heft-typescript-plugin</li><li>copy-static-assets-plugin</li><li>copy-files-plugin</li><li>delete-globs-plugin</li><li>run-script-plugin</li><li>api-extractor-plugin</li><li>project-validator-plugin</li><li>node-service-plugin</li></ul><p><strong>NEW:</strong> After migrating, every plugin must be explicitly loaded via the <strong>heft.json</strong> config file. Typically this is inherited from your rig. This new model eliminates magic and mysteries, since the full set of plugins and their dependencies is now represented in the config file.</p><p>If you are using our <code>@rushstack/heft-node-rig</code> and <code>@rushstack/heft-web-rig</code>, your project should only need minor changes, since the updated rigs now explicitly load all these plugins. If you created a custom rig, the migration work will be more involved, but you can copy from our examples:</p><ul><li><a href="https://github.com/microsoft/rushstack/blob/main/rigs/heft-node-rig/profiles/default/config/heft.json" target="_blank" rel="noopener noreferrer">heft-node-rig/profiles/default/config/heft.json</a></li><li><a href="https://github.com/microsoft/rushstack/blob/main/rigs/heft-web-rig/profiles/app/config/heft.json" target="_blank" rel="noopener noreferrer">heft-web-rig/profiles/app/config/heft.json</a></li></ul><h3 class="anchor anchorWithStickyNavbar_Cwtr" id="migrating-packagejson-dependencies">Migrating package.json dependencies<a href="#migrating-packagejson-dependencies" class="hash-link" aria-label="Direct link to Migrating package.json dependencies" title="Direct link to Migrating package.json dependencies">​</a></h3><p>Many of these plugins have been extracted into their own NPM packages. This reduces the startup time and installation footprint for projects that don't use certain plugins.</p><p>Here's the current inventory as of this writing:</p><ul><li><a href="https://github.com/microsoft/rushstack/tree/main/apps/heft" target="_blank" rel="noopener noreferrer">@rushstack/heft</a>: Its <a href="https://github.com/microsoft/rushstack/blob/main/apps/heft/heft-plugin.json" target="_blank" rel="noopener noreferrer">heft-plugin.json</a> defines multiple plugins copy-files-plugin, delete-files-plugin, node-service-plugin, run-script-plugin</li><li><a href="https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-api-extractor-plugin" target="_blank" rel="noopener noreferrer">@rushstack/heft-api-extractor-plugin</a></li><li><a href="https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-dev-cert-plugin" target="_blank" rel="noopener noreferrer">@rushstack/heft-dev-cert-plugin</a></li><li><a href="https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-jest-plugin" target="_blank" rel="noopener noreferrer">@rushstack/heft-jest-plugin</a></li><li><a href="https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-lint-plugin" target="_blank" rel="noopener noreferrer">@rushstack/heft-lint-plugin</a></li><li><a href="https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-sass-plugin" target="_blank" rel="noopener noreferrer">@rushstack/heft-sass-plugin</a></li><li><a href="https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-serverless-stack-plugin" target="_blank" rel="noopener noreferrer">@rushstack/heft-serverless-stack-plugin</a></li><li><a href="https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-storybook-plugin" target="_blank" rel="noopener noreferrer">@rushstack/heft-storybook-plugin</a></li><li><a href="https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-typescript-plugin" target="_blank" rel="noopener noreferrer">@rushstack/heft-typescript-plugin</a></li><li><a href="https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-webpack4-plugin" target="_blank" rel="noopener noreferrer">@rushstack/heft-webpack4-plugin</a></li><li><a href="https://github.com/microsoft/rushstack/tree/main/heft-plugins/heft-webpack5-plugin" target="_blank" rel="noopener noreferrer">@rushstack/heft-webpack5-plugin</a></li></ul><h3 class="anchor anchorWithStickyNavbar_Cwtr" id="migrating-a-standalone-heftjson">Migrating a standalone heft.json<a href="#migrating-a-standalone-heftjson" class="hash-link" aria-label="Direct link to Migrating a standalone heft.json" title="Direct link to Migrating a standalone heft.json">​</a></h3><p>The old <strong>heft.json</strong> distinguished "event actions" (i.e. built-in tasks) versus "heftPlugins" (i.e. tasks from plugin packages).</p><p><strong>OLD:</strong> <strong>heft.json</strong> excerpt from <code>heft-node-rig</code></p><div class="language-ts codeBlockContainer_sQcC theme-code-block" style="--prism-color:#000000;--prism-background-color:#ffffff"><div class="codeBlockContent_aCbw"><pre tabindex="0" class="prism-code language-ts codeBlock_hdfK thin-scrollbar"><code class="codeBlockLines_lb0E"><span class="token-line" style="color:#000000"><span class="token comment" style="color:rgb(0, 128, 0)">// ⚠️ OLD FORMAT EXAMPLE -- DO NOT USE! ⚠️</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain"></span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"$schema"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"https://developer.microsoft.com/json-schemas/heft/heft.schema.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token comment" style="color:rgb(0, 128, 0)">// "deleteGlobs" is specified to run with the "clean" event</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"eventActions"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token comment" style="color:rgb(0, 128, 0)">// 📌 [1] old way of cleaning</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"actionKind"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"deleteGlobs"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"heftEvent"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"clean"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"actionId"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"defaultClean"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"globsToDelete"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"dist"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"lib"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"lib-commonjs"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"temp"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token comment" style="color:rgb(0, 128, 0)">// the Jest plugin is loaded using the "heftPlugins" section</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token comment" style="color:rgb(0, 128, 0)">// and its event sequence was defined using program logic</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"heftPlugins"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token comment" style="color:rgb(0, 128, 0)">// 📌 [2] old way of loading a plugin</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"> </span><span class="token string-property property">"plugin"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-jest-plugin"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain"></span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><br></span></code></pre><div class="buttonGroup_A7Vp"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_GFHe" aria-hidden="true"><svg class="copyButtonIcon_dPFB" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_Fsz1" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>NEW:</strong> <strong>heft.json</strong> excerpt from <code>heft-node-rig</code></p><div class="language-ts codeBlockContainer_sQcC theme-code-block" style="--prism-color:#000000;--prism-background-color:#ffffff"><div class="codeBlockContent_aCbw"><pre tabindex="0" class="prism-code language-ts codeBlock_hdfK thin-scrollbar"><code class="codeBlockLines_lb0E"><span class="token-line" style="color:#000000"><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"$schema"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"phasesByName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token comment" style="color:rgb(0, 128, 0)">// ("build" is a user-defined name, not a schema field)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token string-property property">"build"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token comment" style="color:rgb(0, 128, 0)">// 📌 [1] new way of cleaning</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"cleanFiles"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"> </span><span class="token string-property property">"sourcePath"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"dist"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"> </span><span class="token string-property property">"sourcePath"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"lib"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"> </span><span class="token string-property property">"sourcePath"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"lib-commonjs"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"tasksByName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token comment" style="color:rgb(0, 128, 0)">// ("typescript" is a user-defined name, not a schema field)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token string-property property">"typescript"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskPlugin"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginPackage"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-typescript-plugin"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token string-property property">"lint"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskDependencies"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"typescript"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskPlugin"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginPackage"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-lint-plugin"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token string-property property">"api-extractor"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskDependencies"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"typescript"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskPlugin"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginPackage"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-api-extractor-plugin"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token string-property property">"node-service"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskDependencies"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"typescript"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskPlugin"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token comment" style="color:rgb(0, 128, 0)">// This built-in plugin specifies "@rushstack/heft" as its package name</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginPackage"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"node-service-plugin"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token comment" style="color:rgb(0, 128, 0)">// ("test" is a user-defined name, not a schema field)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token string-property property">"test"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"phaseDependencies"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"build"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"tasksByName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token comment" style="color:rgb(0, 128, 0)">// ("jest" is a user-defined name for this task)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token string-property property">"jest"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token comment" style="color:rgb(0, 128, 0)">// 📌 [2] new way of loading a plugin</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskPlugin"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginPackage"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-jest-plugin"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain"></span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><br></span></code></pre><div class="buttonGroup_A7Vp"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_GFHe" aria-hidden="true"><svg class="copyButtonIcon_dPFB" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_Fsz1" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Looking at the above example, the major changes are:</p><ul><li>every task must be explicitly loaded from a <code>pluginPackage</code>, so the rig's <strong>heft.json</strong> is now more verbose (but more understandable!)</li><li>built-in tasks (e.g. <code>node-service</code>) have identical specification as external plugins</li><li>the old <code>"heftEvent"</code> lifecycle has been replaced by <code>phaseDependencies</code> and <code>taskDependencies</code> whose dependency graph determines the sequencing of tasks</li></ul><p>The complete config file can be found here: <a href="https://github.com/microsoft/rushstack/blob/main/rigs/heft-node-rig/profiles/default/config/heft.json" target="_blank" rel="noopener noreferrer">heft-node-rig/profiles/default/config/heft.json</a></p><h3 class="anchor anchorWithStickyNavbar_Cwtr" id="migrating-a-rigged-heftjson">Migrating a rigged heft.json<a href="#migrating-a-rigged-heftjson" class="hash-link" aria-label="Direct link to Migrating a rigged heft.json" title="Direct link to Migrating a rigged heft.json">​</a></h3><p>Here's another example from the <a href="https://tsdoc.org/play/" target="_blank" rel="noopener noreferrer">TSDoc Playground</a> project, whose <a href="https://github.com/microsoft/tsdoc/blob/main/playground/config/heft.json" target="_blank" rel="noopener noreferrer">heft.json</a> inherits from our <code>heft-web-rig</code>:</p><p><strong>OLD:</strong> <strong>heft.json</strong> excerpt from <code>playground/config/heft.json</code></p><div class="language-ts codeBlockContainer_sQcC theme-code-block" style="--prism-color:#000000;--prism-background-color:#ffffff"><div class="codeBlockContent_aCbw"><pre tabindex="0" class="prism-code language-ts codeBlock_hdfK thin-scrollbar"><code class="codeBlockLines_lb0E"><span class="token-line" style="color:#000000"><span class="token comment" style="color:rgb(0, 128, 0)">// ⚠️ OLD FORMAT EXAMPLE -- DO NOT USE! ⚠️</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain"></span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"$schema"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"https://developer.microsoft.com/json-schemas/heft/heft.schema.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"extends"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-web-rig/profiles/library/config/heft.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"eventActions"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"actionId"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"copyLicenseToDistFolder"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"actionKind"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"copyFiles"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token comment" style="color:rgb(0, 128, 0)">// 📌 [3] old way to do a post-compile action</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"heftEvent"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"compile"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"copyOperations"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"destinationFolders"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"./dist"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token comment" style="color:rgb(0, 128, 0)">// 📌 [4] old way of specifying a source folder</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"sourceFolder"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">".."</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"includeGlobs"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"LICENSE"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain"></span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><br></span></code></pre><div class="buttonGroup_A7Vp"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_GFHe" aria-hidden="true"><svg class="copyButtonIcon_dPFB" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_Fsz1" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>NEW:</strong> <strong>heft.json</strong> excerpt from <code>playground/config/heft.json</code></p><div class="language-ts codeBlockContainer_sQcC theme-code-block" style="--prism-color:#000000;--prism-background-color:#ffffff"><div class="codeBlockContent_aCbw"><pre tabindex="0" class="prism-code language-ts codeBlock_hdfK thin-scrollbar"><code class="codeBlockLines_lb0E"><span class="token-line" style="color:#000000"><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"$schema"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"extends"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-web-rig/profiles/library/config/heft.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"phasesByName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token comment" style="color:rgb(0, 128, 0)">// ("build" is a user-defined name, not a schema field)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token string-property property">"build"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"tasksByName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token comment" style="color:rgb(0, 128, 0)">// ("post-compile-copy" is a user-defined name, not a schema field)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token string-property property">"post-compile-copy"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token comment" style="color:rgb(0, 128, 0)">// 📌 [3] new way to do a post-compile action, by depending on the relevant task(s)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token comment" style="color:rgb(0, 128, 0)">// The "post-compile-copy" task should not run until after "typescript" completes</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskDependencies"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"typescript"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskPlugin"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"copy-files-plugin"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginPackage"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"options"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">              </span><span class="token string-property property">"copyOperations"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                  </span><span class="token comment" style="color:rgb(0, 128, 0)">// 📌 [4] new way of specifying a source folder (or file path)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                  </span><span class="token string-property property">"sourcePath"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">".."</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                  </span><span class="token string-property property">"destinationFolders"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"./dist"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                  </span><span class="token string-property property">"includeGlobs"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"LICENSE"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">              </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain"></span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><br></span></code></pre><div class="buttonGroup_A7Vp"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_GFHe" aria-hidden="true"><svg class="copyButtonIcon_dPFB" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_Fsz1" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Observations:</p><ul><li>The changes here are minimal, since the rig provides most of the build definition</li><li>The latest <code>heft-web-rig</code> uses <code>heft-webpack5-plugin</code>, so we had to upgrade from Webpack 4 -&gt; 5 as part of this conversion</li><li>The <code>"heftEvent": "compile"</code> event no longer exists; instead it must be represented via an equivalent <code>"taskDependencies"</code> entry, which references the rig's <code>"typescript"</code> task definition</li></ul><h3 class="anchor anchorWithStickyNavbar_Cwtr" id="migrating-a-pre-compile-action">Migrating a "pre-compile" action<a href="#migrating-a-pre-compile-action" class="hash-link" aria-label="Direct link to Migrating a &quot;pre-compile&quot; action" title="Direct link to Migrating a &quot;pre-compile&quot; action">​</a></h3><p>In the above example, we migrated our config file by replacing <code>"heftEvent": "compile"</code>
with <code>"taskDependencies": ["typescript"]</code>, which accomplishes the same thing by expressing that the
action cannot be performed until after the <code>"typescript"</code> task has completed. But the <code>"taskDependencies"</code>
is a unidirectional relationship. In this new model, how can we represent an event such as <code>pre-compile</code>?</p><p>Consider this hypothetical example:</p><p><strong>OLD:</strong> <strong>heft.json</strong> sample</p><div class="language-ts codeBlockContainer_sQcC theme-code-block" style="--prism-color:#000000;--prism-background-color:#ffffff"><div class="codeBlockContent_aCbw"><pre tabindex="0" class="prism-code language-ts codeBlock_hdfK thin-scrollbar"><code class="codeBlockLines_lb0E"><span class="token-line" style="color:#000000"><span class="token comment" style="color:rgb(0, 128, 0)">// ⚠️ OLD FORMAT EXAMPLE -- DO NOT USE! ⚠️</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain"></span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"$schema"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"https://developer.microsoft.com/json-schemas/heft/heft.schema.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"extends"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-web-rig/profiles/app/config/heft.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"eventActions"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"actionKind"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"copyFiles"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"actionId"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"copyAssets"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token comment" style="color:rgb(0, 128, 0)">// 📌 [5] old way to do a "post-compile" action</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"heftEvent"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"pre-compile"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"copyOperations"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"sourceFolder"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"node_modules/some-library/dist"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"destinationFolders"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"temp/typings"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"includeGlobs"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"*.d.ts"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain"></span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><br></span></code></pre><div class="buttonGroup_A7Vp"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_GFHe" aria-hidden="true"><svg class="copyButtonIcon_dPFB" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_Fsz1" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>NEW:</strong> <strong>heft.json</strong> sample</p><div class="language-ts codeBlockContainer_sQcC theme-code-block" style="--prism-color:#000000;--prism-background-color:#ffffff"><div class="codeBlockContent_aCbw"><pre tabindex="0" class="prism-code language-ts codeBlock_hdfK thin-scrollbar"><code class="codeBlockLines_lb0E"><span class="token-line" style="color:#000000"><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"$schema"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"extends"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-web-rig/profiles/app/config/heft.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"phasesByName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token comment" style="color:rgb(0, 128, 0)">// ("build" is a user-defined name, not a schema field)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token string-property property">"build"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"tasksByName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token comment" style="color:rgb(0, 128, 0)">// ("pre-compile-copy" is a user-defined name, not a schema field)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token string-property property">"pre-compile-copy"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskPlugin"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginPackage"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"copy-files-plugin"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"options"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">              </span><span class="token string-property property">"copyOperations"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                  </span><span class="token string-property property">"sourcePath"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"node_modules/some-library/dist"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                  </span><span class="token string-property property">"destinationFolders"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"temp/typings"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                  </span><span class="token string-property property">"includeGlobs"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"*.d.ts"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">              </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token comment" style="color:rgb(0, 128, 0)">// ("typescript" is a user-defined name, that is originally defined in the rig)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token string-property property">"typescript"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token comment" style="color:rgb(0, 128, 0)">// 📌 [5] new way to do a "post-compile" action</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token comment" style="color:rgb(0, 128, 0)">// The "typescript" task should not run until after "pre-compile-copy" completes.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskDependencies"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"pre-compile-copy"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain"></span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><br></span></code></pre><div class="buttonGroup_A7Vp"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_GFHe" aria-hidden="true"><svg class="copyButtonIcon_dPFB" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_Fsz1" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>For reference, <code>@rushstack/heft-web-rig</code> defines the <code>"typescript"</code> task as follows:</p><p><a href="https://github.com/microsoft/rushstack/blob/main/rigs/heft-web-rig/profiles/app/config/heft.json" target="_blank" rel="noopener noreferrer">heft-web-rig/profiles/app/config/heft.json</a> excerpt</p><div class="language-js codeBlockContainer_sQcC theme-code-block" style="--prism-color:#000000;--prism-background-color:#ffffff"><div class="codeBlockContent_aCbw"><pre tabindex="0" class="prism-code language-js codeBlock_hdfK thin-scrollbar"><code class="codeBlockLines_lb0E"><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">.</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">.</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"typescript"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token string-property property">"taskDependencies"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"sass"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token string-property property">"taskPlugin"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"pluginPackage"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-typescript-plugin"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">.</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">.</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">.</span><br></span></code></pre><div class="buttonGroup_A7Vp"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_GFHe" aria-hidden="true"><svg class="copyButtonIcon_dPFB" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_Fsz1" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Observations:</p><ul><li>Recall that we implemented <code>"post-compile-copy"</code> by specifying <code>taskDependencies</code> for our own task (<code>"taskDependencies": ["typescript"]</code>)</li><li>By contrast, <code>"pre-compile-copy"</code> is implemented by amending the <code>taskDependencies</code> for the rig's <code>"typescript"</code> task
(<code>"taskDependencies": ["pre-compile-copy"]</code>)</li><li>The rig already has <code>"taskDependencies": ["sass"]</code>. But we do NOT need to specify <code>"taskDependencies": ["typescript", "sass"]</code> because by default, Heft's config parser will merge arrays by appending rather than replacing entries</li><li>This merge behavior is implemented by <code>@rushstack/heft-config-file</code> and can be customized using
<a href="/blog/2023/06/15/heft-whats-new/#heftjson-property-inheritance-directives">property inheritance directives</a></li></ul><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="migrating-command-line-syntax">Migrating command line syntax<a href="#migrating-command-line-syntax" class="hash-link" aria-label="Direct link to Migrating command line syntax" title="Direct link to Migrating command line syntax">​</a></h2><p>The old <code>--watch</code> command line parameter has been removed. Instead, watch mode is enabled by appending <code>-watch</code>
to the action name.</p><p><strong>OLD:</strong></p><div class="language-shell codeBlockContainer_sQcC theme-code-block" style="--prism-color:#000000;--prism-background-color:#ffffff"><div class="codeBlockContent_aCbw"><pre tabindex="0" class="prism-code language-shell codeBlock_hdfK thin-scrollbar"><code class="codeBlockLines_lb0E"><span class="token-line" style="color:#000000"><span class="token plain">heft build --watch --verbose</span><br></span></code></pre><div class="buttonGroup_A7Vp"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_GFHe" aria-hidden="true"><svg class="copyButtonIcon_dPFB" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_Fsz1" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>NEW:</strong></p><div class="codeBlockContainer_sQcC theme-code-block" style="--prism-color:#000000;--prism-background-color:#ffffff"><div class="codeBlockContent_aCbw"><pre tabindex="0" class="prism-code language-text codeBlock_hdfK thin-scrollbar"><code class="codeBlockLines_lb0E"><span class="token-line" style="color:#000000"><span class="token plain">heft build-watch --verbose</span><br></span></code></pre><div class="buttonGroup_A7Vp"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_GFHe" aria-hidden="true"><svg class="copyButtonIcon_dPFB" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_Fsz1" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="command-aliases">Command aliases<a href="#command-aliases" class="hash-link" aria-label="Direct link to Command aliases" title="Direct link to Command aliases">​</a></h2><p>In the old design, <code>heft start</code> was a special action for launching dev servers. In the new design, it is
a command alias defined in <strong>heft.json</strong>. The new aliasing system allows you to define your own custom aliases
to shorten common commands.</p><p><a href="https://github.com/microsoft/rushstack/blob/main/rigs/heft-web-rig/profiles/app/config/heft.json" target="_blank" rel="noopener noreferrer">heft-web-rig/profiles/app/config/heft.json</a> excerpt</p><div class="language-js codeBlockContainer_sQcC theme-code-block" style="--prism-color:#000000;--prism-background-color:#ffffff"><div class="codeBlockContent_aCbw"><pre tabindex="0" class="prism-code language-js codeBlock_hdfK thin-scrollbar"><code class="codeBlockLines_lb0E"><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token comment" style="color:rgb(0, 128, 0)">// Define "heft start" to be an alias for "heft build-watch --serve".</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"aliasesByName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token string-property property">"start"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"actionName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"build-watch"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"defaultParameters"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token string" style="color:rgb(163, 21, 21)">"--serve"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><br></span></code></pre><div class="buttonGroup_A7Vp"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_GFHe" aria-hidden="true"><svg class="copyButtonIcon_dPFB" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_Fsz1" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The <code>--serve</code> CLI parameter is our standard convention for launching a <code>localhost</code> dev server. It is supported by both <code>heft-webpack5-plugin</code> and the built-in <code>node-service-plugin</code>.</p><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="rushstackheft-jest-plugin-changes">@rushstack/heft-jest-plugin changes<a href="#rushstackheft-jest-plugin-changes" class="hash-link" aria-label="Direct link to @rushstack/heft-jest-plugin changes" title="Direct link to @rushstack/heft-jest-plugin changes">​</a></h2><p>Heft does not follow the Jest convention of using <code>ts-jest</code> to naively translate <code>.ts</code> files to <code>.js</code>. Instead, the full Heft toolchain is invoked, avoiding duplicate transpilation and ensuring accurate invocation of all preprocessors. In the past, this was implemented by pointing your <strong>jest.config.json</strong> at the source code (<code>"roots": ["&lt;rootDir&gt;/src"]</code>) and relying on <code>@rushstack/heft-jest-plugin/exports/jest-build-transform.js</code> to return Heft's output <code>.js</code> files. However newer releases of Jest introduced a <a href="https://jestjs.io/docs/configuration/#snapshotresolver-string" target="_blank" rel="noopener noreferrer">snapshotResolver</a> setting, which allows Jest to process <code>"&lt;rootDir&gt;/lib"</code> directly and still be able to update inline snapshots. The latest Heft adopted this approach because it provides a better debugging experience.</p><p><strong>How to migrate:</strong> If you're using the Rush Stack rigs or extending from <code>@rushstack/heft-jest-plugin/includes/jest-shared.config.json</code>, just delete <code>emitFolderNameForTests</code> from your <strong>typescript.json</strong> file.</p><p>For more customized setups, here's the full list of underlying changes:</p><ul><li>These plugin options have been removed from <code>@rushstack/heft-jest-plugin</code>: <code>extensionForTests</code>, <code>folderNameForTests</code>, <code>folderNameForSnapshots</code></li><li>The <code>emitFolderNameForTests</code> setting is removed from <strong>config/typescript.json</strong></li><li>In <strong>jest.config.json</strong>, fields such as <code>roots</code>, <code>testMatch</code>, <code>collectCoverageFrom</code> should now point to the CommonJS output folder (<code>lib-commonjs</code> or <code>lib</code>) instead of the <code>src</code> folder</li><li>In <strong>jest.config.json</strong>, <code>moduleFileExtensions</code> should no longer include <code>.ts</code> or <code>.tsx</code> extensions</li><li>In <strong>jest.config.json</strong>, <strong>jest-build-transform.js</strong> is replaced by <code>"snapshotResolver": "@rushstack/heft-jest-plugin/exports/jest-source-map-snapshot-resolver.js"</code></li><li>For web development, we've introduced <a href="https://github.com/microsoft/rushstack/blob/main/heft-plugins/heft-jest-plugin/includes/jest-web.config.json" target="_blank" rel="noopener noreferrer">heft-jest-plugin/includes/jest-web.config.json</a> (for web projects that write their CommonJS to <code>lib-commonjs</code>) alongside the familiar <strong>jest-shared.config.json</strong> (for Node.js projects that write their CommonJS to <code>lib</code>).</li></ul><p>For a real world example, <a href="https://github.com/microsoft/rushstack/compare/6edf3f81a96b7f0c2951b3320825a952ba9d7d0c..4ec1513cdd37cb805b5ed348b5cd3d0e5a9fdba6#diff-467d5815d520ad0cdf1d3338f7ad09f6cdabdd8583f9eb36f8b4547b1728506f" target="_blank" rel="noopener noreferrer">this GitHub diff</a> shows the recent changes to <strong>heft-jest-plugin/includes/jest-shared.config.json</strong>.</p><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="migrating-custom-plugins">Migrating custom plugins<a href="#migrating-custom-plugins" class="hash-link" aria-label="Direct link to Migrating custom plugins" title="Direct link to Migrating custom plugins">​</a></h2><p>In updating to the new version of Heft, plugins will also need to be updated for compatibility. Some of the more notable API changes include:</p><ul><li>The <strong>heft-plugin.json</strong> manifest file must accompany any plugin package. If no <strong>heft-plugin.json</strong> file is found, Heft will report an error.</li><li>Plugin classes must have parameterless constructors, and must be the default export of the file pointed to by the <code>entryPoint</code> property in <strong>heft-plugin.json</strong></li><li>Schema files for options provided in <strong>heft.json</strong> can now be specified using the <code>optionsSchema</code> property in <strong>heft-plugin.json</strong> and they will be validated by Heft</li><li>Parameters are now defined in <strong>heft-plugin.json</strong> and are consumed in the plugin via the <code>IHeftTaskSession.parameters</code> or <code>IHeftLifecycleSession.parameters</code> property.
<em>NOTE: Other than the default Heft-included parameters, only parameters defined by the calling plugin are accessible</em></li><li>Plugins can no longer define their own actions. If a plugin requires its own action, a dedicated phase should be added to the consumers <strong>heft.json</strong></li><li>The <code>runScript</code> Heft event has been modified to only accept a <code>runAsync</code> method, and the properties have been updated to reflect what is available to normal Heft task plugins</li><li>Path-related variables have been renamed to clarify they are paths (ex. <code>HeftConfiguration.buildFolder</code> is now <code>HeftConfiguration.buildFolderPath</code>)</li><li>The <code>runIncremental</code> hook can now be utilized to ensure that watch mode rebuilds occur in proper dependency order</li><li>The <code>clean</code> hook was removed in favor of the <code>cleanFiles</code> option in <strong>heft.json</strong> in order to make it obvious what files are being cleaned and when</li><li>As a consequence, plugins can no longer programmatically compute folders to be cleaned by the <code>heft clean</code> command; its behavior is predetermined by static config files, which makes the overall system simpler and more predictable.</li></ul><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="miscellaneous-migration-notes">Miscellaneous migration notes<a href="#miscellaneous-migration-notes" class="hash-link" aria-label="Direct link to Miscellaneous migration notes" title="Direct link to Miscellaneous migration notes">​</a></h2><ul><li>The <code>node-service-plugin</code> built-in plugin now supports the <code>--serve</code> parameter, to be consistent with the <code>@rushstack/heft-webpack5-plugin</code> dev server.</li><li>If <code>--serve</code> is specified and <code>config/node-service.json</code> is omitted, then <code>node-service-plugin</code> fails with a hard error</li><li>Although <code>@rushstack/heft-lint-plugin</code> and <code>@rushstack/heft-typescript-plugin</code> have been extracted into separate NPM packages, they must be invoked in the same phase, due to their optimized communication using a <a href="/blog/2023/06/15/heft-whats-new/#cross-plugin-interaction">plugin accessor</a>.</li></ul>]]></content:encoded>
            <category>heft</category>
        </item>
        <item>
            <title><![CDATA[What's New in Heft 0.51]]></title>
            <link>https://rushstack.io/blog/2023/06/15/heft-whats-new</link>
            <guid>https://rushstack.io/blog/2023/06/15/heft-whats-new</guid>
            <pubDate>Thu, 15 Jun 2023 00:00:00 GMT</pubDate>
            <description><![CDATA["Multi-phase" Heft is a major update for the @rushstack/heft project with the goal of integrating more closely with Rush phased builds. In addition, this update brings greater customizability and improved parallel process handling to Heft. This post explains the motivation and architecture behind these improvements.]]></description>
            <content:encoded><![CDATA[<p>"Multi-phase" Heft is a major update for the <code>@rushstack/heft</code> project with the goal of integrating more closely with <a href="https://rushjs.io/pages/maintainer/phased_builds/" target="_blank" rel="noopener noreferrer">Rush phased builds</a>. In addition, this update brings greater customizability and improved parallel process handling to Heft. This post explains the motivation and architecture behind these improvements.</p><blockquote><p>For upgrade instructions, refer to the <a href="/blog/2023/06/16/heft-migration-guide/">Heft 0.51 Migration Guide</a> post.</p></blockquote><p>Some key areas that were improved with the updated version of Heft include:</p><ul><li>Developer-defined order of execution for Heft plugins and Heft events</li><li>Partial execution of Heft actions via scoping parameters like <code>--to</code> or <code>--only</code></li><li>A simplified plugin API for developers making Heft plugins</li><li>Explicit definition of all Heft plugins via <strong>heft-plugin.json</strong></li><li>Native support for defining multiple plugins within a single plugin package</li><li>Improved handling of plugin parameters</li><li>Native support for incremental watch-mode in Heft actions</li><li>Reduced overhead and performance improvements</li><li>Much more!</li></ul><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="heft-tasks">Heft tasks<a href="#heft-tasks" class="hash-link" aria-label="Direct link to Heft tasks" title="Direct link to Heft tasks">​</a></h2><p>Heft tasks are the smallest unit of work specified in <strong>heft.json</strong>. Heft tasks may take dependencies on other tasks within the same phase, and all task dependencies must complete execution before dependent tasks can execute.</p><p>In past releases, we distinguished built-in tasks (<code>copy-files-plugin</code>, <code>node-service-plugin</code>, etc)
versus third-party tasks loaded from plugin packages. As of Heft 0.53.0 both kinds of tasks
are now declared identically. Built-in plugins simply specify <code>@rushstack/heft</code> as for
their plugin <code>packageName</code>.</p><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="heft-phases">Heft phases<a href="#heft-phases" class="hash-link" aria-label="Direct link to Heft phases" title="Direct link to Heft phases">​</a></h2><p>Heft phases define a collection of tasks that will run when executing that phase. Phases act as a logical collection of tasks that would reasonably (but not necessarily) map to a <a href="https://rushjs.io/pages/maintainer/phased_builds/" target="_blank" rel="noopener noreferrer">Rush phase</a>. Heft phases may take dependencies on other phases, and when executing multiple phases, all selected phases must complete execution before dependent phases can execute.</p><p>The <strong>heft.json</strong> file is where phases and tasks are defined for a given project or rig. Since this file contains the relationships between the phases and tasks, it defines the order of operations for the execution of a Heft action.</p><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="heft-actions">Heft actions<a href="#heft-actions" class="hash-link" aria-label="Direct link to Heft actions" title="Direct link to Heft actions">​</a></h2><p>Using similar expansion logic to Rush, execution of a selection of Heft phases can be done through the use of the <code>heft run</code> action. This action executes a set of selected phases in order of phase dependency. If the selected phases are not dependent upon each other, they will be executed in parallel. Selection parameters include:</p><ul><li><code>--only</code> - Execute the specified phase</li><li><code>--to</code> - Execute the specified phase and all its dependencies</li></ul><p>Additionally, task- and phase-specific parameters may be provided to the <code>heft run</code> action by appending <code>-- &lt;parameters&gt;</code> to the command. For example, <code>heft run --only build -- --clean</code> will run only the <code>build</code> phase and will run a clean before executing the phase.</p><p>In addition, Heft will generate actions for each phase specified in the <strong>heft.json</strong> configuration. These actions are executed by running <code>heft &lt;phaseName&gt;</code> and run Heft to the specified phase, including all phase dependencies. As such, these inferred Heft actions are equivalent to running <code>heft run --to &lt;phaseName&gt;</code>, and are intended as a CLI shorthand.</p><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="watch-mode">Watch mode<a href="#watch-mode" class="hash-link" aria-label="Direct link to Watch mode" title="Direct link to Watch mode">​</a></h2><p>Watch mode is now a first-class feature in Heft. Watch mode actions are created for all Heft actions. For example, to run <code>build</code> and <code>test</code> phases in watch mode, either of the commands <code>heft test-watch</code> or <code>heft run-watch --to test</code>. When running in watch mode, Heft prefers the <code>runIncremental</code> hook to the <code>run</code> hook (see <a href="#heft-task-plugins">Heft Task Plugins</a>).</p><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="heftjson-structure">heft.json structure<a href="#heftjson-structure" class="hash-link" aria-label="Direct link to heft.json structure" title="Direct link to heft.json structure">​</a></h2><p>All phases are defined within the top-level <code>phasesByName</code> property. Each phase may specify <code>phaseDependencies</code> to define the order of phase execution when running a selection of Heft phases. Phases may also provide the <code>cleanFiles</code> option, which accepts an array of deletion operations to perform when running with the <code>--clean</code> flag.</p><p>Within the phase specification, <code>tasksByName</code> defines all tasks that run while executing a phase. Each task may specify <code>taskDependencies</code> to define the order of task execution. (If <code>taskDependencies</code> is omitted, it defaults to [] and the task only waits for any <code>phaseDependencies</code> of the containing phase.) All tasks defined in <code>taskDependencies</code> must exist within the same phase. For CLI-availability reasons, phase names, task names, plugin names, and parameter scopes, must be <code>kebab-cased</code>.</p><p>The following is an example "heft.json" file defining both a <code>build</code> and a <code>test</code> phase:</p><p><strong>heft.json</strong> example for defining phases and tasks</p><div class="language-js codeBlockContainer_sQcC theme-code-block" style="--prism-color:#000000;--prism-background-color:#ffffff"><div class="codeBlockContent_aCbw"><pre tabindex="0" class="prism-code language-js codeBlock_hdfK thin-scrollbar"><code class="codeBlockLines_lb0E"><span class="token-line" style="color:#000000"><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"$schema"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"extends"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"base-project/config/heft.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token comment" style="color:rgb(0, 128, 0)">// "phasesByName" defines all phases, and each phase defines tasks to be run</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"phasesByName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token comment" style="color:rgb(0, 128, 0)">// ("build" is a user-defined name, not a schema field)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token string-property property">"build"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"phaseDescription"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"Transpile and run a linter against build output"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"cleanFiles"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"sourcePath"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"temp-build-output"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token comment" style="color:rgb(0, 128, 0)">// "tasksByName" defines all tasks within a phase</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"tasksByName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token comment" style="color:rgb(0, 128, 0)">// ("typescript" is a user-defined name, not a schema field)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token string-property property">"typescript"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskPlugin"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginPackage"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-typescript-plugin"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token string-property property">"lint"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskDependencies"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"typescript"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskPlugin"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginPackage"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-lint-plugin"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"eslint"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token string-property property">"copy-assets"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskPlugin"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginPackage"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"copy-files-plugin"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"options"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">              </span><span class="token string-property property">"copyOperations"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                  </span><span class="token comment" style="color:rgb(0, 128, 0)">// NOTE: THIS WAS CALLED "sourceFolder" IN PREVIOUS HEFT VERSIONS</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                  </span><span class="token string-property property">"sourcePath"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"src/assets"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                  </span><span class="token string-property property">"destinationFolders"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"dist/assets"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">                </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">              </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token comment" style="color:rgb(0, 128, 0)">// ("test" is a user-defined name, not a schema field)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token string-property property">"test"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"phaseDependencies"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"build"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"phaseDescription"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"Run Jest tests, if provided."</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"tasksByName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token comment" style="color:rgb(0, 128, 0)">// ("jest" is a user-defined name, not a schema field)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token string-property property">"jest"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token string-property property">"taskPlugin"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">            </span><span class="token string-property property">"pluginPackage"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-jest-plugin"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain"></span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><br></span></code></pre><div class="buttonGroup_A7Vp"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_GFHe" aria-hidden="true"><svg class="copyButtonIcon_dPFB" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_Fsz1" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Lifecycle plugins are specified in the top-level <code>heftPlugins</code> array. Plugins can be referenced by providing a package name and a plugin name. Optionally, if a package contains only a single plugin, a plugin can be referenced by providing only the package name and Heft will resolve to the only exported plugin. Lifecycle plugins can also be provided options to modify the default behavior.</p><p><strong>heft.json</strong> example for loading a lifecycle plugin</p><div class="language-js codeBlockContainer_sQcC theme-code-block" style="--prism-color:#000000;--prism-background-color:#ffffff"><div class="codeBlockContent_aCbw"><pre tabindex="0" class="prism-code language-js codeBlock_hdfK thin-scrollbar"><code class="codeBlockLines_lb0E"><span class="token-line" style="color:#000000"><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"$schema"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"extends"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"base-project/config/heft.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"heftPlugins"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"pluginPackage"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-metrics-reporter"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"options"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token string-property property">"disableMetrics"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"pluginPackage"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"@rushstack/heft-initialization-plugin"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token string-property property">"pluginName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"my-lifecycle-plugin"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token comment" style="color:rgb(0, 128, 0)">// (the "phasesByName" section can also appear here)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain"></span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><br></span></code></pre><div class="buttonGroup_A7Vp"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_GFHe" aria-hidden="true"><svg class="copyButtonIcon_dPFB" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_Fsz1" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="heftjson-property-inheritance-directives">heft.json property inheritance directives<a href="#heftjson-property-inheritance-directives" class="hash-link" aria-label="Direct link to heft.json property inheritance directives" title="Direct link to heft.json property inheritance directives">​</a></h2><p>Previously, common properties between a <strong>heft.json</strong> file its extended base file would merge arrays and overwrite objects. Now, both arrays and objects will merge, allowing for simplified use of the <strong>heft.json</strong> file when customizing extended base configurations.</p><p>Additionally, the config file parsers now supports <strong>property inheritance directives</strong> for customizing how JSON properties get merged when using <code>"extends"</code> inheritance. This system is implemented by the <a href="https://www.npmjs.com/package/@rushstack/heft-config-file" target="_blank" rel="noopener noreferrer">@rushstack/heft-config-file</a> library, and applies to all config files that are loaded using that parser. Overrides are specified by using directives that define inheritance behavior.</p><p>For example, assume that we are extending a file with a previously defined <code>exampleObject</code> value that is a keyed object, and a <code>exampleArray</code> value that is an array object:</p><div class="language-js codeBlockContainer_sQcC theme-code-block" style="--prism-color:#000000;--prism-background-color:#ffffff"><div class="codeBlockContent_aCbw"><pre tabindex="0" class="prism-code language-js codeBlock_hdfK thin-scrollbar"><code class="codeBlockLines_lb0E"><span class="token-line" style="color:#000000"><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"$schema"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"https://developer.microsoft.com/json-schemas/heft/v0/example-config-file.schema.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"extends"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"base-project/config/example-config-file.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"$exampleObject.inheritanceType"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"merge"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(0, 128, 0)">// valid choices are: "merge", "replace"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"exampleObject"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token string-property property">"$exampleObjectMember.inheritanceType"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"merge"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(0, 128, 0)">// valid choices are: "merge", "replace"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token string-property property">"exampleObjectMember"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"> </span><span class="token spread operator" style="color:rgb(0, 0, 0)">...</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token string-property property">"$exampleArrayMember.inheritanceType"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"append"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(0, 128, 0)">// valid choices are: "append", "replace"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token string-property property">"exampleArrayMember"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"> </span><span class="token spread operator" style="color:rgb(0, 0, 0)">...</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"$exampleArray.inheritanceType"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"replace"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(0, 128, 0)">// valid choices are: "append", "replace"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token string-property property">"exampleArray"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"> </span><span class="token spread operator" style="color:rgb(0, 0, 0)">...</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain"></span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><br></span></code></pre><div class="buttonGroup_A7Vp"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_GFHe" aria-hidden="true"><svg class="copyButtonIcon_dPFB" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_Fsz1" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Once an object is set to a <code>inheritanceType</code> of override, all sub-property <code>inheritanceType</code> values will be ignored, since the top-most object already overrides all sub-properties.</p><p>One thing to note is that different <code>mergeBehavior</code> verbs are used for the merging of keyed objects and arrays. This is to make it explicit that arrays will be appended as-is, and no additional processing (eg. deduplicating if the array is intended to be a set) is done during merge. If such behavior is required, it can be done on the implementation side. Deduplicating arrays within the <code>@rushstack/heft-config-file</code> package doesn't quite make sense, since deduplicating arrays of non-primitive objects is not easily defined.</p><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="associated-npm-packages">Associated NPM packages<a href="#associated-npm-packages" class="hash-link" aria-label="Direct link to Associated NPM packages" title="Direct link to Associated NPM packages">​</a></h2><p>Many tasks that were previously built-in to have Heft have been split out into separate NPM packages. The full list:</p><ul><li><code>@rushstack/heft</code></li><li><code>@rushstack/heft-typescript-plugin</code></li><li><code>@rushstack/heft-lint-plugin</code></li><li><code>@rushstack/heft-api-extractor-plugin</code></li><li><code>@rushstack/heft-jest-plugin</code></li><li><code>@rushstack/heft-sass-plugin</code></li><li><code>@rushstack/heft-storybook-plugin</code></li><li><code>@rushstack/heft-webpack4-plugin</code></li><li><code>@rushstack/heft-webpack5-plugin</code></li><li><code>@rushstack/heft-dev-cert-plugin</code></li></ul><p>Additionally, Rushstack-provided rigs have been updated to be compatible with the new version of Heft:</p><ul><li><code>@rushstack/heft-node-rig</code></li><li><code>@rushstack/heft-web-rig</code></li></ul><h2 class="anchor anchorWithStickyNavbar_Cwtr" id="authoring-heft-plugins">Authoring Heft plugins<a href="#authoring-heft-plugins" class="hash-link" aria-label="Direct link to Authoring Heft plugins" title="Direct link to Authoring Heft plugins">​</a></h2><h3 class="anchor anchorWithStickyNavbar_Cwtr" id="lifecycle-plugins">Lifecycle plugins<a href="#lifecycle-plugins" class="hash-link" aria-label="Direct link to Lifecycle plugins" title="Direct link to Lifecycle plugins">​</a></h3><p>Heft lifecycle plugins provide the implementation for certain lifecycle-related hooks. These plugins will be used across all Heft phases, and as such should be rarely used outside of a few specific cases (such as for metrics reporting). Heft lifecycle plugins provide an <code>apply()</code> method, and here plugins can hook into the following Tapable hooks:</p><ul><li><code>toolStart</code> - Used to provide plugin-related functionality at the start of Heft execution</li><li><code>toolFinish</code> - Used to provide plugin-related functionality at the end of Heft execution, after all tasks are finished</li><li><code>recordMetrics</code> - Used to provide metrics information about the Heft run to the plugin after all tasks are finished</li></ul><h3 class="anchor anchorWithStickyNavbar_Cwtr" id="task-plugins">Task plugins<a href="#task-plugins" class="hash-link" aria-label="Direct link to Task plugins" title="Direct link to Task plugins">​</a></h3><p>Heft task plugins provide the implementation for Heft tasks. Heft plugins provide an <code>apply()</code> method, and here plugins can hook into the following Tapable hooks:</p><ul><li><code>registerFileOperations</code> - Invoked exactly once before the first time a plugin runs. Allows a plugin to register copy or delete operations using the same options as the <code>copyFiles</code> and <code>deleteFiles</code> Heft events (this hook is how those events are implemented).</li><li><code>run</code> - Used to provide plugin-related task functionality</li><li><code>runIncremental</code> - Used to provide plugin-related task functionality when in watch mode. If no <code>runIncremental</code> implementation is provided for a task, Heft will fall back to using the <code>run</code> hook as usual. The options structure includes two functions used to support watch operations:<ul><li><code>requestRun()</code> - This function asks the Heft runtime to schedule a new run of the plugin's owning task, potentially cancelling the current build.</li><li><code>watchGlobAsync(patterns, options)</code> - This function is provided for convenience for the common case of monitoring a glob for changes. It returns a <code>Map&lt;string, IWatchedFileState&gt;</code> that enumerates the list of files (or folders) selected by the glob and whether or not they have changed since the previous invocation. It will automatically invoke the <code>requestRun()</code> callback if it detects changes to files or directory listings that might impact the output of the glob.</li></ul></li></ul><h3 class="anchor anchorWithStickyNavbar_Cwtr" id="heft-pluginjson">heft-plugin.json<a href="#heft-pluginjson" class="hash-link" aria-label="Direct link to heft-plugin.json" title="Direct link to heft-plugin.json">​</a></h3><p>The <strong>heft-plugin.json</strong> config file is a new, required manifest file that must be present in the package folder of all Heft plugin packages. This file is used for multiple purposes, including the definition of all contained lifecycle or task plugins, the definition of all plugin-specific CLI parameters, and providing an optional schema file to validate plugin options that can be passed via <strong>heft.json</strong>.</p><p>The following is an example <strong>heft-plugin.json</strong> file defining a lifecycle plugin and a task plugin:</p><div class="language-json codeBlockContainer_sQcC theme-code-block" style="--prism-color:#000000;--prism-background-color:#ffffff"><div class="codeBlockContent_aCbw"><pre tabindex="0" class="prism-code language-json codeBlock_hdfK thin-scrollbar"><code class="codeBlockLines_lb0E"><span class="token-line" style="color:#000000"><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token property">"$schema"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"https://developer.microsoft.com/json-schemas/heft/v0/heft-plugin.schema.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token property">"lifecyclePlugins"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token property">"pluginName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"my-lifecycle-plugin"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token property">"entryPoint"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"./lib/MyLifecyclePlugin.js"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token property">"optionsSchema"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"./lib/schemas/mylifecycleplugin.schema.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token property">"parameterScope"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"my-lifecycle"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token property">"parameters"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token property">"parameterKind"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"string"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token property">"longName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"--my-string"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token property">"description"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"…"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token property">"argumentName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"ARG_NAME"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token property">"required"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token property">"taskPlugins"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token property">"pluginName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"my-task-plugin"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token property">"entryPoint"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"./lib/MyTaskPlugin.js"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token property">"optionsSchema"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"./lib/schemas/mytaskplugin.schema.json"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token property">"parameterScope"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"my-task"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token property">"parameters"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(4, 81, 165)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token property">"parameterKind"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"string"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token property">"longName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"--my-other-string"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token property">"description"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"…"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token property">"argumentName"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(163, 21, 21)">"ARG_NAME"</span><span class="token punctuation" style="color:rgb(4, 81, 165)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">          </span><span class="token property">"required"</span><span class="token operator" style="color:rgb(0, 0, 0)">:</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">        </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(4, 81, 165)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#000000"><span class="token plain"></span><span class="token punctuation" style="color:rgb(4, 81, 165)">}</span><br></span></code></pre><div class="buttonGroup_A7Vp"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_GFHe" aria-hidden="true"><svg class="copyButtonIcon_dPFB" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_Fsz1" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_Cwtr" id="cross-plugin-interaction">Cross-plugin interaction<a href="#cross-plugin-interaction" class="hash-link" aria-label="Direct link to Cross-plugin interaction" title="Direct link to Cross-plugin interaction">​</a></h3><p>Sometimes plugins can benefit by communicating with each other. For example, <code>@rushstack/heft-lint-plugin</code> and <code>@rushstack/heft-typescript-plugin</code> share a single TypeScript <code>ts.Program</code> object, which significantly improves build time by avoiding the need to compute the compiler's semantic analysis two times. This optimization brings a constraint that the tasks must share the same Heft phase in your <strong>heft.json</strong> configuration.</p><p>How does this work? Heft plugins can use the <code>requestAccessToPluginByName()</code> API to access the requested <strong>plugin accessors</strong>. Accessors are objects provided by plugins for external use and are the ideal place to share plugin-specific information or hooks used to provide additional plugin functionality.</p><p>Access requests are fulfilled at the beginning of phase execution, prior to <code>clean</code> hook execution. If the requested plugin does not provide an accessor, an error will be thrown noting the plugin with the missing accessor. However, if the plugin requested is not present at all, the access request will silently fail. This is done to allow for non-required integrations with external plugins. For this reason, it is important to implement cross-plugin interaction in such a way as to expect this case and to handle it gracefully, or to throw a helpful error.</p><p>Plugins available for access are restricted based on scope. For lifecycle plugins, you may request access to any other lifecycle plugin added to the Heft configuration. For task plugins, you may request access to any other task plugin residing within the same phase in the Heft configuration.</p><h3 class="anchor anchorWithStickyNavbar_Cwtr" id="custom-cli-parameters">Custom CLI parameters<a href="#custom-cli-parameters" class="hash-link" aria-label="Direct link to Custom CLI parameters" title="Direct link to Custom CLI parameters">​</a></h3><p>Defining CLI parameters is now only possible via <strong>heft-plugin.json</strong>, and defined parameters can be consumed in plugins via the <code>HeftTaskSession.parameters</code> API. Additionally, all plugin parameters for the selected Heft phases are now discoverable on the CLI when using the <code>--help</code> argument (ex. <code>heft test --help</code> or <code>heft run --to test -- --help</code>).</p><p>These parameters can be automatically "de-duped" on the CLI using an optionally-provided <code>parameterScope</code>. By default, parameters defined in <strong>heft-plugin.json</strong> will be available on the CLI using <code>--&lt;parameterName&gt;</code> and <code>--&lt;parameterScope&gt;:&lt;parameterName&gt;</code>. When multiple plugins provide the same parameter, only the latter parameter will be available on the CLI in order to "de-dupe" conflicting parameters. For example, if PluginA with parameter scope "PluginA" defines <code>--parameter</code>, and PluginB with parameter scope "PluginB" also defines <code>--parameter</code>, the parameters will <em>only</em> be available as <code>--PluginA:parameter</code> and <code>--PluginB:parameter</code>.</p><p>If you have any questions or feedback regarding these changes to Heft, please <a href="https://rushstack.zulipchat.com/#narrow/stream/262522-heft" target="_blank" rel="noopener noreferrer">ask in the chatroom</a> or <a href="https://github.com/microsoft/rushstack/issues/new?assignees=&amp;labels=&amp;template=heft.md&amp;title=%5Bheft%2Frc%2f0%5D+" target="_blank" rel="noopener noreferrer">file an issue</a>.</p>]]></content:encoded>
            <category>heft</category>
        </item>
        <item>
            <title><![CDATA[About the Rush Stack blog]]></title>
            <link>https://rushstack.io/blog/2023/06/01/blog-launch</link>
            <guid>https://rushstack.io/blog/2023/06/01/blog-launch</guid>
            <pubDate>Thu, 01 Jun 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Welcome to the Rush Stack blog! We've added this new website section for sharing news and insights]]></description>
            <content:encoded><![CDATA[<p>Welcome to the <strong>Rush Stack blog</strong>! We've added this new website section for sharing news and insights
about Rush Stack projects.</p><p>We'll announce new blog posts on <a href="https://twitter.com/rushstack" target="_blank" rel="noopener noreferrer">Twitter</a>
and <a href="https://fosstodon.org/@rushstack" target="_blank" rel="noopener noreferrer">Mastodon</a>. You can also subscribe directly to the blog's
<a href="https://rushstack.io/blog/rss.xml" target="_blank" rel="noopener noreferrer">RSS</a> or <a href="https://rushstack.io/blog/atom.xml" target="_blank" rel="noopener noreferrer">Atom</a> feeds.</p><p>Whereas the website docs are primarily reference material, blog topics may include:</p><ul><li>Announcement details</li><li>Explanations of major changes</li><li>Tips about tech to try out</li><li>Best practices</li><li>Ideas and analyses</li></ul><p>If you'd like to contribute a blog post, please contact <a href="https://github.com/octogonz" target="_blank" rel="noopener noreferrer">@octogonz</a>.</p>]]></content:encoded>
        </item>
    </channel>
</rss>