diff --git a/.changeset/stupid-toes-complain.md b/.changeset/stupid-toes-complain.md new file mode 100644 index 0000000000..246dce3af1 --- /dev/null +++ b/.changeset/stupid-toes-complain.md @@ -0,0 +1,5 @@ +--- +'@backstage/cli': patch +--- + +The build commands now support the new `backstage.inline` flag in `package.json`, which causes the contents of private packages to be inlined into the consuming package, rather than be treated as an external dependency. diff --git a/packages/cli/src/commands/build/buildBackend.ts b/packages/cli/src/commands/build/buildBackend.ts index 3609e40eb5..88d322d482 100644 --- a/packages/cli/src/commands/build/buildBackend.ts +++ b/packages/cli/src/commands/build/buildBackend.ts @@ -21,6 +21,7 @@ import tar, { CreateOptions } from 'tar'; import { createDistWorkspace } from '../../lib/packager'; import { getEnvironmentParallelism } from '../../lib/parallel'; import { buildPackage, Output } from '../../lib/builder'; +import { PackageGraph } from '@backstage/cli-node'; const BUNDLE_FILE = 'bundle.tar.gz'; const SKELETON_FILE = 'skeleton.tar.gz'; @@ -42,6 +43,7 @@ export async function buildBackend(options: BuildBackendOptions) { packageJson: pkg, outputs: new Set([Output.cjs]), minify, + workspacePackages: await PackageGraph.listTargetPackages(), }); const tmpDir = await fs.mkdtemp(resolvePath(os.tmpdir(), 'backstage-bundle')); diff --git a/packages/cli/src/commands/build/command.ts b/packages/cli/src/commands/build/command.ts index c0ad3c912b..a5f7f60971 100644 --- a/packages/cli/src/commands/build/command.ts +++ b/packages/cli/src/commands/build/command.ts @@ -17,7 +17,7 @@ import { OptionValues } from 'commander'; import { buildPackage, Output } from '../../lib/builder'; import { findRoleFromCommand } from '../../lib/role'; -import { PackageRoles } from '@backstage/cli-node'; +import { PackageGraph, PackageRoles } from '@backstage/cli-node'; import { paths } from '../../lib/paths'; import { buildFrontend } from './buildFrontend'; import { buildBackend } from './buildBackend'; @@ -82,5 +82,6 @@ export async function command(opts: OptionValues): Promise { return buildPackage({ outputs, minify: Boolean(opts.minify), + workspacePackages: await PackageGraph.listTargetPackages(), }); } diff --git a/packages/cli/src/commands/repo/build.ts b/packages/cli/src/commands/repo/build.ts index 6d362c7d98..6a2b9be06d 100644 --- a/packages/cli/src/commands/repo/build.ts +++ b/packages/cli/src/commands/repo/build.ts @@ -137,6 +137,7 @@ export async function command(opts: OptionValues, cmd: Command): Promise { outputs, logPrefix: `${chalk.cyan(relativePath(paths.targetRoot, pkg.dir))}: `, minify: buildOptions.minify, + workspacePackages: packages, }; }); diff --git a/packages/cli/src/lib/builder/config.test.ts b/packages/cli/src/lib/builder/config.test.ts index 733c35fb55..e426e1ffa5 100644 --- a/packages/cli/src/lib/builder/config.test.ts +++ b/packages/cli/src/lib/builder/config.test.ts @@ -29,6 +29,7 @@ describe('makeRollupConfigs', () => { version: '0.0.0', main: './src/index.ts', }, + workspacePackages: [], }); const external = config.external as Exclude< ExternalOption, diff --git a/packages/cli/src/lib/builder/config.ts b/packages/cli/src/lib/builder/config.ts index 8beb2cbb1e..b568b402bd 100644 --- a/packages/cli/src/lib/builder/config.ts +++ b/packages/cli/src/lib/builder/config.ts @@ -53,6 +53,21 @@ function isFileImport(source: string) { return false; } +function buildInternalImportPattern(options: BuildOptions) { + const inlinedPackages = options.workspacePackages.filter( + pkg => pkg.packageJson.backstage?.inline, + ); + for (const { packageJson } of inlinedPackages) { + if (!packageJson.private) { + throw new Error( + `Inlined package ${packageJson.name} must be marked as private`, + ); + } + } + const names = inlinedPackages.map(pkg => pkg.packageJson.name); + return new RegExp(`^(?:${names.join('|')})(?:$|/)`); +} + export async function makeRollupConfigs( options: BuildOptions, ): Promise { @@ -83,6 +98,19 @@ export async function makeRollupConfigs( SCRIPT_EXTS.includes(e.ext), ); + const internalImportPattern = buildInternalImportPattern(options); + const external = ( + source: string, + importer: string | undefined, + isResolved: boolean, + ) => + Boolean( + importer && + !isResolved && + !internalImportPattern.test(source) && + !isFileImport(source), + ); + if (options.outputs.has(Output.cjs) || options.outputs.has(Output.esm)) { const output = new Array(); const mainFields = ['module', 'main']; @@ -120,8 +148,7 @@ export async function makeRollupConfigs( onwarn, preserveEntrySignatures: 'strict', // All module imports are always marked as external - external: (source, importer, isResolved) => - Boolean(importer && !isResolved && !isFileImport(source)), + external, plugins: [ resolve({ mainFields }), commonjs({ @@ -190,18 +217,11 @@ export async function makeRollupConfigs( chunkFileNames: `types/[name]-[hash].d.ts`, format: 'es', }, - external: [ - /\.css$/, - /\.scss$/, - /\.sass$/, - /\.svg$/, - /\.eot$/, - /\.woff$/, - /\.woff2$/, - /\.ttf$/, - ], + external: (source, importer, isResolved) => + /\.css|scss|sass|svg|eot|woff|woff2|ttf$/.test(source) || + external(source, importer, isResolved), onwarn, - plugins: [dts()], + plugins: [dts({ respectExternal: true })], }); } diff --git a/packages/cli/src/lib/builder/types.ts b/packages/cli/src/lib/builder/types.ts index 7d9c34fe29..937bd157c9 100644 --- a/packages/cli/src/lib/builder/types.ts +++ b/packages/cli/src/lib/builder/types.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { BackstagePackageJson } from '@backstage/cli-node'; +import { BackstagePackage, BackstagePackageJson } from '@backstage/cli-node'; export enum Output { esm, @@ -28,4 +28,5 @@ export type BuildOptions = { packageJson?: BackstagePackageJson; outputs: Set; minify?: boolean; + workspacePackages: BackstagePackage[]; }; diff --git a/packages/cli/src/lib/packager/createDistWorkspace.ts b/packages/cli/src/lib/packager/createDistWorkspace.ts index b966e23a85..54ce9c073f 100644 --- a/packages/cli/src/lib/packager/createDistWorkspace.ts +++ b/packages/cli/src/lib/packager/createDistWorkspace.ts @@ -211,6 +211,7 @@ export async function createDistWorkspace( outputs: outputs, logPrefix: `${chalk.cyan(relativePath(paths.targetRoot, pkg.dir))}: `, minify: options.minify, + workspacePackages: packages, }); } }