Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Frontend] Migrate to create-react-app #3156

Merged
merged 12 commits into from
Feb 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions frontend/.eslintrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
extends: react-app
ignorePatterns:
- node_modules/
- src/apis # these are generated api clients
- '*.test.ts'
- '*.test.tsx'

rules:
react/jsx-no-target-blank: ['error', { "allowReferrer": true }]

17 changes: 8 additions & 9 deletions frontend/analyze_bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,16 @@
* limitations under the License.
*/

process.env.NODE_ENV = "production"
var BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin
process.env.NODE_ENV = 'production';
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

const webpackConfigProd = require("react-scripts-ts/config/webpack.config.prod")
const webpackConfigProd = require('react-scripts/config/webpack.config.prod');

webpackConfigProd.plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: "static",
reportFilename: "report.html",
})
)
analyzerMode: 'static',
reportFilename: 'report.html',
}),
);

require("react-scripts-ts/scripts/build")
require('react-scripts/scripts/build');
2 changes: 1 addition & 1 deletion frontend/mock-backend/mock-api-middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import * as express from 'express';
import * as fs from 'fs';
import RunUtils from '../src/lib/RunUtils';
import helloWorldRuntime from './integration-test-runtime';
import proxyMiddleware from '../server/proxy-middleware';
import proxyMiddleware from './proxy-middleware';
import { ApiFilter, PredicateOp } from '../src/apis/filter';
import { ApiListExperimentsResponse, ApiExperiment } from '../src/apis/experiment';
import { ApiListJobsResponse, ApiJob } from '../src/apis/job';
Expand Down
4 changes: 2 additions & 2 deletions frontend/mock-backend/mock-api-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import * as express from 'express';
import express from 'express';
import mockApiMiddleware from './mock-api-middleware';

const app = express();
Expand All @@ -21,7 +21,7 @@ const port = process.argv[2] || 3001;
// Uncomment the following line to get 1000ms delay to all requests
// app.use((req, res, next) => { setTimeout(next, 1000); });

app.use((_, res, next) => {
app.use((_: any, res: any, next: any) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, content-type');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE');
Expand Down
85 changes: 85 additions & 0 deletions frontend/mock-backend/proxy-middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright 2018 Google LLC
//
// 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 * as express from 'express';
import proxy from 'http-proxy-middleware';
import { URL, URLSearchParams } from 'url';

export function _extractUrlFromReferer(proxyPrefix: string, referer = ''): string {
const index = referer.indexOf(proxyPrefix);
return index > -1 ? referer.substr(index + proxyPrefix.length) : '';
}

export function _trimProxyPrefix(proxyPrefix: string, path: string): string {
return path.indexOf(proxyPrefix) === 0 ? (path = path.substr(proxyPrefix.length)) : path;
}

export function _routePathWithReferer(proxyPrefix: string, path: string, referer = ''): string {
// If a referer header is included, extract the referer URL, otherwise
// just trim out the /_proxy/ prefix. Use the origin of the resulting URL.
const proxiedUrlInReferer = _extractUrlFromReferer(proxyPrefix, referer);
let decodedPath = decodeURIComponent(proxiedUrlInReferer || _trimProxyPrefix(proxyPrefix, path));
if (!decodedPath.startsWith('http://') && !decodedPath.startsWith('https://')) {
decodedPath = 'http://' + decodedPath;
}
return new URL(decodedPath).origin;
}

export function _rewritePath(proxyPrefix: string, path: string, query: string): string {
// Trim the proxy prefix if exists. It won't exist for any requests made
// to absolute paths by the proxied resource.
const querystring = new URLSearchParams(query).toString();
const decodedPath = decodeURIComponent(path);
return _trimProxyPrefix(proxyPrefix, decodedPath) + (querystring && '?' + querystring);
}

export default (app: express.Application, apisPrefix: string) => {
const proxyPrefix = apisPrefix + '/_proxy/';

app.use((req, _, next) => {
// For any request that has a proxy referer header but no proxy prefix,
// prepend the proxy prefix to it and redirect.
if (req.headers.referer) {
const refererUrl = _extractUrlFromReferer(proxyPrefix, req.headers.referer as string);
if (refererUrl && req.url.indexOf(proxyPrefix) !== 0) {
let proxiedUrl = decodeURIComponent(
_extractUrlFromReferer(proxyPrefix, req.headers.referer as string),
);
if (!proxiedUrl.startsWith('http://') && !proxiedUrl.startsWith('https://')) {
proxiedUrl = 'http://' + proxiedUrl;
}
const proxiedOrigin = new URL(proxiedUrl).origin;
req.url = proxyPrefix + encodeURIComponent(proxiedOrigin + req.url);
}
}
next();
});

app.all(
proxyPrefix + '*',
proxy({
changeOrigin: true,
logLevel: 'debug',
target: 'http://127.0.0.1',

router: (req: any) => {
return _routePathWithReferer(proxyPrefix, req.path, req.headers.referer as string);
},

pathRewrite: (_: any, req: any) => {
return _rewritePath(proxyPrefix, req.path, req.query);
},
}),
);
};
24 changes: 24 additions & 0 deletions frontend/mock-backend/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"outDir": "build/dist",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom", "es2019"],
"sourceMap": true,
"allowJs": true,
"resolveJsonModule": true,
"jsx": "react",
"moduleResolution": "node",
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictBindCallApply": true,
"strictNullChecks": true,
"suppressImplicitAnyIndexErrors": true,
"skipLibCheck": true,
"esModuleInterop": true
},
"exclude": ["dist", "coverage"]
}
Loading