Skip to content

Commit

Permalink
new: Support different declaration type outputs. (#9)
Browse files Browse the repository at this point in the history
* Start on decl types.

* Polish.
  • Loading branch information
milesj authored Nov 13, 2020
1 parent f448f50 commit 3e44964
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 48 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"scripts": {
"prepare": "beemo create-config --silent",
"setup": "beemo typescript",
"build": "NODE_ENV=production yarn run packemon build --addEngines --generateDeclaration",
"build": "NODE_ENV=production yarn run packemon build --addEngines --generateDeclaration=api",
"build:fast": "yarn run packemon build",
"validate": "yarn run packemon validate",
"ci": "yarn run type && yarn run test && yarn run lint",
"clean": "rm -rf {build,dts,lib}",
Expand Down
6 changes: 3 additions & 3 deletions src/BundleArtifact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { rollup, RollupCache } from 'rollup';
import Artifact from './Artifact';
import { NODE_SUPPORTED_VERSIONS, NPM_SUPPORTED_VERSIONS } from './constants';
import { getRollupConfig } from './rollup/config';
import { Format, BuildOptions, BundleBuild, Support, Platform, AnalyzeType } from './types';
import { Format, BuildOptions, BundleBuild, Support, Platform } from './types';

const debug = createDebugger('packemon:bundle');

Expand Down Expand Up @@ -67,8 +67,8 @@ export default class BundleArtifact extends Artifact<BundleBuild> {

const features = this.package.getFeatureFlags();

if (options.analyzeBundle) {
features.analyze = options.analyzeBundle as AnalyzeType;
if (options.analyzeBundle !== 'none') {
features.analyze = options.analyzeBundle;
}

const { output = [], ...input } = getRollupConfig(this, features);
Expand Down
19 changes: 12 additions & 7 deletions src/Packemon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,23 @@ import { createDebugger } from '@boost/debug';
import { Event } from '@boost/event';
import { PooledPipeline, Context } from '@boost/pipeline';
import Package from './Package';
import PackageValidator from './PackageValidator';
import Project from './Project';
import BundleArtifact from './BundleArtifact';
import TypesArtifact from './TypesArtifact';
import {
AnalyzeType,
BrowserFormat,
BuildOptions,
DeclarationType,
Format,
NodeFormat,
BuildOptions,
PackemonPackage,
PackemonPackageConfig,
Platform,
TypesBuild,
ValidateOptions,
} from './types';
import PackageValidator from './PackageValidator';

const debug = createDebugger('packemon:core');
const { array, bool, custom, number, object, string, union } = predicates;
Expand Down Expand Up @@ -80,9 +82,9 @@ export default class Packemon {
const options = optimal(baseOptions, {
addEngines: bool(),
addExports: bool(),
analyzeBundle: string().oneOf(['', 'sunburst', 'treemap', 'network']),
analyzeBundle: string('none').oneOf<AnalyzeType>(['none', 'sunburst', 'treemap', 'network']),
concurrency: number(1).gte(1),
generateDeclaration: bool(),
generateDeclaration: string('none').oneOf<DeclarationType>(['none', 'standard', 'api']),
skipPrivate: bool(),
timeout: number().gte(0),
});
Expand Down Expand Up @@ -245,7 +247,7 @@ export default class Packemon {
this.packages = this.validateAndPreparePackages(packages);
}

protected generateArtifacts(declarations: boolean) {
protected generateArtifacts(declarationType: DeclarationType) {
debug('Generating build artifacts for packages');

this.packages.forEach((pkg) => {
Expand Down Expand Up @@ -275,8 +277,11 @@ export default class Packemon {
});
});

if (declarations) {
pkg.addArtifact(new TypesArtifact(pkg, typesBuilds));
if (declarationType !== 'none') {
const artifact = new TypesArtifact(pkg, typesBuilds);
artifact.declarationType = declarationType;

pkg.addArtifact(artifact);
}

debug('\t%s - %s', pkg.getName(), pkg.artifacts.join(', '));
Expand Down
8 changes: 7 additions & 1 deletion src/Project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@ export default class Project extends BaseProject {
'--force',
);
} else {
args.push('--declaration', '--declarationMap', '--emitDeclarationOnly');
args.push(
'--declaration',
'--declarationDir',
'dts',
'--declarationMap',
'--emitDeclarationOnly',
);
}

// Store the promise so parallel artifacts can rely on the same build
Expand Down
39 changes: 22 additions & 17 deletions src/TypesArtifact.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Path } from '@boost/common';
import { createDebugger } from '@boost/debug';
import { Extractor, ExtractorConfig } from '@microsoft/api-extractor';
import Artifact from './Artifact';
import { APIExtractorStructure, TypesBuild } from './types';
import { APIExtractorStructure, DeclarationType, TypesBuild } from './types';

const debug = createDebugger('packemon:types');

Expand All @@ -19,6 +19,8 @@ const extractorConfig = require(path.join(__dirname, '../api-extractor.json')) a
};

export default class TypesArtifact extends Artifact<TypesBuild> {
declarationType: DeclarationType = 'standard';

async cleanup(): Promise<void> {
// API extractor config files
await this.removeFiles(
Expand All @@ -27,32 +29,35 @@ export default class TypesArtifact extends Artifact<TypesBuild> {
}

async build(): Promise<void> {
debug('Building types artifact with TypeScript');
debug('Building %s types artifact with TypeScript', this.declarationType);

const tsConfig = this.package.tsconfigJson;

// Resolved compiler options use absolute paths, so we should match
const declBuildPath = tsConfig
? new Path(tsConfig.options.declarationDir || tsConfig.options.outDir!)
: this.package.path.append('lib');

// Compile the current projects declarations
debug('Generating declarations at the root using `tsc`');

await this.package.project.generateDeclarations();

// Combine all DTS files into a single file for each input
debug('Combining declarations into a single API declaration file');
if (this.declarationType === 'api') {
debug('Combining declarations into a single API declaration file');

await Promise.all(
this.builds.map(({ inputPath, outputName }) =>
this.generateDeclaration(outputName, inputPath, declBuildPath),
),
);
// Resolved compiler options use absolute paths, so we should match
let declBuildPath = this.package.path.append('dts');

// Workspaces use the tsconfig setting, while non-workspaces is hard-coded to "dts"
if (tsConfig && this.package.project.isWorkspacesEnabled()) {
declBuildPath = new Path(tsConfig.options.declarationDir || tsConfig.options.outDir!);
}

await Promise.all(
this.builds.map(({ inputPath, outputName }) =>
this.generateApiDeclaration(outputName, inputPath, declBuildPath),
),
);

// Remove the TS output directory to reduce package size.
// We do this in the background to speed up the CLI process!
if (this.package.project.isWorkspacesEnabled()) {
// Remove the TS output directory to reduce package size.
// We do this in the background to speed up the CLI process!
debug('Removing old and unnecessary declarations in the background');

void this.removeDeclarationBuild(declBuildPath);
Expand All @@ -75,7 +80,7 @@ export default class TypesArtifact extends Artifact<TypesBuild> {
return `types (dts)`;
}

protected async generateDeclaration(
protected async generateApiDeclaration(
outputName: string,
inputPath: string,
declBuildPath: Path,
Expand Down
14 changes: 8 additions & 6 deletions src/commands/Build.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import os from 'os';
import { Arg, Command, Config, GlobalOptions } from '@boost/cli';
import Build from '../components/Build';
import Packemon from '../Packemon';
import { BuildOptions } from '../types';
import { AnalyzeType, BuildOptions, DeclarationType } from '../types';

export type BuildParams = [string];

@Config('build', 'Build standardized packages for distribution.')
@Config('build', 'Build standardized packages for distribution')
export class BuildCommand extends Command<GlobalOptions & BuildOptions, BuildParams> {
@Arg.Flag('Add `engine` versions to each `package.json`')
addEngines: boolean = false;
Expand All @@ -16,15 +16,17 @@ export class BuildCommand extends Command<GlobalOptions & BuildOptions, BuildPar
addExports: boolean = false;

@Arg.String('Visualize and analyze all generated builds', {
choices: ['sunburst', 'treemap', 'network'],
choices: ['none', 'sunburst', 'treemap', 'network'],
})
analyze: string = '';
analyze: AnalyzeType = 'none';

@Arg.Number('Number of builds to run in parallel')
concurrency: number = os.cpus().length;

@Arg.Flag('Generate a single TypeScript declaration for each package input')
generateDeclaration: boolean = false;
@Arg.String('Generate a single TypeScript declaration for each package input', {
choices: ['none', 'standard', 'api'],
})
generateDeclaration: DeclarationType = 'none';

@Arg.Flag('Skip `private` packages from being built')
skipPrivate: boolean = false;
Expand Down
2 changes: 1 addition & 1 deletion src/commands/Clean.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Packemon from '../Packemon';

export type CleanParams = [string];

@Config('clean', 'Clean build artifacts from packages.')
@Config('clean', 'Clean build artifacts from packages')
export class CleanCommand extends Command<GlobalOptions, CleanParams> {
@Arg.Params<CleanParams>({
description: 'Project root that contains a `package.json`',
Expand Down
2 changes: 1 addition & 1 deletion src/commands/Validate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Validate from '../components/Validate';

export type ValidateParams = [string];

@Config('validate', 'Validate package metadata and configuration.')
@Config('validate', 'Validate package metadata and configuration')
export class ValidateCommand extends Command<GlobalOptions & ValidateOptions, ValidateParams> {
@Arg.Flag('Check that dependencies have valid versions and constraints')
deps: boolean = true;
Expand Down
10 changes: 5 additions & 5 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ export type NodeFormat =

export type Format = NodeFormat | BrowserFormat;

export type AnalyzeType = 'sunburst' | 'treemap' | 'network';
export type AnalyzeType = 'none' | 'sunburst' | 'treemap' | 'network';

export type DeclarationType = 'none' | 'standard' | 'api';

// PACKAGES

Expand Down Expand Up @@ -61,14 +63,12 @@ export interface PackageConfig {

export type ArtifactState = 'pending' | 'building' | 'passed' | 'failed';

export type BuildDeclarationType = 'standard' | 'api';

export interface BuildOptions {
addEngines: boolean;
addExports: boolean;
analyzeBundle: string;
analyzeBundle: AnalyzeType;
concurrency: number;
generateDeclaration: boolean;
generateDeclaration: DeclarationType;
skipPrivate: boolean;
timeout: number;
}
Expand Down
17 changes: 11 additions & 6 deletions website/docs/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ to their configured build targets (platform, formats, etc).
```json title="package.json"
{
"scripts": {
"build:internal": "packemon build --addEngines --generateDeclaration",
"build:internal": "packemon build --addEngines --generateDeclaration=api",
"build": "NODE_ENV=production yarn run build:internal",
"release": "yarn run build && yarn publish"
}
Expand All @@ -34,12 +34,17 @@ Build supports the following command line options.
setting. This is an experimental Node.js feature and may not work correctly
([more information](https://nodejs.org/api/packages.html#packages_package_entry_points)).
- `--analyze` - Analyze and visualize all generated builds. Will open a browser visualization for
each bundle in one of the following formats: `sunburst`, `treemap`, `network`.
each bundle in one of the following formats.
- `sunburst` - Displays an inner circle surrounded by rings of deeper hierarchy levels.
- `treemap` - Displays hierarchy levels as top-level and nested rectangles of varying size.
- `network` - Displays files as nodes with the relationship between files.
- `--concurrency` - Number of builds to run in parallel. Defaults to operating system CPU count.
- `--generateDeclaration` - Generate a single TypeScript declaration for each package according to
the `inputs` setting. Uses
[@microsoft/api-extractor](https://www.npmjs.com/package/@microsoft/api-extractor) to _only_
generate the public API.
- `--generateDeclaration` - Generate TypeScript declarations for each package. Accepts one of the
following values.
- `standard` - Generates multiple `d.ts` files with `tsc`.
- `api` - Generates a single `d.ts` file for each input. Uses
[@microsoft/api-extractor](https://www.npmjs.com/package/@microsoft/api-extractor) to _only_
generate the public API. (NOTE: this is quite slow)
- `--skipPrivate` - Skip `private` packages from being built.
- `--timeout` - Timeout in milliseconds before a build is cancelled. Defaults to no timeout.

Expand Down

0 comments on commit 3e44964

Please sign in to comment.