Skip to content

Instantly share code, notes, and snippets.

@sergeymakoveev
Last active October 29, 2019 18:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sergeymakoveev/cc453586a59896c7605c22382d181bb7 to your computer and use it in GitHub Desktop.
Save sergeymakoveev/cc453586a59896c7605c22382d181bb7 to your computer and use it in GitHub Desktop.
webpack: use express-middleware for proxy request and modify response, set fake-endpoints and generate its response

Рецепты использования Webpack

// webpack: set fake-endpoints and generate its response
export default {
entry: {
// ...
},
devServer: {
proxy: {
'/some/path': {
bypass: (req, res, opts) => {
if (req.url === opts.context) {
// generate request here
}
return false;
}
}
}
}
};
// webpack: set fake-endpoints and generate its response
const
DATA = { a: 1, b: 2 },
DATA_PATH = 'data.json';
export default {
entry: {
// ...
},
devServer: {
proxy: {
'/some/path': {
bypass: (req, res, opts) => {
if (req.url === opts.context) {
console.log(`${req.url} -> bypass: generated response`);
// generate and send response
res.send(DATA);
}
return false;
}
},
'/some/another/path': {
bypass: (req, res, opts) => {
if (req.url === opts.context) {
console.log(`${req.url} -> bypass: response from file "${DATA_PATH}"`);
// return path to file with response-data
return DATA_PATH;
}
return false;
}
}
}
}
};
// webpack: set fake-endpoints and generate its response
const
DATA = { a: 1, b: 2 },
DATA_PATH = 'data.json';
const proxyfy = ({ url, data={}, path, opts }) => ({
[url]: {
bypass:
(req, res, opts) =>
(req.url === opts.context)
? (
path
? path
: res.send(data)
)
: false,
...opts
}
});
export default {
entry: {
// ...
},
devServer: {
proxy: {
...proxyfy({
url: '/some/path',
data: DATA
}),
...proxyfy({
url: '/some/another/path',
path: DATA_PATH
})
}
}
};
// webpack: use express-middleware for proxy request and modify response
export default {
entry: {
// ...
},
devServer: {
before: (app) => {
/*
app - express server instatce
Set here middleware app.use(...) for:
- proxy request
- modify request
- generate response
- modify response
*/
}
}
};
// webpack: use express-middleware for proxy request and modify response
const proxy = require('http-proxy-middleware');
export default {
entry: {
// ...
},
devServer: {
before: (app) => {
// request logging
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
// proxy-endpoint for modify external response
app.use(
'/some/path',
proxy({
target: 'http://example.com',
onProxyRes: (proxyRes, req, res) => {
const end = res.end;
const write = res.write;
const writeHead = res.writeHead;
let writeHeadArgs;
let buffer = new Buffer('');
res.writeHead = (...args) => { writeHeadArgs = args };
res.write = (chunk) => buffer = Buffer.concat([buffer, chunk]);
res.end = () => {
const isZipped = proxyRes.headers['content-encoding'] === 'gzip';
const body = (isZipped ? zlib.gunzipSync(buffer) : buffer).toString('utf8');
// modify external response
const json = {...{ a: 1, b: 2 }, ...JSON.parse(body)};
const output = JSON.stringify(json);
res.setHeader('content-length', Buffer.byteLength(output));
res.setHeader('content-encoding', '');
writeHead.apply(res, writeHeadArgs);
write.call(res, output);
end.call(res);
}
}
})
);
}
}
};
// webpack: use express-middleware for proxy request and modify response
const proxy = require('http-proxy-middleware');
const proxyfy_modify =
(app) =>
({
target, url,
reducer = ({ status, headers, body }) => ({ status, headers, body }),
...opts
}) => {
app.use(
url,
proxy({
target,
onProxyRes: (proxyRes, req, res) => {
const end = res.end;
const write = res.write;
const writeHead = res.writeHead;
let status, headers;
let buffer = new Buffer('');
res.writeHead = (code, phrase, hdrs) => {
status = { code, phrase };
headers = hdrs || {};
};
res.write = (chunk) => buffer = Buffer.concat([buffer, chunk]);
res.end = () => {
const isZipped = proxyRes.headers['content-encoding'] === 'gzip';
const body = (isZipped ? zlib.gunzipSync(buffer) : buffer).toString('utf8');
const reduced = reducer({ status, headers, body });
const response = {
...reduced,
headers: {
'content-length': Buffer.byteLength(reduced.body),
'content-encoding': '',
...reduced.headers
}
};
// res.setHeader('content-length', Buffer.byteLength(output_body));
// res.setHeader('content-encoding', '');
writeHead.call(res, response.status.code, response.status.phrase, response.headers);
write.call(res, response.body);
end.call(res);
}
},
...opts
})
);
};
export default {
entry: {
// ...
},
devServer: {
before: (app) => {
// request logging
app.use((req, res, next) => {
console.log(`${req.method} ${req.url}`);
next();
});
const modify = proxyfy_modify(app);
modify({
url: '/some/path',
target: 'http://example.com',
reducer: ({ status: { code, phrase }, headers, body }) => {
console.log({ status: { code, phrase }, headers, body });
const s = { code: code + 22, phrase: `Say: ${phrase}` };
const b = { ...{ c: 3, d: 4 }, ...JSON.parse(body || '{}') };
const h = { ...headers, 'x-some-header': 'some value'};
return {
status: s,
headers: h,
body: JSON.stringify(b)
};
}
});
modify({
url: '/some/another/path',
target: 'http://example.com',
reducer: ({ status, headers, body }) => {
const b = { ...{ c: 3, d: 4 }, ...JSON.parse(body) };
return {
status,
headers,
body: JSON.stringify(b)
};
}
}
});
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment