packages/cli,app: read config to template html and set up public path

This commit is contained in:
Patrik Oldsberg
2020-06-04 11:01:40 +02:00
parent 8a0ccc1bcd
commit 945362723d
6 changed files with 52 additions and 40 deletions
+10 -19
View File
@@ -8,47 +8,38 @@
name="description"
content="Backstage is an open platform for building developer portals"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="apple-touch-icon" href="<%= publicPath %>/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link
rel="manifest"
href="%PUBLIC_URL%/manifest.json"
href="<%= publicPath %>/manifest.json"
crossorigin="use-credentials"
/>
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<link rel="icon" href="<%= publicPath %>/favicon.ico" />
<link rel="shortcut icon" href="<%= publicPath %>/favicon.ico" />
<link
rel="apple-touch-icon"
sizes="180x180"
href="%PUBLIC_URL%/apple-touch-icon.png"
href="<%= publicPath %>/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="%PUBLIC_URL%/favicon-32x32.png"
href="<%= publicPath %>/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="%PUBLIC_URL%/favicon-16x16.png"
href="<%= publicPath %>/favicon-16x16.png"
/>
<link
rel="mask-icon"
href="%PUBLIC_URL%/safari-pinned-tab.svg"
href="<%= publicPath %>/safari-pinned-tab.svg"
color="#5bbad5"
/>
<style>
@@ -56,9 +47,9 @@
min-height: 100%;
}
</style>
<title>Backstage</title>
<title><%= app.title %></title>
</head>
<body style="margin: 0">
<body style="margin: 0;">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
+23 -3
View File
@@ -17,6 +17,7 @@
import webpack from 'webpack';
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
import ModuleScopePlugin from 'react-dev-utils/ModuleScopePlugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import { BundlingPaths } from './paths';
import { transforms } from './transforms';
import { optimization } from './optimization';
@@ -33,7 +34,13 @@ export function createConfig(
): webpack.Configuration {
const { checksEnabled, isDev } = options;
const { plugins, loaders } = transforms(paths, options);
const { plugins, loaders } = transforms(options);
const baseUrl = options.config.getString('app.baseUrl');
if (!baseUrl) {
throw new Error('app.baseUrl must be set in config');
}
const validBaseUrl = new URL(baseUrl, 'https://backstage-app.dev');
if (checksEnabled) {
plugins.push(
@@ -53,7 +60,20 @@ export function createConfig(
plugins.push(
new webpack.EnvironmentPlugin({
APP_CONFIG: options.appConfig,
APP_CONFIG: options.appConfigs,
}),
);
plugins.push(
new HtmlWebpackPlugin({
template: paths.targetHtml,
templateParameters: {
publicPath: validBaseUrl.pathname.replace(/\/$/, ''),
app: {
title: options.config.getString('app.title'),
baseUrl: validBaseUrl.href,
},
},
}),
);
@@ -85,7 +105,7 @@ export function createConfig(
},
output: {
path: paths.targetDist,
publicPath: '/',
publicPath: validBaseUrl.pathname,
filename: isDev ? '[name].js' : '[name].[hash:8].js',
chunkFilename: isDev
? '[name].chunk.js'
+14 -5
View File
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { existsSync } from 'fs';
import fs from 'fs-extra';
import { paths } from '../paths';
export type BundlingPathsOptions = {
@@ -28,20 +28,29 @@ export function resolveBundlingPaths(options: BundlingPathsOptions) {
const resolveTargetModule = (path: string) => {
for (const ext of ['mjs', 'js', 'ts', 'tsx', 'jsx']) {
const filePath = paths.resolveTarget(`${path}.${ext}`);
if (existsSync(filePath)) {
if (fs.pathExistsSync(filePath)) {
return filePath;
}
}
return paths.resolveTarget(`${path}.js`);
};
let targetHtml = paths.resolveTarget(`${entry}.html`);
if (!existsSync(targetHtml)) {
targetHtml = paths.resolveOwn('templates/serve_index.html');
let targetPublic = undefined;
let targetHtml = paths.resolveTarget('public/index.html');
// Prefer public folder
if (fs.pathExistsSync(targetHtml)) {
targetPublic = paths.resolveTarget('public');
} else {
targetHtml = paths.resolveTarget(`${entry}.html`);
if (!fs.pathExistsSync(targetHtml)) {
targetHtml = paths.resolveOwn('templates/serve_index.html');
}
}
return {
targetHtml,
targetPublic,
targetPath: paths.resolveTarget('.'),
targetDist: paths.resolveTarget('dist'),
targetAssets: paths.resolveTarget('assets'),
+3 -1
View File
@@ -44,7 +44,9 @@ export async function serveBundle(options: ServeOptions) {
const server = new WebpackDevServer(compiler, {
hot: true,
publicPath: '/',
contentBase: paths.targetPublic,
contentBasePublicPath: config.output?.publicPath,
publicPath: config.output?.publicPath,
historyApiFallback: true,
clientLogLevel: 'warning',
stats: 'errors-warnings',
+1 -12
View File
@@ -15,20 +15,15 @@
*/
import webpack, { Module, Plugin } from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import { BundlingOptions } from './types';
import { BundlingPaths } from './paths';
type Transforms = {
loaders: Module['rules'];
plugins: Plugin[];
};
export const transforms = (
paths: BundlingPaths,
options: BundlingOptions,
): Transforms => {
export const transforms = (options: BundlingOptions): Transforms => {
const { isDev } = options;
const loaders = [
@@ -80,12 +75,6 @@ export const transforms = (
const plugins = new Array<Plugin>();
plugins.push(
new HtmlWebpackPlugin({
template: paths.targetHtml,
}),
);
if (isDev) {
plugins.push(new webpack.HotModuleReplacementPlugin());
} else {
@@ -1,5 +1,6 @@
app:
title: Scaffolded Backstage App
baseUrl: http://localhost:3000
organization:
name: Acme Corporation