Skip to content

Commit 4b5cc40

Browse files
authored
refactor(cli): new --in-place/--no-in-place option to the export-dynamic-plugin CLI command to allow exporting to dist-dynamic (when value is false). (#1584)
refactor(cli): New `--in-place`/`--no-in-place` option to the `export-dynamic-plugin` CLI command to allow exporting to `dist-dynamic` (when value is `false`). Signed-off-by: David Festal <[email protected]>
1 parent f868a85 commit 4b5cc40

File tree

8 files changed

+111
-22
lines changed

8 files changed

+111
-22
lines changed

packages/cli/src/commands/export-dynamic-plugin/backend-embed-as-dependencies.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ function checkWorkspacePackageVersion(
600600
);
601601
}
602602

603-
function customizeForDynamicUse(options: {
603+
export function customizeForDynamicUse(options: {
604604
embedded: ResolvedEmbedded[];
605605
monoRepoPackages: Packages | undefined;
606606
sharedPackages?: SharedPackagesRules | undefined;

packages/cli/src/commands/export-dynamic-plugin/command.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import chalk from 'chalk';
2020
import { OptionValues } from 'commander';
2121
import fs from 'fs-extra';
2222

23+
import path from 'path';
24+
2325
import { paths } from '../../lib/paths';
2426
import { getConfigSchema } from '../../lib/schema/collect';
2527
import { Task } from '../../lib/tasks';
@@ -28,9 +30,9 @@ import { backend as backendEmbedAsDependencies } from './backend-embed-as-depend
2830
import { applyDevOptions } from './dev';
2931
import { frontend } from './frontend';
3032

31-
const saveSchema = async (packageName: string, path: string) => {
33+
const saveSchema = async (packageName: string, destination: string) => {
3234
const configSchema = await getConfigSchema(packageName);
33-
await fs.writeJson(paths.resolveTarget(path), configSchema, {
35+
await fs.writeJson(paths.resolveTarget(destination), configSchema, {
3436
encoding: 'utf8',
3537
spaces: 2,
3638
});
@@ -53,10 +55,10 @@ export async function command(opts: OptionValues): Promise<void> {
5355
} else {
5456
targetPath = await backendEmbedAsCode(roleInfo, opts);
5557
}
56-
configSchemaPath = 'dist-dynamic/dist/configSchema.json';
58+
configSchemaPath = path.join(targetPath, 'dist/configSchema.json');
5759
} else if (role === 'frontend-plugin') {
5860
targetPath = await frontend(roleInfo, opts);
59-
configSchemaPath = 'dist-scalprum/configSchema.json';
61+
configSchemaPath = path.join(targetPath, 'dist-scalprum/configSchema.json');
6062
} else {
6163
throw new Error(
6264
'Only packages with the "backend-plugin", "backend-plugin-module" or "frontend-plugin" roles can be exported as dynamic backend plugins',

packages/cli/src/commands/export-dynamic-plugin/frontend.ts

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,28 @@
1616

1717
import { PackageRoleInfo } from '@backstage/cli-node';
1818

19+
import { getPackages } from '@manypkg/get-packages';
20+
import chalk from 'chalk';
1921
import { OptionValues } from 'commander';
2022
import fs from 'fs-extra';
2123

24+
import path from 'path';
25+
2226
import { buildScalprumPlugin } from '../../lib/builder/buildScalprumPlugin';
27+
import { productionPack } from '../../lib/packager/productionPack';
2328
import { paths } from '../../lib/paths';
29+
import { Task } from '../../lib/tasks';
30+
import { customizeForDynamicUse } from './backend-embed-as-dependencies';
2431

2532
export async function frontend(
2633
_: PackageRoleInfo,
27-
__: OptionValues,
34+
opts: OptionValues,
2835
): Promise<string> {
2936
const {
3037
name,
3138
version,
3239
scalprum: scalprumExternal,
40+
files,
3341
} = await fs.readJson(paths.resolveTarget('package.json'));
3442

3543
let scalprum = scalprumExternal;
@@ -54,7 +62,63 @@ export async function frontend(
5462
);
5563
}
5664

57-
await fs.remove(paths.resolveTarget('dist-scalprum'));
65+
const distDynamicRelativePath = 'dist-dynamic';
66+
const target = opts.inPlace
67+
? path.resolve(paths.targetDir)
68+
: path.resolve(paths.targetDir, distDynamicRelativePath);
69+
70+
if (!opts.inPlace) {
71+
Task.log(
72+
`Packing main package to ${chalk.cyan(
73+
path.join(distDynamicRelativePath, 'package.json'),
74+
)}`,
75+
);
76+
77+
if (opts.clean) {
78+
await fs.remove(target);
79+
}
80+
81+
await fs.mkdirs(target);
82+
83+
await productionPack({
84+
packageDir: paths.targetDir,
85+
targetDir: target,
86+
});
87+
88+
Task.log(
89+
`Customizing main package in ${chalk.cyan(
90+
path.join(distDynamicRelativePath, 'package.json'),
91+
)} for dynamic loading`,
92+
);
93+
if (files && Array.isArray(files) && !files.includes('dist-scalprum')) {
94+
files.push('dist-scalprum');
95+
}
96+
const monoRepoPackages = await getPackages(paths.targetDir);
97+
await customizeForDynamicUse({
98+
embedded: [],
99+
monoRepoPackages,
100+
overridding: {
101+
name: `${name}-dynamic`,
102+
// We remove scripts, because they do not make sense for this derived package.
103+
// They even bring errors, especially the pre-pack and post-pack ones:
104+
// we want to be able to use npm pack on this derived package to distribute it as a dynamic plugin,
105+
// and obviously this should not trigger the backstage pre-pack or post-pack actions
106+
// which are related to the packaging of the original static package.
107+
scripts: {},
108+
files,
109+
},
110+
})(path.resolve(target, 'package.json'));
111+
}
112+
113+
const resolvedScalprumDistPath = path.join(target, 'dist-scalprum');
114+
115+
Task.log(
116+
`Generating dynamic frontend plugin assets in ${chalk.cyan(
117+
resolvedScalprumDistPath,
118+
)}`,
119+
);
120+
121+
await fs.remove(resolvedScalprumDistPath);
58122

59123
await buildScalprumPlugin({
60124
writeStats: false,
@@ -65,7 +129,8 @@ export async function frontend(
65129
version,
66130
},
67131
fromPackage: name,
132+
resolvedScalprumDistPath,
68133
});
69134

70-
return paths.targetDir;
135+
return target;
71136
}

packages/cli/src/commands/index.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,16 @@ export function registerScriptCommand(program: Command) {
123123
)
124124
.option(
125125
'--embed-as-dependencies',
126-
'Include embedded packages as private dependencies, instead of merging the with the generated code. Experimental for now, but expected to become the default.',
126+
'Include embedded packages as private dependencies of backend plugins, instead of merging them with the generated code. Experimental for now, but expected to become the default.',
127+
false,
127128
)
129+
.option('--no-embed-as-dependencies', undefined, true)
130+
.option(
131+
'--in-place',
132+
'Adds the frontend dynamic plugin assets to the `dist-scalprum` folder of the original plugin package. When value is `false` (using `--no-in-place`), it produces the assets in a distinct package located in the `dist-dynamic` sub-folder, as for backend plugins. `true` by default for now, it is expected to become `false` by default.',
133+
true,
134+
)
135+
.option('--no-in-place', undefined, false)
128136
.action(lazy(() => import('./export-dynamic-plugin').then(m => m.command)));
129137

130138
command

packages/cli/src/lib/builder/buildScalprumPlugin.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ interface BuildScalprumPluginOptions {
1010
configPaths: string[];
1111
pluginMetadata: PluginBuildMetadata;
1212
fromPackage: string;
13+
resolvedScalprumDistPath: string;
1314
}
1415

1516
export async function buildScalprumPlugin(options: BuildScalprumPluginOptions) {
16-
const { targetDir, pluginMetadata, fromPackage } = options;
17+
const { targetDir, pluginMetadata, fromPackage, resolvedScalprumDistPath } =
18+
options;
1719
await buildScalprumBundle({
1820
targetDir,
1921
entry: 'src/index',
@@ -23,5 +25,6 @@ export async function buildScalprumPlugin(options: BuildScalprumPluginOptions) {
2325
args: [],
2426
fromPackage,
2527
})),
28+
resolvedScalprumDistPath,
2629
});
2730
}

packages/cli/src/lib/bundler/bundlePlugin.ts

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,35 @@ function applyContextToError(error: string, moduleName: string): string {
2323
}
2424

2525
export async function buildScalprumBundle(
26-
options: BundlingPathsOptions & DynamicPluginOptions,
26+
options: BundlingPathsOptions &
27+
DynamicPluginOptions & {
28+
resolvedScalprumDistPath: string;
29+
},
2730
) {
2831
const paths = resolveBundlingPaths(options);
29-
const config = await createScalprumConfig(paths, {
30-
...options,
31-
checksEnabled: false,
32-
isDev: false,
33-
baseUrl: resolveBaseUrl(options.frontendConfig),
34-
});
32+
const config = await createScalprumConfig(
33+
{
34+
targetScalprumDist: options.resolvedScalprumDistPath,
35+
...paths,
36+
},
37+
{
38+
...options,
39+
checksEnabled: false,
40+
isDev: false,
41+
baseUrl: resolveBaseUrl(options.frontendConfig),
42+
},
43+
);
3544

3645
const isCi = yn(process.env.CI, { default: false });
3746

3847
const previousFileSizes = await measureFileSizesBeforeBuild(
39-
paths.targetScalprumDist,
48+
options.resolvedScalprumDistPath,
4049
);
41-
await fs.emptyDir(paths.targetScalprumDist);
50+
await fs.emptyDir(options.resolvedScalprumDistPath);
4251

52+
// TODO(davidfestal): ask @tumido or @Hyperkid123if this still makes sense here for dynamic plugins.
53+
// That seems strange since the public assets are not copied to `dist-scalprum`,
54+
// which is the place from where the dynamic plugin assets will be served
4355
if (paths.targetPublic) {
4456
await fs.copy(paths.targetPublic, paths.targetDist, {
4557
dereference: true,
@@ -56,7 +68,7 @@ export async function buildScalprumBundle(
5668
printFileSizesAfterBuild(
5769
stats,
5870
previousFileSizes,
59-
paths.targetScalprumDist,
71+
options.resolvedScalprumDistPath,
6072
WARN_AFTER_BUNDLE_GZIP_SIZE,
6173
WARN_AFTER_CHUNK_GZIP_SIZE,
6274
);

packages/cli/src/lib/bundler/paths.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ export function resolveBundlingPaths(options: BundlingPathsOptions) {
6363
targetPath: resolvePath(targetDir, '.'),
6464
targetRunFile: runFileExists ? targetRunFile : undefined,
6565
targetDist: resolvePath(targetDir, 'dist'),
66-
targetScalprumDist: resolvePath(targetDir, 'dist-scalprum'),
6766
targetAssets: resolvePath(targetDir, 'assets'),
6867
targetSrc: resolvePath(targetDir, 'src'),
6968
targetDev: resolvePath(targetDir, 'dev'),

packages/cli/src/lib/bundler/scalprumConfig.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export const sharedModules = {
7171
};
7272

7373
export async function createScalprumConfig(
74-
paths: BundlingPaths,
74+
paths: BundlingPaths & { targetScalprumDist: string },
7575
options: DynamicPluginOptions,
7676
): Promise<webpack.Configuration> {
7777
const { checksEnabled, isDev } = options;

0 commit comments

Comments
 (0)