cli: remove support for --experimental-type-build
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -65,6 +65,5 @@ export async function command(opts: OptionValues): Promise<void> {
|
||||
return buildPackage({
|
||||
outputs,
|
||||
minify: Boolean(opts.minify),
|
||||
useApiExtractor: Boolean(opts.experimentalTypeBuild),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -130,10 +130,6 @@ export function registerScriptCommand(program: Command) {
|
||||
'--minify',
|
||||
'Minify the generated code. Does not apply to app or backend packages.',
|
||||
)
|
||||
.option(
|
||||
'--experimental-type-build',
|
||||
'Enable experimental type build. Does not apply to app or backend packages. [DEPRECATED]',
|
||||
)
|
||||
.option(
|
||||
'--skip-build-dependencies',
|
||||
'Skip the automatic building of local dependencies. Applies to backend packages only.',
|
||||
|
||||
@@ -49,9 +49,6 @@ export async function command() {
|
||||
if (scripts.build?.includes('--minify')) {
|
||||
buildCmd.push('--minify');
|
||||
}
|
||||
if (scripts.build?.includes('--experimental-type-build')) {
|
||||
buildCmd.push('--experimental-type-build');
|
||||
}
|
||||
if (scripts.build?.includes('--config')) {
|
||||
buildCmd.push(...(scripts.build.match(configArgPattern) ?? []));
|
||||
}
|
||||
|
||||
@@ -137,7 +137,6 @@ export async function command(opts: OptionValues, cmd: Command): Promise<void> {
|
||||
outputs,
|
||||
logPrefix: `${chalk.cyan(relativePath(paths.targetRoot, pkg.dir))}: `,
|
||||
minify: buildOptions.minify,
|
||||
useApiExtractor: buildOptions.experimentalTypeBuild,
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import fs from 'fs-extra';
|
||||
import chalk from 'chalk';
|
||||
import { relative as relativePath, resolve as resolvePath } from 'path';
|
||||
import { paths } from '../paths';
|
||||
import { buildTypeDefinitionsWorker } from './buildTypeDefinitionsWorker';
|
||||
import { runWorkerThreads } from '../parallel';
|
||||
|
||||
// These message types are ignored since we want to avoid duplicating the logic of
|
||||
// handling them correctly, and we already have the API Reports warning about them.
|
||||
const ignoredMessages = new Set(['tsdoc-undefined-tag', 'ae-forgotten-export']);
|
||||
|
||||
export async function buildTypeDefinitions(
|
||||
targetDirs: string[] = [paths.targetDir],
|
||||
) {
|
||||
const packageDirs = targetDirs.map(dir =>
|
||||
relativePath(paths.targetRoot, dir),
|
||||
);
|
||||
const entryPoints = await Promise.all(
|
||||
packageDirs.map(async dir => {
|
||||
const entryPoint = paths.resolveTargetRoot(
|
||||
'dist-types',
|
||||
dir,
|
||||
'src/index.d.ts',
|
||||
);
|
||||
|
||||
const declarationsExist = await fs.pathExists(entryPoint);
|
||||
if (!declarationsExist) {
|
||||
throw new Error(
|
||||
`No declaration files found at ${entryPoint}, be sure to run ${chalk.bgRed.white(
|
||||
'yarn tsc',
|
||||
)} to generate .d.ts files before packaging`,
|
||||
);
|
||||
}
|
||||
return entryPoint;
|
||||
}),
|
||||
);
|
||||
|
||||
const workerConfigs = packageDirs.map(packageDir => {
|
||||
const targetDir = paths.resolveTargetRoot(packageDir);
|
||||
const targetTypesDir = paths.resolveTargetRoot('dist-types', packageDir);
|
||||
const extractorOptions = {
|
||||
configObject: {
|
||||
mainEntryPointFilePath: resolvePath(targetTypesDir, 'src/index.d.ts'),
|
||||
bundledPackages: [],
|
||||
|
||||
compiler: {
|
||||
skipLibCheck: true,
|
||||
tsconfigFilePath: paths.resolveTargetRoot('tsconfig.json'),
|
||||
},
|
||||
|
||||
dtsRollup: {
|
||||
enabled: true,
|
||||
untrimmedFilePath: resolvePath(targetDir, 'dist/index.alpha.d.ts'),
|
||||
betaTrimmedFilePath: resolvePath(targetDir, 'dist/index.beta.d.ts'),
|
||||
publicTrimmedFilePath: resolvePath(targetDir, 'dist/index.d.ts'),
|
||||
},
|
||||
|
||||
newlineKind: 'lf',
|
||||
|
||||
projectFolder: targetDir,
|
||||
},
|
||||
configObjectFullPath: targetDir,
|
||||
packageJsonFullPath: resolvePath(targetDir, 'package.json'),
|
||||
};
|
||||
return { extractorOptions, targetTypesDir };
|
||||
});
|
||||
|
||||
const typescriptDir = paths.resolveTargetRoot('node_modules/typescript');
|
||||
const hasTypescript = await fs.pathExists(typescriptDir);
|
||||
const typescriptCompilerFolder = hasTypescript ? typescriptDir : undefined;
|
||||
await runWorkerThreads({
|
||||
threadCount: 1,
|
||||
workerData: {
|
||||
entryPoints,
|
||||
workerConfigs,
|
||||
typescriptCompilerFolder,
|
||||
},
|
||||
worker: buildTypeDefinitionsWorker,
|
||||
onMessage: ({
|
||||
message,
|
||||
targetTypesDir,
|
||||
}: {
|
||||
message: any;
|
||||
targetTypesDir: string;
|
||||
}) => {
|
||||
if (ignoredMessages.has(message.messageId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let text = `${message.text} (${message.messageId})`;
|
||||
if (message.sourceFilePath) {
|
||||
text += ' at ';
|
||||
text += relativePath(targetTypesDir, message.sourceFilePath);
|
||||
if (message.sourceFileLine) {
|
||||
text += `:${message.sourceFileLine}`;
|
||||
if (message.sourceFileColumn) {
|
||||
text += `:${message.sourceFileColumn}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (message.logLevel === 'error') {
|
||||
console.error(chalk.red(`Error: ${text}`));
|
||||
} else if (
|
||||
message.logLevel === 'warning' ||
|
||||
message.category === 'Extractor'
|
||||
) {
|
||||
console.warn(`Warning: ${text}`);
|
||||
} else {
|
||||
console.log(text);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* NOTE: This is a worker thread function that is stringified and executed
|
||||
* within a `worker_threads.Worker`. Everything in this function must
|
||||
* be self-contained.
|
||||
* Using TypeScript is fine as it is transpiled before being stringified.
|
||||
*/
|
||||
export async function buildTypeDefinitionsWorker(
|
||||
workerData: any,
|
||||
sendMessage: (message: any) => void,
|
||||
) {
|
||||
try {
|
||||
require('@microsoft/api-extractor');
|
||||
} catch (error) {
|
||||
throw new Error(
|
||||
'Failed to resolve @microsoft/api-extractor, it must best installed ' +
|
||||
'as a dependency of your project in order to use experimental type builds',
|
||||
);
|
||||
}
|
||||
|
||||
const { dirname } = require('path');
|
||||
const { entryPoints, workerConfigs, typescriptCompilerFolder } = workerData;
|
||||
|
||||
const apiExtractor = require('@microsoft/api-extractor');
|
||||
const { Extractor, ExtractorConfig, CompilerState } = apiExtractor;
|
||||
|
||||
/**
|
||||
* All of this monkey patching below is because Material UI has these bare package.json file as a method
|
||||
* for making TypeScript accept imports like `@material-ui/core/Button`, and improve tree-shaking
|
||||
* by declaring them side effect free.
|
||||
*
|
||||
* The package.json lookup logic in api-extractor really doesn't like that though, as it enforces
|
||||
* that the 'name' field exists in all package.json files that it discovers. This below is just
|
||||
* making sure that we ignore those file package.json files instead of crashing.
|
||||
*/
|
||||
const {
|
||||
PackageJsonLookup,
|
||||
// eslint-disable-next-line @backstage/no-undeclared-imports
|
||||
} = require('@rushstack/node-core-library/lib/PackageJsonLookup');
|
||||
|
||||
const old = PackageJsonLookup.prototype.tryGetPackageJsonFilePathFor;
|
||||
PackageJsonLookup.prototype.tryGetPackageJsonFilePathFor =
|
||||
function tryGetPackageJsonFilePathForPatch(path: string) {
|
||||
if (
|
||||
path.includes('@material-ui') &&
|
||||
!dirname(path).endsWith('@material-ui')
|
||||
) {
|
||||
return undefined;
|
||||
}
|
||||
return old.call(this, path);
|
||||
};
|
||||
|
||||
let compilerState;
|
||||
for (const { extractorOptions, targetTypesDir } of workerConfigs) {
|
||||
const extractorConfig = ExtractorConfig.prepare(extractorOptions);
|
||||
|
||||
if (!compilerState) {
|
||||
compilerState = CompilerState.create(extractorConfig, {
|
||||
additionalEntryPoints: entryPoints,
|
||||
});
|
||||
}
|
||||
|
||||
const extractorResult = Extractor.invoke(extractorConfig, {
|
||||
compilerState,
|
||||
localBuild: false,
|
||||
typescriptCompilerFolder,
|
||||
showVerboseMessages: false,
|
||||
showDiagnostics: false,
|
||||
messageCallback: (message: any) => {
|
||||
message.handled = true;
|
||||
sendMessage({ message, targetTypesDir });
|
||||
},
|
||||
});
|
||||
|
||||
if (!extractorResult.succeeded) {
|
||||
throw new Error(
|
||||
`Type definition build completed with ${extractorResult.errorCount} errors` +
|
||||
` and ${extractorResult.warningCount} warnings`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,7 +151,7 @@ export async function makeRollupConfigs(
|
||||
});
|
||||
}
|
||||
|
||||
if (options.outputs.has(Output.types) && !options.useApiExtractor) {
|
||||
if (options.outputs.has(Output.types)) {
|
||||
const input = Object.fromEntries(
|
||||
scriptEntryPoints.map(e => [
|
||||
e.name,
|
||||
|
||||
@@ -21,7 +21,6 @@ import { relative as relativePath, resolve as resolvePath } from 'path';
|
||||
import { paths } from '../paths';
|
||||
import { makeRollupConfigs } from './config';
|
||||
import { BuildOptions, Output } from './types';
|
||||
import { buildTypeDefinitions } from './buildTypeDefinitions';
|
||||
import { PackageRoles } from '@backstage/cli-node';
|
||||
import { runParallelWorkers } from '../parallel';
|
||||
|
||||
@@ -112,10 +111,6 @@ export const buildPackage = async (options: BuildOptions) => {
|
||||
|
||||
const buildTasks = rollupConfigs.map(rollupBuild);
|
||||
|
||||
if (options.outputs.has(Output.types) && options.useApiExtractor) {
|
||||
buildTasks.push(buildTypeDefinitions());
|
||||
}
|
||||
|
||||
await Promise.all(buildTasks);
|
||||
};
|
||||
|
||||
@@ -131,18 +126,6 @@ export const buildPackages = async (options: BuildOptions[]) => {
|
||||
|
||||
const buildTasks = rollupConfigs.flat().map(opts => () => rollupBuild(opts));
|
||||
|
||||
const typeDefinitionTargetDirs = options
|
||||
.filter(
|
||||
({ outputs, useApiExtractor }) =>
|
||||
outputs.has(Output.types) && useApiExtractor,
|
||||
)
|
||||
.map(_ => _.targetDir!);
|
||||
|
||||
if (typeDefinitionTargetDirs.length > 0) {
|
||||
// Make sure this one is started first
|
||||
buildTasks.unshift(() => buildTypeDefinitions(typeDefinitionTargetDirs));
|
||||
}
|
||||
|
||||
await runParallelWorkers({
|
||||
items: buildTasks,
|
||||
worker: async task => task(),
|
||||
|
||||
@@ -28,5 +28,4 @@ export type BuildOptions = {
|
||||
packageJson?: BackstagePackageJson;
|
||||
outputs: Set<Output>;
|
||||
minify?: boolean;
|
||||
useApiExtractor?: boolean;
|
||||
};
|
||||
|
||||
@@ -206,7 +206,6 @@ export async function createDistWorkspace(
|
||||
logPrefix: `${chalk.cyan(relativePath(paths.targetRoot, pkg.dir))}: `,
|
||||
// No need to detect these for the backend builds, we assume no minification or types
|
||||
minify: false,
|
||||
useApiExtractor: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user