From cfc85926755fd00a421a8b1940e548430e8fc8cf Mon Sep 17 00:00:00 2001 From: christophercr Date: Wed, 27 Jun 2018 16:43:29 +0200 Subject: [PATCH] fix(stark-demo): add baseHref dynamically via Angular provider to fix Showcase when published in GitHub pages ISSUES CLOSED: #466 --- packages/stark-build/config/build-utils.js | 35 ++++++++++++++----- showcase/angular.json | 2 +- .../src/environments/environment.e2e.prod.ts | 5 ++- showcase/src/environments/environment.hmr.ts | 5 ++- showcase/src/environments/environment.prod.ts | 28 ++++++++++++++- showcase/src/environments/environment.ts | 5 ++- 6 files changed, 67 insertions(+), 13 deletions(-) diff --git a/packages/stark-build/config/build-utils.js b/packages/stark-build/config/build-utils.js index 7c26e58a73..806acb8f69 100644 --- a/packages/stark-build/config/build-utils.js +++ b/packages/stark-build/config/build-utils.js @@ -5,10 +5,13 @@ const helpers = require("./helpers"); const ngCliUtils = require("./ng-cli-utils"); const angularCliAppConfig = ngCliUtils.getAngularCliAppConfig(helpers.root("angular.json")); + +// default values for baseHref and deployUrl are taken from +// node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/styles.js const ANGULAR_APP_CONFIG = { config: angularCliAppConfig, deployUrl: angularCliAppConfig.architect.build.options.deployUrl || "", - baseHref: angularCliAppConfig.architect.build.options.baseHref || "/", + baseHref: angularCliAppConfig.architect.build.options.baseHref || "", sourceRoot: angularCliAppConfig.sourceRoot, outputPath: angularCliAppConfig.architect.build.options.outputPath }; @@ -39,17 +42,26 @@ function readTsConfig(tsConfigPath) { } /** - * The method reads the content of angular.json for getting the path (read with value or replace in "fileReplacements" of environment. + * Read the content of angular.json to get the path of the environment file. + * It returns the path of the replacement file defined in "fileReplacements" of the environment or the default file + * in case the replacement file does not exist. * * See: https://github.com/angular/angular-cli/wiki/angular-workspace * * @param environment - * @returns {*} - the path of the environment file of the received environment. + * @returns {string} - The path of the environment file of the given environment. */ function getEnvironmentFile(environment) { if (typeof environment === "string") { let fileName = helpers.root("src/environments/environment.ts"); let fileNameAlt; + + // the production config is under "production" section instead of "prod" in angular.json + // see https://github.com/angular/angular-cli/wiki/stories-application-environments + if (environment === "prod") { + environment = "production"; + } + let angularCliEnvConfig = ANGULAR_APP_CONFIG.config.architect.build.configurations[environment]; if (angularCliEnvConfig && angularCliEnvConfig.fileReplacements instanceof Array) { @@ -59,12 +71,19 @@ function getEnvironmentFile(environment) { fileNameAlt = helpers.root(angularCliEnvConfig.fileReplacements[0].replace); } } + } else { + // for "dev" environment the default environment.ts file is used + if (environment !== "dev") { + throw new Error( + `Configuration for '${environment}' not found in angular.json or it contains invalid fileReplacements section.` + ); + } } if (fs.existsSync(fileName)) { return fileName; } else if (fs.existsSync(fileNameAlt)) { - console.warn(`Could not find environment file for ${environment}, loading default environment file`); + console.warn(`Could not find environment file for '${environment}', loading default environment file`); return fileNameAlt; } else { throw new Error("Environment file not found."); @@ -76,7 +95,7 @@ function getEnvironmentFile(environment) { * Read the tsconfig to determine if we should prefer ES2015 modules. * Load rxjs path aliases. * https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md#build-and-treeshaking - * @param shouldSupportES2015 Set to true when the output of typescript is >= ES6 + * @param shouldSupportES2015 - Set to true when the output of typescript is >= ES6 */ function rxjsAlias(shouldSupportES2015) { try { @@ -90,9 +109,9 @@ function rxjsAlias(shouldSupportES2015) { } /** - * Foreach installed NationalBankBelgium packages, read angular.json file in the root of the module. - * Based on angular.json file, fill an array with the needed assets for the module. - * Then return those to be read by CopyWebpackPlugin. + * Read the assets array in the angular.json file of each NationalBankBelgium package installed in node_modules and concatenate + * them into one single array that will be provided to the CopyWebpackPlugin. + * @returns {Array} An array containing the assets to be copied by CopyWebpackPlugin. */ function getNbbAssetsConfig() { let customAssets = []; diff --git a/showcase/angular.json b/showcase/angular.json index 4cee4c77c8..600a03d6d5 100644 --- a/showcase/angular.json +++ b/showcase/angular.json @@ -36,7 +36,7 @@ "styles": ["src/styles.css"], "scripts": [], "deployUrl": "", - "baseHref": "/" + "baseHref": "" }, "configurations": { "hmr": { diff --git a/showcase/src/environments/environment.e2e.prod.ts b/showcase/src/environments/environment.e2e.prod.ts index 8cb0e994c7..76259132d2 100644 --- a/showcase/src/environments/environment.e2e.prod.ts +++ b/showcase/src/environments/environment.e2e.prod.ts @@ -1,5 +1,6 @@ import { enableProdMode, NgModuleRef } from "@angular/core"; import { disableDebugTools } from "@angular/platform-browser"; +import { APP_BASE_HREF } from "@angular/common"; import { StarkEnvironment } from "@nationalbankbelgium/stark-core"; enableProdMode(); @@ -17,5 +18,7 @@ export const environment: StarkEnvironment = { disableDebugTools(); return modRef; }, - ENV_PROVIDERS: [] + ENV_PROVIDERS: [ + { provide: APP_BASE_HREF, useValue: "/" } // the baseHref is defined via the Angular provider instead of the angular.json file + ] }; diff --git a/showcase/src/environments/environment.hmr.ts b/showcase/src/environments/environment.hmr.ts index 1e8df766fd..1a5ca36309 100644 --- a/showcase/src/environments/environment.hmr.ts +++ b/showcase/src/environments/environment.hmr.ts @@ -1,5 +1,6 @@ import { ApplicationRef, ComponentRef, NgModuleRef } from "@angular/core"; import { enableDebugTools } from "@angular/platform-browser"; +import { APP_BASE_HREF } from "@angular/common"; import { StarkEnvironment } from "@nationalbankbelgium/stark-core"; // Ensure that we get detailed stack tracks during development (useful with node & Webpack) @@ -26,5 +27,7 @@ export const environment: StarkEnvironment = { (window).ng.coreTokens = _ng.coreTokens; return modRef; }, - ENV_PROVIDERS: [] + ENV_PROVIDERS: [ + { provide: APP_BASE_HREF, useValue: "/" } // the baseHref is defined via the Angular provider instead of the angular.json file + ] }; diff --git a/showcase/src/environments/environment.prod.ts b/showcase/src/environments/environment.prod.ts index 8cb0e994c7..735fa1e7cc 100644 --- a/showcase/src/environments/environment.prod.ts +++ b/showcase/src/environments/environment.prod.ts @@ -1,9 +1,33 @@ import { enableProdMode, NgModuleRef } from "@angular/core"; import { disableDebugTools } from "@angular/platform-browser"; +import { APP_BASE_HREF } from "@angular/common"; import { StarkEnvironment } from "@nationalbankbelgium/stark-core"; enableProdMode(); +/** + * This factory constructs the final baseHref based on the path location of the Showcase app in GitHub Pages + */ +export function appBaseHrefFactory(): string { + // the final url in GitHub Pages will be something like "/showcase/latest/" or "/showcase/some-version/" + const finalUrlRegex: RegExp = /(\/showcase\/[\d\D][^\/]+(\/|\/$|$))/; + const trailingSlashRegex: RegExp = /\/$/; + const matches: RegExpExecArray | null = finalUrlRegex.exec(window.location.pathname); + + let finalBaseHref: string = ""; + + if (matches && matches[1]) { + finalBaseHref = matches[1]; + } + + // add a trailing slash to the url in case it doesn't have any + if (!finalBaseHref.match(trailingSlashRegex)) { + finalBaseHref = finalBaseHref + "/"; + } + + return finalBaseHref; +} + export const environment: StarkEnvironment = { production: true, hmr: false, @@ -17,5 +41,7 @@ export const environment: StarkEnvironment = { disableDebugTools(); return modRef; }, - ENV_PROVIDERS: [] + ENV_PROVIDERS: [ + { provide: APP_BASE_HREF, useFactory: appBaseHrefFactory } // the baseHref is defined via the Angular provider instead of the angular.json file + ] }; diff --git a/showcase/src/environments/environment.ts b/showcase/src/environments/environment.ts index 883f95d72d..a452d38f34 100644 --- a/showcase/src/environments/environment.ts +++ b/showcase/src/environments/environment.ts @@ -1,5 +1,6 @@ import { ApplicationRef, ComponentRef, NgModuleRef } from "@angular/core"; import { enableDebugTools } from "@angular/platform-browser"; +import { APP_BASE_HREF } from "@angular/common"; import { StarkEnvironment } from "@nationalbankbelgium/stark-core"; // Ensure that we get detailed stack tracks during development (useful with node & Webpack) @@ -26,5 +27,7 @@ export const environment: StarkEnvironment = { (window).ng.coreTokens = _ng.coreTokens; return modRef; }, - ENV_PROVIDERS: [] + ENV_PROVIDERS: [ + { provide: APP_BASE_HREF, useValue: "/" } // the baseHref is defined via the Angular provider instead of the angular.json file + ] };