cli: switch config injection to index.html
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2024 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 { AppConfig } from '@backstage/config';
|
||||
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
||||
|
||||
export class ConfigInjectingHtmlWebpackPlugin extends HtmlWebpackPlugin {
|
||||
readonly name = 'ConfigInjectingHtmlWebpackPlugin';
|
||||
readonly #getFrontendAppConfigs: () => AppConfig[];
|
||||
|
||||
constructor(
|
||||
options: HtmlWebpackPlugin.Options,
|
||||
getFrontendAppConfigs: () => AppConfig[],
|
||||
) {
|
||||
super(options);
|
||||
this.#getFrontendAppConfigs = getFrontendAppConfigs;
|
||||
}
|
||||
|
||||
apply: HtmlWebpackPlugin['apply'] = compiler => {
|
||||
super.apply(compiler);
|
||||
|
||||
compiler.hooks.compilation.tap(this.name, compilation => {
|
||||
const hooks = HtmlWebpackPlugin.getCompilationHooks(compilation);
|
||||
hooks.alterAssetTagGroups.tap(this.name, ctx => {
|
||||
if (ctx.plugin !== this) {
|
||||
return ctx;
|
||||
}
|
||||
return {
|
||||
...ctx,
|
||||
headTags: [
|
||||
...ctx.headTags,
|
||||
HtmlWebpackPlugin.createHtmlTagObject(
|
||||
'script',
|
||||
{ type: 'backstage.io/config' },
|
||||
`\n${JSON.stringify(this.#getFrontendAppConfigs(), null, 2)}\n`,
|
||||
),
|
||||
],
|
||||
};
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -37,6 +37,7 @@ import { version } from '../../lib/version';
|
||||
import yn from 'yn';
|
||||
import { hasReactDomClient } from './hasReactDomClient';
|
||||
import { createWorkspaceLinkingPlugins } from './linkWorkspaces';
|
||||
import { ConfigInjectingHtmlWebpackPlugin } from './ConfigInjectingHtmlWebpackPlugin';
|
||||
|
||||
const BUILD_CACHE_ENV_VAR = 'BACKSTAGE_CLI_EXPERIMENTAL_BUILD_CACHE';
|
||||
|
||||
@@ -182,19 +183,35 @@ export async function createConfig(
|
||||
);
|
||||
|
||||
if (options.moduleFederation?.mode !== 'remote') {
|
||||
plugins.push(
|
||||
// `rspack.HtmlRspackPlugin` does not support object type `templateParameters` value, `frontendConfig` in this case
|
||||
new HtmlWebpackPlugin({
|
||||
meta: {
|
||||
'backstage-app-mode': options?.appMode ?? 'public',
|
||||
},
|
||||
template: paths.targetHtml,
|
||||
templateParameters: {
|
||||
publicPath,
|
||||
config: frontendConfig,
|
||||
},
|
||||
}),
|
||||
);
|
||||
const templateOptions = {
|
||||
meta: {
|
||||
'backstage-app-mode': options?.appMode ?? 'public',
|
||||
},
|
||||
template: paths.targetHtml,
|
||||
templateParameters: {
|
||||
publicPath,
|
||||
config: frontendConfig,
|
||||
},
|
||||
};
|
||||
if (rspack) {
|
||||
// With Rspack we inject config via index.html, this is both because we
|
||||
// can't use APP_CONFIG due to the lack of support for runtime values, but
|
||||
// also because we are able to do it and it lines up better with what the
|
||||
// app-backend is doing.
|
||||
//
|
||||
// We still use the html plugin from WebPack, since the Rspack one won't
|
||||
// let us inject complex objects like the config.
|
||||
plugins.push(
|
||||
new ConfigInjectingHtmlWebpackPlugin(
|
||||
templateOptions,
|
||||
options.getFrontendAppConfigs,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// Config injection via index.html doesn't work across reloads with
|
||||
// WebPack, so we rely on the APP_CONFIG injection instead
|
||||
plugins.push(new HtmlWebpackPlugin(templateOptions));
|
||||
}
|
||||
plugins.push(
|
||||
new HtmlWebpackPlugin({
|
||||
meta: {
|
||||
@@ -284,8 +301,7 @@ export async function createConfig(
|
||||
new bundler.DefinePlugin({
|
||||
'process.env.BUILD_INFO': JSON.stringify(buildInfo),
|
||||
'process.env.APP_CONFIG': rspack
|
||||
? // FIXME: see also https://github.com/web-infra-dev/rspack/issues/5606
|
||||
JSON.stringify(options.getFrontendAppConfigs())
|
||||
? JSON.stringify([]) // Inject via index.html instead
|
||||
: bundler.DefinePlugin.runtimeValue(
|
||||
() => JSON.stringify(options.getFrontendAppConfigs()),
|
||||
true,
|
||||
|
||||
Reference in New Issue
Block a user