Skip to content

Commit

Permalink
Merge pull request #2039 from iclanton/ianc/heft-ae-config
Browse files Browse the repository at this point in the history
[Heft] Make API Extractor's typescriptCompilerFolder option configurable.
  • Loading branch information
iclanton authored Jul 20, 2020
2 parents 26e3a9d + 8eb7e96 commit 0a1705e
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 8 deletions.
1 change: 1 addition & 0 deletions apps/heft/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export {
BundleSubstageHooks,
CompileSubstageHooks,
CopyFromCacheMode,
IApiExtractorConfiguration,
IBuildStageContext,
IBuildStageProperties,
IBuildSubstage,
Expand Down
16 changes: 14 additions & 2 deletions apps/heft/src/plugins/ApiExtractorPlugin/ApiExtractorPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const CONFIG_FILE_LOCATION: string = './config/api-extractor.json';

interface IRunApiExtractorOptions {
heftConfiguration: HeftConfiguration;
useProjectTypescriptVersion: boolean;
buildFolder: string;
debugMode: boolean;
watchMode: boolean;
Expand All @@ -32,6 +33,8 @@ export class ApiExtractorPlugin implements IHeftPlugin {
bundle.hooks.run.tapPromise(PLUGIN_NAME, async () => {
await this._runApiExtractorAsync({
heftConfiguration,
useProjectTypescriptVersion: !!bundle.properties.apiExtractorConfiguration
.useProjectTypescriptVersion,
buildFolder,
debugMode: heftSession.debugMode,
watchMode: build.properties.watchMode,
Expand All @@ -44,7 +47,14 @@ export class ApiExtractorPlugin implements IHeftPlugin {
}

private async _runApiExtractorAsync(options: IRunApiExtractorOptions): Promise<void> {
const { heftConfiguration, buildFolder, debugMode, watchMode, production } = options;
const {
heftConfiguration,
useProjectTypescriptVersion,
buildFolder,
debugMode,
watchMode,
production
} = options;

const terminal: Terminal = ApiExtractorRunner.getTerminal(heftConfiguration.terminalProvider);

Expand All @@ -62,7 +72,9 @@ export class ApiExtractorPlugin implements IHeftPlugin {
{
configFileLocation: CONFIG_FILE_LOCATION,
apiExtractorPackagePath: heftConfiguration.compilerPackage.apiExtractorPackagePath,
typescriptPackagePath: heftConfiguration.compilerPackage.typeScriptPackagePath,
typescriptPackagePath: useProjectTypescriptVersion
? heftConfiguration.compilerPackage.typeScriptPackagePath
: undefined,
buildFolder: buildFolder,
production: production
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface IApiExtractorRunnerConfiguration {
*
* For example, /home/username/code/repo/project/node_modules/typescript
*/
typescriptPackagePath: string;
typescriptPackagePath: string | undefined;

/**
* The folder of the project being built
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
IBuildStageContext,
ITypeScriptConfiguration,
ICopyStaticAssetsConfiguration,
IBundleSubstageProperties
IBundleSubstageProperties,
IApiExtractorConfiguration
} from '../../stages/BuildStage';
import { ICleanStageContext, ICleanStageProperties } from '../../stages/CleanStage';

Expand Down Expand Up @@ -76,6 +77,11 @@ export abstract class JsonConfigurationFilesPluginBase implements IHeftPlugin {
bundle.hooks.configureWebpack.tapPromise(this.displayName, async () => {
await this._updateWebpackConfigurationAsync(heftConfiguration, bundle.properties);
});

bundle.hooks.configureApiExtractor.tapPromise(this.displayName, async (existingConfiguration) => {
await this._updateApiExtractorConfigurationAsync(heftConfiguration, existingConfiguration);
return existingConfiguration;
});
});
});
}
Expand Down Expand Up @@ -186,6 +192,20 @@ export abstract class JsonConfigurationFilesPluginBase implements IHeftPlugin {
}
}

private async _updateApiExtractorConfigurationAsync(
heftConfiguration: HeftConfiguration,
apiExtractorConfiguration: IApiExtractorConfiguration
): Promise<void> {
const apiExtractorConfigurationJson:
| IApiExtractorConfiguration
| undefined = await this._getConfigDataByNameAsync(heftConfiguration, 'api-extractor');

if (apiExtractorConfigurationJson?.useProjectTypescriptVersion !== undefined) {
apiExtractorConfiguration.useProjectTypescriptVersion =
apiExtractorConfigurationJson.useProjectTypescriptVersion;
}
}

private async _getConfigDataByNameAsync<TConfigJson extends IConfigurationJsonBase>(
heftConfiguration: HeftConfiguration,
configFilename: string
Expand Down
20 changes: 20 additions & 0 deletions apps/heft/src/schemas/api-extractor.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "API Extractor Task Configuration",
"description": "Defines the heft configuration for the API Extractor task.",
"type": "object",

"additionalProperties": false,

"properties": {
"$schema": {
"description": "Part of the JSON Schema standard, this optional keyword declares the URL of the schema that the file conforms to. Editors may download the schema and use it to perform syntax highlighting.",
"type": "string"
},

"useProjectTypescriptVersion": {
"type": "boolean",
"description": "If set to true, use the project's TypeScript compiler version for API Extractor's analysis. API Extractor's included TypeScript compiler can generally correctly analyze typings generated by older compilers, and referencing the project's compiler can cause issues. If issues are encountered with API Extractor's included compiler, set this option to true. This corresponds to API Extractor's --typescript-compiler-folder CLI option and IExtractorInvokeOptions.typescriptCompilerFolder API option. This option defaults to false."
}
}
}
47 changes: 43 additions & 4 deletions apps/heft/src/stages/BuildStage.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.

import { SyncHook, AsyncParallelHook, AsyncSeriesHook } from 'tapable';
import { SyncHook, AsyncParallelHook, AsyncSeriesHook, AsyncSeriesWaterfallHook } from 'tapable';
import * as webpack from 'webpack';

import { StageBase, StageHooksBase, IStageContext } from './StageBase';
Expand Down Expand Up @@ -123,6 +123,23 @@ export interface ITypeScriptConfiguration extends ISharedTypeScriptConfiguration
isLintingEnabled: boolean | undefined;
}

/**
* @public
*/
export interface IApiExtractorConfiguration {
/**
* If set to true, use the project's TypeScript compiler version for API Extractor's
* analysis. API Extractor's included TypeScript compiler can generally correctly
* analyze typings generated by older compilers, and referencing the project's compiler
* can cause issues. If issues are encountered with API Extractor's included compiler,
* set this option to true.
*
* This corresponds to API Extractor's `--typescript-compiler-folder` CLI option and
* `IExtractorInvokeOptions.typescriptCompilerFolder` API option. This option defaults to false.
*/
useProjectTypescriptVersion?: boolean;
}

/**
* @public
*/
Expand All @@ -140,6 +157,10 @@ export class CompileSubstageHooks extends BuildSubstageHooksBase {
export class BundleSubstageHooks extends BuildSubstageHooksBase {
public readonly configureWebpack: AsyncSeriesHook = new AsyncSeriesHook();
public readonly afterConfigureWebpack: AsyncSeriesHook = new AsyncSeriesHook();

public readonly configureApiExtractor: AsyncSeriesWaterfallHook<
IApiExtractorConfiguration
> = new AsyncSeriesWaterfallHook<IApiExtractorConfiguration>(['apiExtractorConfiguration']);
}

/**
Expand All @@ -154,6 +175,8 @@ export interface ICompileSubstageProperties {
* @public
*/
export interface IBundleSubstageProperties {
apiExtractorConfiguration: IApiExtractorConfiguration;

/**
* A path to a Webpack configuration JS file. If this isn't specified, and a Webpack
* configuration isn't specified via another plugin, Webpack won't be run.
Expand Down Expand Up @@ -336,7 +359,9 @@ export class BuildStage extends StageBase<BuildStageHooks, IBuildStageProperties

const bundleStage: IBundleSubstage = {
hooks: new BundleSubstageHooks(),
properties: {}
properties: {
apiExtractorConfiguration: {}
}
};
this.stageHooks.bundle.call(bundleStage);

Expand All @@ -354,7 +379,13 @@ export class BuildStage extends StageBase<BuildStageHooks, IBuildStageProperties
await Promise.all([
compileStage.hooks.configureTypeScript.promise(),
compileStage.hooks.configureCopyStaticAssets.promise(),
bundleStage.hooks.configureWebpack.promise()
bundleStage.hooks.configureWebpack.promise(),
bundleStage.hooks.configureApiExtractor
.promise(bundleStage.properties.apiExtractorConfiguration)
.then(
(apiExtractorConfiguration) =>
(bundleStage.properties.apiExtractorConfiguration = apiExtractorConfiguration)
)
]);
await Promise.all([
compileStage.hooks.afterConfigureTypeScript.promise(),
Expand Down Expand Up @@ -384,7 +415,15 @@ export class BuildStage extends StageBase<BuildStageHooks, IBuildStageProperties
}
await this._runSubstageWithLoggingAsync('Compile', compileStage);

await bundleStage.hooks.configureWebpack.promise();
await Promise.all([
bundleStage.hooks.configureWebpack.promise(),
bundleStage.hooks.configureApiExtractor
.promise(bundleStage.properties.apiExtractorConfiguration)
.then(
(apiExtractorConfiguration) =>
(bundleStage.properties.apiExtractorConfiguration = apiExtractorConfiguration)
)
]);
await bundleStage.hooks.afterConfigureWebpack.promise();
await this._runSubstageWithLoggingAsync('Bundle', bundleStage);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@rushstack/heft",
"comment": "Make API Extractor's typescriptCompilerFolder option configurable.",
"type": "minor"
}
],
"packageName": "@rushstack/heft",
"email": "[email protected]"
}
10 changes: 10 additions & 0 deletions common/reviews/api/heft.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { AsyncParallelHook } from 'tapable';
import { AsyncSeriesBailHook } from 'tapable';
import { AsyncSeriesHook } from 'tapable';
import { AsyncSeriesWaterfallHook } from 'tapable';
import { CommandLineAction } from '@rushstack/ts-command-line';
import { CommandLineFlagParameter } from '@rushstack/ts-command-line';
import { CommandLineIntegerParameter } from '@rushstack/ts-command-line';
Expand Down Expand Up @@ -40,6 +41,8 @@ export class BundleSubstageHooks extends BuildSubstageHooksBase {
// (undocumented)
readonly afterConfigureWebpack: AsyncSeriesHook;
// (undocumented)
readonly configureApiExtractor: AsyncSeriesWaterfallHook<IApiExtractorConfiguration>;
// (undocumented)
readonly configureWebpack: AsyncSeriesHook;
}

Expand Down Expand Up @@ -95,6 +98,11 @@ export class HeftSession {
readonly metricsCollector: _MetricsCollector;
}

// @public (undocumented)
export interface IApiExtractorConfiguration {
useProjectTypescriptVersion?: boolean;
}

// @public (undocumented)
export interface IBuildStageContext extends IStageContext<BuildStageHooks, IBuildStageProperties> {
}
Expand Down Expand Up @@ -131,6 +139,8 @@ export interface IBundleSubstage extends IBuildSubstage<BundleSubstageHooks, IBu

// @public (undocumented)
export interface IBundleSubstageProperties {
// (undocumented)
apiExtractorConfiguration: IApiExtractorConfiguration;
webpackConfigFilePath?: string;
webpackConfiguration?: webpack.Configuration;
}
Expand Down

0 comments on commit 0a1705e

Please sign in to comment.