Skip to content

Commit

Permalink
Fix #42 use <base> and config webpack at runtime
Browse files Browse the repository at this point in the history
Signed-off-by: Joe Farro <joef@uber.com>
  • Loading branch information
tiffon committed Mar 19, 2018
1 parent 6181a29 commit 5520c89
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 75 deletions.
File renamed without changes.
2 changes: 1 addition & 1 deletion config-overrides.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const rewireLess = require('react-app-rewire-less');
const lessToJs = require('less-vars-to-js');

// Read the less file in as string
const loadedVarOverrides = fs.readFileSync('config-overrides-ant-variables.less', 'utf8');
const loadedVarOverrides = fs.readFileSync('config-overrides-antd-vars.less', 'utf8');

// Pass in file contents
const modifyVars = lessToJs(loadedVarOverrides);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"xfwd": true
}
},
"homepage": null,
"homepage": ".",
"devDependencies": {
"babel-eslint": "^7.2.3",
"babel-plugin-import": "^1.6.3",
Expand Down
3 changes: 3 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />

<!-- NOTE: The document MUST have a <base> element. package.json#homepage is set to "." as part of resolving https://github.com/jaegertracing/jaeger-ui/issues/42 and therefore static assets are linked via relative URLs. This will break on many document URLs, e.g. /trace/abc, unless a valid base URL is provided. The base href defaults to "/" but the query-service can inject an override. -->
<base href="/" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<title>Jaeger UI</title>
<script>
Expand Down
18 changes: 0 additions & 18 deletions src/api/jaeger.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,22 +92,4 @@ const JaegerAPI = {
},
};

/* istanbul ignore next */
function getMock(fnName, ...rest) {
return new Promise(resolve => {
require.ensure(['../demo/jaeger-mock'], require => {
resolve(require('../demo/jaeger-mock').default[fnName](...rest));
});
});
}

/* istanbul ignore if */
if (process.env.REACT_APP_DEMO === 'true') {
Object.keys(JaegerAPI).forEach(key => {
if (typeof JaegerAPI[key] === 'function') {
JaegerAPI[key] = (...args) => getMock(key, ...args);
}
});
}

export default JaegerAPI;
5 changes: 5 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// site-prefix.js must be the first import of the main webpack entrypoint
// becaue it configures the webpack publicPath.
/* eslint-disable import/first */
import './site-prefix';

import React from 'react';
import ReactDOM from 'react-dom';
import { document } from 'global';
Expand Down
29 changes: 29 additions & 0 deletions src/site-prefix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2018 Uber Technologies, Inc.
//
// 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.

// Per the resolution of https://github.com/jaegertracing/jaeger-ui/issues/42,
// package.json#homepage is set to "." and the document MUST have a <base>
// element to define a usable base URL.
const baseNode = document.querySelector('base');
if (!baseNode && process.env.NODE_ENV !== 'test') {
throw new Error('<base> element not found');
}
const sitePrefix = baseNode ? baseNode.href : `${global.location.origin}/`;

// Configure the webpack publicPath to match the <base>:
// https://webpack.js.org/guides/public-path/#on-the-fly
// eslint-disable-next-line camelcase
window.__webpack_public_path__ = sitePrefix;

export default sitePrefix;
41 changes: 13 additions & 28 deletions src/utils/prefix-url.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,29 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import { homepage } from '../../package.json';

// strip the domain, first slash and trailing slash (if present)
const rx = new RegExp('^(?:https?://[^/]+)?/?(.*?)/?$', 'i');
let prefix = '';
import sitePrefix from '../site-prefix';

const origin = process.env.NODE_ENV === 'test' ? global.location.origin : window.location.origin;
/**
* Generate the URL prefix from `value` and use it for all subsequent calls to
* `prefixUrl()`. All of the following `value` parameters result in the prefix
* `"/some/prefix"` (although, the first is the preferred form).
*
* - `"/some/prefix"`
* - `"some/prefix"`
* - `"/some/prefix/"`
* - `"http://my.example.com/some/prefix"`
* - `"https://my.example.com/some/prefix/"`
*
* Note: This function has a side effect of setting the default URL prefix
* applied via the file's default explort.
* Generate the URL prefix from `sitePrefix` and use it for all subsequent calls
* to `prefixUrl()`. `sitePrefix` should be an absolute URL, e.g. with an origin.
* `pathPrefix` is just the path portion and should not have a trailing slash:
*
* @param {?string} value The value to derive the URL prefix from.
* @return {string} The resultant prefix.
* - `"http://localhost:3000/"` to `""`
* - `"http://localhost:3000/abc/"` to `"/abc"`
* - `"http://localhost:3000/abc/def/"` to `"/abc/def"`
*/
export function deriveAndSetPrefix(value) {
prefix = value ? value.replace(rx, '/$1') : '';
return prefix;
}

deriveAndSetPrefix(homepage);
const rx = new RegExp(`^${origin}|/$`, 'ig');
const pathPrefix = sitePrefix.replace(rx, '');

/**
* Add the URL prefix, derived from `homepage` in `package.json`, to the URL
* argument. The domain is stripped from `homepage` before being added.
* Add the path prefix to the URL. See [site-prefix.js](../site-prefix.js) and
* the `<base>` tag in [index.html](../../public/index.html) for details.
*
* @param {string} value The URL to have the prefix added to.
* @return {string} The resultant URL.
*/
export default function prefixUrl(value) {
const s = value == null ? '' : String(value);
return prefix + s;
return `${pathPrefix}${s}`;
}
39 changes: 12 additions & 27 deletions src/utils/prefix-url.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,38 +12,23 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import prefixUrl, { deriveAndSetPrefix } from './prefix-url';
/* eslint-disable import/first */

describe('deriveAndSetPrefix()', () => {
const targetPrefix = '/some/prefix';
const homepages = [
'/some/prefix',
'some/prefix',
'/some/prefix/',
'http://my.example.com/some/prefix',
'https://my.example.com/some/prefix/',
];
jest.mock('../site-prefix', () => `${global.location.origin}/a/site/prefix/`);

homepages.forEach(s => {
it(`parses "${s}" correctly`, () => {
expect(deriveAndSetPrefix(s)).toBe(targetPrefix);
});
});
});
import prefixUrl from './prefix-url';

describe('prefixUrl()', () => {
beforeAll(() => {
deriveAndSetPrefix('/some/prefix');
});
const PATH_PREFIX = '/a/site/prefix';

describe('prefixUrl()', () => {
const tests = [
{ source: undefined, target: '/some/prefix' },
{ source: null, target: '/some/prefix' },
{ source: '', target: '/some/prefix' },
{ source: '/', target: '/some/prefix/' },
{ source: '/a', target: '/some/prefix/a' },
{ source: '/a/', target: '/some/prefix/a/' },
{ source: '/a/b', target: '/some/prefix/a/b' },
{ source: undefined, target: PATH_PREFIX },
{ source: null, target: PATH_PREFIX },
{ source: '', target: PATH_PREFIX },
{ source: '/', target: `${PATH_PREFIX}/` },
{ source: '/a', target: `${PATH_PREFIX}/a` },
{ source: '/a/', target: `${PATH_PREFIX}/a/` },
{ source: '/a/b', target: `${PATH_PREFIX}/a/b` },
];

tests.forEach(({ source, target }) => {
Expand Down

0 comments on commit 5520c89

Please sign in to comment.