@rspack/cli
Version:
CLI for rspack
182 lines (181 loc) • 9.01 kB
JavaScript
;
exports.ids = [
'390'
];
exports.modules = {
"./src/utils/profile.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
__webpack_require__.d(__webpack_exports__, {
applyProfile: ()=>applyProfile
});
var node_fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("node:fs");
var node_fs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/ __webpack_require__.n(node_fs__WEBPACK_IMPORTED_MODULE_0__);
var node_inspector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("node:inspector");
var node_inspector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/ __webpack_require__.n(node_inspector__WEBPACK_IMPORTED_MODULE_1__);
var node_path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("node:path");
var node_path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/ __webpack_require__.n(node_path__WEBPACK_IMPORTED_MODULE_2__);
var node_url__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("node:url");
var _rspack_core__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("@rspack/core");
function _define_property(obj, key, value) {
if (key in obj) Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
else obj[key] = value;
return obj;
}
const timestamp = Date.now();
const defaultOutputDirname = node_path__WEBPACK_IMPORTED_MODULE_2___default().resolve(`.rspack-profile-${timestamp}-${process.pid}`);
const defaultJSCPUProfileOutput = node_path__WEBPACK_IMPORTED_MODULE_2___default().join(defaultOutputDirname, "./jscpuprofile.json");
const defaultRustTraceChromeOutput = node_path__WEBPACK_IMPORTED_MODULE_2___default().join(defaultOutputDirname, "./trace.json");
const defaultRustTraceLoggerOutput = "stdout";
const defaultRustTraceFilter = "trace";
const defaultRustTraceLayer = "chrome";
const defaultLoggingOutput = node_path__WEBPACK_IMPORTED_MODULE_2___default().join(defaultOutputDirname, "./logging.json");
function resolveProfile(value) {
if ("ALL" === value.toUpperCase()) return {
TRACE: {
filter: defaultRustTraceFilter,
layer: defaultRustTraceLayer,
output: defaultRustTraceChromeOutput
},
JSCPU: {
output: defaultJSCPUProfileOutput
},
LOGGING: {
output: defaultLoggingOutput
}
};
if (value.startsWith("[") && value.endsWith("]")) return {
TRACE: resolveRustTraceOptions(value.slice(1, value.length - 1)),
JSCPU: {
output: defaultJSCPUProfileOutput
},
LOGGING: {
output: defaultLoggingOutput
}
};
return value.split("|").reduce((acc, cur)=>{
const upperCur = cur.toUpperCase();
if (upperCur.startsWith("TRACE")) acc.TRACE = resolveRustTraceOptions(cur.slice(6));
else if (upperCur.startsWith("JSCPU")) acc.JSCPU = resolveJSCPUProfileOptions(cur.slice(6));
else if (upperCur.startsWith("LOGGING")) acc.LOGGING = resolveLoggingOptions(cur.slice(8));
return acc;
}, {});
}
function resolveJSCPUProfileOptions(value) {
if (value.includes("=")) {
const parsed = new node_url__WEBPACK_IMPORTED_MODULE_3__.URLSearchParams(value);
return {
output: parsed.get("output") || defaultJSCPUProfileOutput
};
}
return {
output: value || defaultJSCPUProfileOutput
};
}
function isSupportedLayer(layer) {
const SUPPORTED_LAYERS = [
"chrome",
"logger",
"otel"
];
return SUPPORTED_LAYERS.includes(layer);
}
function resolveRustTraceOptions(value) {
if (value.includes("=")) {
const parsed = new node_url__WEBPACK_IMPORTED_MODULE_3__.URLSearchParams(value);
const filter = parsed.get("filter") || defaultRustTraceFilter;
const layer = parsed.get("layer") || defaultRustTraceLayer;
const output = "chrome" === layer ? parsed.get("output") || defaultRustTraceChromeOutput : parsed.get("output") || defaultRustTraceLoggerOutput;
if (!isSupportedLayer(layer)) throw new Error(`${layer} is not a valid layer, should be chrome or logger`);
return {
filter,
layer,
output
};
}
return {
filter: value || defaultRustTraceFilter,
layer: defaultRustTraceLayer,
output: defaultRustTraceChromeOutput
};
}
function resolveLoggingOptions(value) {
if (value.includes("=")) {
const parsed = new node_url__WEBPACK_IMPORTED_MODULE_3__.URLSearchParams(value);
return {
output: parsed.get("output") || defaultLoggingOutput
};
}
return {
output: value || defaultLoggingOutput
};
}
class RspackProfileJSCPUProfilePlugin {
apply(compiler) {
const session = new (node_inspector__WEBPACK_IMPORTED_MODULE_1___default()).Session();
session.connect();
session.post("Profiler.enable");
session.post("Profiler.start");
compiler.hooks.done.tapAsync(RspackProfileJSCPUProfilePlugin.name, (_stats, callback)=>{
if (compiler.watchMode) return callback();
session.post("Profiler.stop", (error, param)=>{
if (error) {
console.error("Failed to generate JS CPU profile:", error);
return;
}
node_fs__WEBPACK_IMPORTED_MODULE_0___default().writeFileSync(this.output, JSON.stringify(param.profile));
});
return callback();
});
}
constructor(output){
_define_property(this, "output", void 0);
this.output = output;
}
}
class RspackProfileLoggingPlugin {
apply(compiler) {
compiler.hooks.done.tapAsync(RspackProfileLoggingPlugin.name, (stats, callback)=>{
if (compiler.watchMode) return callback();
const logging = stats.toJson({
all: false,
logging: "verbose",
loggingTrace: true
});
node_fs__WEBPACK_IMPORTED_MODULE_0___default().writeFileSync(this.output, JSON.stringify(logging));
return callback();
});
}
constructor(output){
_define_property(this, "output", void 0);
this.output = output;
}
}
async function applyProfile(profileValue, item) {
const { asyncExitHook } = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "exit-hook"));
const entries = Object.entries(resolveProfile(profileValue));
if (entries.length <= 0) return;
await node_fs__WEBPACK_IMPORTED_MODULE_0___default().promises.mkdir(defaultOutputDirname);
for (const [kind, value] of entries){
await ensureFileDir(value.output);
if ("TRACE" === kind && "filter" in value) {
await _rspack_core__WEBPACK_IMPORTED_MODULE_4__.rspack.experiments.globalTrace.register(value.filter, value.layer, value.output);
asyncExitHook(_rspack_core__WEBPACK_IMPORTED_MODULE_4__.rspack.experiments.globalTrace.cleanup, {
wait: 500
});
} else if ("JSCPU" === kind) (item.plugins ??= []).push(new RspackProfileJSCPUProfilePlugin(value.output));
else if ("LOGGING" === kind) (item.plugins ??= []).push(new RspackProfileLoggingPlugin(value.output));
}
}
async function ensureFileDir(outputFilePath) {
const dir = node_path__WEBPACK_IMPORTED_MODULE_2___default().dirname(outputFilePath);
await node_fs__WEBPACK_IMPORTED_MODULE_0___default().promises.mkdir(dir, {
recursive: true
});
return dir;
}
}
};