Skip to content

Commit

Permalink
feat: proxy for ssr dev server
Browse files Browse the repository at this point in the history
  • Loading branch information
chenjun1011 committed Jul 17, 2019
1 parent 95e5133 commit 9707ed9
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 16 deletions.
2 changes: 1 addition & 1 deletion packages/rax-scripts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rax-scripts",
"version": "1.3.9",
"version": "1.3.10",
"license": "BSD-3-Clause",
"description": "Project scripts for Rax.",
"bin": {
Expand Down
9 changes: 5 additions & 4 deletions packages/rax-scripts/src/config/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const fs = require('fs');
const path = require('path');
const pathConfig = require('./path.config');
const appConfig = require('./app.config');
const rewireWebpackConfig = require('../utils/rewireWebpackConfig');

const webpackConfigMap = {
webapp: {
Expand All @@ -15,7 +16,7 @@ const webpackConfigMap = {
};

exports.getWebpackConfig = (type, env = 'prod') => {
let config = [];
let config;
if (type === 'webapp') {
config = [
require(`${webpackConfigMap.webapp.client}.${env}`)
Expand All @@ -28,11 +29,11 @@ exports.getWebpackConfig = (type, env = 'prod') => {
config.push(require(`${webpackConfigMap.webapp.serverless}.${env}`));
}
}

return config;
} else {
config = require(`${webpackConfigMap[type]}.${env}`);
}

return require(`${webpackConfigMap[type]}.${env}`);
return rewireWebpackConfig(config);
};

exports.getEntries = () => {
Expand Down
22 changes: 19 additions & 3 deletions packages/rax-scripts/src/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,28 @@ module.exports = function start(type = 'webapp') {
const webpackConfig = getWebpackConfig(type, 'dev');
const compiler = createWebpackCompiler(webpackConfig);

let devServer;
const devServerConfig = webpackDevServerConfig;

if (appConfig.ssr) {
const ssrDevServerConfig = getDevServerConfig();
devServer = new SSRDevServer(compiler, ssrDevServerConfig);
Object.assign(devServerConfig, ssrDevServerConfig);
}

// rewire webpack dev config
if (Array.isArray(webpackConfig)) {
const customConfig = webpackConfig.find(config => {
return config.devServer;
});
customConfig && Object.assign(devServerConfig, customConfig.devServer);
} else if (webpackConfig.devServer) {
Object.assign(devServerConfig, webpackConfig.devServer);
}

let devServer;
if (appConfig.ssr) {
devServer = new SSRDevServer(compiler, devServerConfig);
} else {
devServer = new WebpackDevServer(compiler, webpackDevServerConfig);
devServer = new WebpackDevServer(compiler, devServerConfig);
}

// Launch WebpackDevServer.
Expand Down
5 changes: 1 addition & 4 deletions packages/rax-scripts/src/utils/createWebpackCompiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
/* eslint no-console: 0 */
const colors = require('chalk');

const rewireWebpackConfig = require('./rewireWebpackConfig');
const webpack = require('webpack');

/**
Expand All @@ -16,10 +15,8 @@ const webpack = require('webpack');
module.exports = (webpackConfig) => {
let compiler;

const config = rewireWebpackConfig(webpackConfig);

try {
compiler = webpack(config);
compiler = webpack(webpackConfig);
} catch (err) {
console.error(colors.red('[ERR]: Failed to compile.'));
console.log('');
Expand Down
16 changes: 15 additions & 1 deletion packages/rax-ssr-dev-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,18 @@ assets info for pages

absolute path for assets manifest file

If assets manifest is update with compilation, you can save it to a temp file and config this option. SSR will read the assets manifest before each render.
If assets manifest is update with compilation, you can save it to a temp file and config this option. SSR will read the assets manifest before each render.

### proxy

Proxying some URLs can be useful when you have a separate API backend development server and you want to send API requests on the same domain.

Config for proxy is same as [webpack-dev-server](https://webpack.js.org/configuration/dev-server/#devserverproxy).

```json
{
"proxy": {
"/api": "http://localhost:3000"
}
}
```
124 changes: 122 additions & 2 deletions packages/rax-ssr-dev-server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const express = require('express');
const RaxServer = require('rax-server');
const devMiddleware = require('webpack-dev-middleware');
const hotMiddleware = require('webpack-hot-middleware');
const httpProxyMiddleware = require('http-proxy-middleware');

class DevServer {
constructor(compiler, options) {
Expand All @@ -12,6 +13,7 @@ class DevServer {

setupApp(compiler) {
const app = express();
this.app = app;

// eslint-disable-next-line new-cap
const router = express.Router();
Expand Down Expand Up @@ -52,9 +54,11 @@ class DevServer {
hotMiddleware(compiler)
);

app.use(router);
if (this.options.proxy) {
this.setupProxyFeature();
}

this.app = app;
app.use(router);
}

close() { }
Expand Down Expand Up @@ -110,6 +114,122 @@ class DevServer {
const fs = res.locals.fs;
return fs.readFileSync(filePath, 'utf8');
}

// https://github.com/webpack/webpack-dev-server/blob/master/lib/Server.js
setupProxyFeature() {
/**
* Assume a proxy configuration specified as:
* proxy: {
* 'context': { options }
* }
* OR
* proxy: {
* 'context': 'target'
* }
*/
if (!Array.isArray(this.options.proxy)) {
if (Object.prototype.hasOwnProperty.call(this.options.proxy, 'target')) {
this.options.proxy = [this.options.proxy];
} else {
this.options.proxy = Object.keys(this.options.proxy).map((context) => {
let proxyOptions;
// For backwards compatibility reasons.
const correctedContext = context
.replace(/^\*$/, '**')
.replace(/\/\*$/, '');

if (typeof this.options.proxy[context] === 'string') {
proxyOptions = {
context: correctedContext,
target: this.options.proxy[context],
};
} else {
proxyOptions = Object.assign({}, this.options.proxy[context]);
proxyOptions.context = correctedContext;
}

proxyOptions.logLevel = proxyOptions.logLevel || 'warn';

return proxyOptions;
});
}
}

const getProxyMiddleware = (proxyConfig) => {
const context = proxyConfig.context || proxyConfig.path;

// It is possible to use the `bypass` method without a `target`.
// However, the proxy middleware has no use in this case, and will fail to instantiate.
if (proxyConfig.target) {
return httpProxyMiddleware(context, proxyConfig);
}
};
/**
* Assume a proxy configuration specified as:
* proxy: [
* {
* context: ...,
* ...options...
* },
* // or:
* function() {
* return {
* context: ...,
* ...options...
* };
* }
* ]
*/
this.options.proxy.forEach((proxyConfigOrCallback) => {
let proxyConfig;
let proxyMiddleware;

if (typeof proxyConfigOrCallback === 'function') {
proxyConfig = proxyConfigOrCallback();
} else {
proxyConfig = proxyConfigOrCallback;
}

proxyMiddleware = getProxyMiddleware(proxyConfig);

if (proxyConfig.ws) {
this.websocketProxies.push(proxyMiddleware);
}

this.app.use((req, res, next) => {
if (typeof proxyConfigOrCallback === 'function') {
const newProxyConfig = proxyConfigOrCallback();

if (newProxyConfig !== proxyConfig) {
proxyConfig = newProxyConfig;
proxyMiddleware = getProxyMiddleware(proxyConfig);
}
}

// - Check if we have a bypass function defined
// - In case the bypass function is defined we'll retrieve the
// bypassUrl from it otherwise byPassUrl would be null
const isByPassFuncDefined = typeof proxyConfig.bypass === 'function';
const bypassUrl = isByPassFuncDefined
? proxyConfig.bypass(req, res, proxyConfig)
: null;

if (typeof bypassUrl === 'boolean') {
// skip the proxy
req.url = null;
next();
} else if (typeof bypassUrl === 'string') {
// byPass to that url
req.url = bypassUrl;
next();
} else if (proxyMiddleware) {
return proxyMiddleware(req, res, next);
} else {
next();
}
});
});
}
}

function interopDefault(mod) {
Expand Down
3 changes: 2 additions & 1 deletion packages/rax-ssr-dev-server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rax-ssr-dev-server",
"version": "1.0.0",
"version": "1.0.1",
"description": "Rax SSR dev server.",
"license": "BSD-3-Clause",
"main": "index.js",
Expand All @@ -17,6 +17,7 @@
},
"dependencies": {
"express": "^4.17.1",
"http-proxy-middleware": "^0.19.1",
"rax-server": "^1.0.0",
"webpack-dev-middleware": "^3.7.0",
"webpack-hot-middleware": "^2.25.0"
Expand Down

0 comments on commit 9707ed9

Please sign in to comment.