rspack-plugin-mock
Version:
inject api mock server to development server
203 lines (192 loc) • 8.57 kB
JavaScript
;Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
var _chunkM7F5AAOFcjs = require('./chunk-M7F5AAOF.cjs');
var _chunkHTVJXQRMcjs = require('./chunk-HTVJXQRM.cjs');
// src/rsbuild.ts
var _http = require('http');
var _path = require('path'); var _path2 = _interopRequireDefault(_path);
var _process = require('process'); var _process2 = _interopRequireDefault(_process);
var _utils = require('@pengzhanbo/utils');
var _core = require('@rspack/core'); var _core2 = _interopRequireDefault(_core);
var _picocolors = require('picocolors'); var _picocolors2 = _interopRequireDefault(_picocolors);
var _portfinder = require('portfinder');
function pluginMockServer(options = {}) {
return {
name: "plugin-mock-server",
setup(api) {
const rsbuildConfig = api.getRsbuildConfig();
const resolvedOptions = _chunkM7F5AAOFcjs.resolvePluginOptions.call(void 0, options, {
proxies: resolveConfigProxies(rsbuildConfig),
alias: {},
context: api.context.rootPath,
plugins: [new _core2.default.DefinePlugin(_optionalChain([rsbuildConfig, 'access', _ => _.source, 'optionalAccess', _2 => _2.define]) || {})]
});
if (_process2.default.env.NODE_ENV === "production") {
if (resolvedOptions.build) {
api.onAfterBuild(async () => {
const config = api.getNormalizedConfig();
await _chunkM7F5AAOFcjs.buildMockServer.call(void 0,
resolvedOptions,
_path2.default.resolve(_process2.default.cwd(), config.output.distPath.root || "dist")
);
});
}
return;
}
const mockCompiler = _chunkM7F5AAOFcjs.createMockCompiler.call(void 0, resolvedOptions);
api.modifyRsbuildConfig((config) => {
updateServerProxyConfigByHttpMock(config);
const mockMiddleware = _chunkM7F5AAOFcjs.createMockMiddleware.call(void 0, mockCompiler, resolvedOptions);
config.dev ??= {};
config.dev.setupMiddlewares ??= [];
config.dev.setupMiddlewares.push((middlewares, server2) => {
mockMiddleware(middlewares, () => server2.sockWrite("static-changed"));
});
});
let port = 3079;
const shouldMockWs = _utils.toArray.call(void 0, resolvedOptions.wsPrefix).length > 0;
if (shouldMockWs) {
api.modifyRsbuildConfig(async (config) => {
const defaultPort = (_optionalChain([config, 'access', _3 => _3.server, 'optionalAccess', _4 => _4.port]) || port) + 1;
port = await _portfinder.getPortPromise.call(void 0, { port: defaultPort });
updateServerProxyConfigByWSMock(config, options.wsPrefix || [], port);
});
}
let server;
function startMockServer() {
mockCompiler.run();
if (shouldMockWs) {
server = _http.createServer.call(void 0, );
_chunkHTVJXQRMcjs.mockWebSocket.call(void 0, mockCompiler, server, resolvedOptions);
server.listen(port);
}
}
function close() {
mockCompiler.close();
_optionalChain([server, 'optionalAccess', _5 => _5.close, 'call', _6 => _6()]);
}
api.onAfterCreateCompiler(({ compiler }) => {
if ("compilers" in compiler) {
compiler.compilers.forEach((compiler2) => {
mockCompiler.updateAlias(_optionalChain([compiler2, 'access', _7 => _7.options, 'access', _8 => _8.resolve, 'optionalAccess', _9 => _9.alias]) || {});
});
} else {
mockCompiler.updateAlias(_optionalChain([compiler, 'access', _10 => _10.options, 'access', _11 => _11.resolve, 'optionalAccess', _12 => _12.alias]) || {});
}
});
api.onAfterStartDevServer(startMockServer);
api.onAfterStartProdServer(startMockServer);
api.onExit(close);
}
};
}
function onProxyError(err, _req, res) {
console.error(_picocolors2.default.red(_optionalChain([err, 'optionalAccess', _13 => _13.stack]) || err.message));
res.statusCode = 500;
res.end();
}
function updateServerProxyConfigByHttpMock(config) {
if (!_optionalChain([config, 'access', _14 => _14.server, 'optionalAccess', _15 => _15.proxy]))
return;
if (_utils.isArray.call(void 0, config.server.proxy)) {
config.server.proxy = config.server.proxy.map((item) => {
if (typeof item !== "function" && !item.ws) {
const onProxyReq = item.onProxyReq;
const onError = item.onError;
return {
...item,
onError: onError || onProxyError,
onProxyReq: (proxyReq, req, ...args) => {
_optionalChain([onProxyReq, 'optionalCall', _16 => _16(proxyReq, req, ...args)]);
_chunkHTVJXQRMcjs.rewriteRequest.call(void 0, proxyReq, req);
}
};
}
return item;
});
} else if ("target" in config.server.proxy) {
const onProxyReq = config.server.proxy.onProxyReq;
config.server.proxy.onProxyReq = (proxyReq, req, ...args) => {
_optionalChain([onProxyReq, 'optionalCall', _17 => _17(proxyReq, req, ...args)]);
_chunkHTVJXQRMcjs.rewriteRequest.call(void 0, proxyReq, req);
};
config.server.proxy.onError ??= onProxyError;
} else if (config.server.proxy) {
const proxy = config.server.proxy;
Object.keys(proxy).forEach((key) => {
const target = proxy[key];
const options = typeof target === "string" ? { target } : target;
if (options.ws)
return;
const { onProxyReq, onError, ...rest } = options;
proxy[key] = {
...rest,
onProxyReq: (proxyReq, req, ...args) => {
_optionalChain([onProxyReq, 'optionalCall', _18 => _18(proxyReq, req, ...args)]);
_chunkHTVJXQRMcjs.rewriteRequest.call(void 0, proxyReq, req);
},
onError: onError || onProxyError
};
});
}
}
function updateServerProxyConfigByWSMock(config, wsPrefix, port) {
config.server ??= {};
const proxy = config.server.proxy ??= {};
const wsTarget = `ws://localhost:${port}`;
const prefix = _utils.toArray.call(void 0, wsPrefix);
const has = (context) => typeof context === "string" && prefix.includes(context);
const used = /* @__PURE__ */ new Set();
function updateProxy(item) {
if (_utils.isArray.call(void 0, item.context)) {
item.context = item.context.filter(has);
} else if (has(item.context)) {
used.add(item.context);
item.target = wsTarget;
}
}
if (_utils.isArray.call(void 0, proxy)) {
for (const item of proxy) {
if (typeof item !== "function" && item.context && item.ws) {
updateProxy(item);
}
}
prefix.filter((context) => !used.has(context)).forEach((context) => proxy.push({ context, target: wsTarget }));
} else if ("target" in proxy) {
if (proxy.ws) {
updateProxy(proxy);
const list = config.server.proxy = [proxy];
prefix.filter((context) => !used.has(context)).forEach((context) => list.push({ context, target: wsTarget }));
}
} else {
Object.entries(proxy).forEach(([, opt]) => {
if (typeof opt !== "string" && opt.ws) {
updateProxy(opt);
}
});
prefix.filter((context) => !used.has(context)).forEach((context) => {
proxy[context] = { target: wsTarget, ws: true };
});
}
}
function resolveConfigProxies(config) {
config.server ??= {};
const proxy = config.server.proxy ??= {};
const proxies = [];
if (_utils.isArray.call(void 0, proxy)) {
for (const item of proxy) {
if (typeof item !== "function" && item.context && !item.ws) {
proxies.push(..._utils.toArray.call(void 0, item.context));
}
}
} else if ("target" in proxy) {
if (!proxy.ws)
proxies.push(..._utils.toArray.call(void 0, proxy.context));
} else {
Object.entries(proxy).forEach(([context, opt]) => {
if (typeof opt === "string" || !opt.ws)
proxies.push(context);
});
}
return proxies;
}
exports.pluginMockServer = pluginMockServer;