fix(@angular-devkit/build-angular): baseHref with protocol and localize option

`posix.join` will dedupe double forward slashes resulting in incorrect protocol.

Closes: #17029
This commit is contained in:
Alan Agius 2020-02-20 14:51:53 +01:00 committed by Douglas Parker
parent 764b977de4
commit 4e65705205
5 changed files with 60 additions and 8 deletions

View File

@ -49,6 +49,7 @@ import {
normalizeAssetPatterns,
normalizeOptimization,
normalizeSourceMaps,
urlJoin,
} from '../utils';
import { BundleActionExecutor } from '../utils/action-executor';
import { findCachePath } from '../utils/cache-path';
@ -695,11 +696,9 @@ export function buildWebpackBrowser(
for (const [locale, outputPath] of outputPaths.entries()) {
let localeBaseHref;
if (i18n.locales[locale] && i18n.locales[locale].baseHref !== '') {
localeBaseHref = path.posix.join(
localeBaseHref = urlJoin(
options.baseHref || '',
i18n.locales[locale].baseHref === undefined
? `/${locale}/`
: i18n.locales[locale].baseHref,
i18n.locales[locale].baseHref ?? `/${locale}/`,
);
}
@ -726,11 +725,9 @@ export function buildWebpackBrowser(
for (const [locale, outputPath] of outputPaths.entries()) {
let localeBaseHref;
if (i18n.locales[locale] && i18n.locales[locale].baseHref !== '') {
localeBaseHref = path.posix.join(
localeBaseHref = urlJoin(
options.baseHref || '',
i18n.locales[locale].baseHref === undefined
? `/${locale}/`
: i18n.locales[locale].baseHref,
i18n.locales[locale].baseHref ?? `/${locale}/`,
);
}

View File

@ -15,3 +15,4 @@ export * from './normalize-asset-patterns';
export * from './normalize-source-maps';
export * from './normalize-optimization';
export * from './normalize-builder-schema';
export * from './url';

View File

@ -0,0 +1,17 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
export function urlJoin(...parts: string[]): string {
const [p, ...rest] = parts;
// Remove trailing slash from first part
// Join all parts with `/`
// Dedupe double slashes from path names
return p.replace(/\/$/, '') + ('/' + rest.join('/')).replace(/\/\/+/g, '/');
}

View File

@ -0,0 +1,30 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { urlJoin } from './url';
describe('urlJoin', () => {
it('should work with absolute url with trailing slash', () => {
expect(urlJoin('http://foo.com/', '/one/')).toBe('http://foo.com/one/');
});
it('should work with absolute url without trailing slash', () => {
expect(urlJoin('http://foo.com', '/one')).toBe('http://foo.com/one');
});
it('should work with absolute url without slashes', () => {
expect(urlJoin('http://foo.com', 'one', 'two')).toBe('http://foo.com/one/two');
});
it('should work with relative url without slashes', () => {
expect(urlJoin('one', 'two', 'three')).toBe('one/two/three');
});
it('should keep trailing slash if empty path is provided', () => {
expect(urlJoin('one/', '')).toBe('one/');
});
});

View File

@ -100,4 +100,11 @@ export default async function() {
server.close();
}
}
// Test absolute base href.
await ng('build', '--base-href', 'http://www.domain.com/');
for (const { lang, outputPath } of langTranslations) {
// Verify the HTML base HREF attribute is present
await expectFileToMatch(`${outputPath}/index.html`, `href="http://www.domain.com${baseHrefs[lang] || '/'}"`);
}
}