f2e-server3
Version:
f2e-server 3.0
159 lines (158 loc) • 7.56 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path = __importStar(require("node:path"));
const fs = __importStar(require("node:fs"));
const logger_1 = __importDefault(require("../../utils/logger"));
const node_process_1 = require("node:process");
const _ = __importStar(require("../../utils/misc"));
const store_1 = require("./store");
const utils_1 = require("./utils");
const utils_2 = require("../../utils");
const middleware_esbuild = {
name: 'esbuild',
mode: ['dev', 'build'],
execute: (conf) => {
const { root, esbuild: esbuildConfig, mode } = conf;
// prod 模式下不加载esbuild
if (!esbuildConfig) {
return;
}
const { esbuildrc = utils_1.default_config.esbuildrc, external_lib_name = utils_1.default_config.external_lib_name, reg_inject = utils_1.default_config.reg_inject, reg_replacer = utils_1.default_config.reg_replacer, cache_root = utils_1.default_config.cache_root, } = esbuildConfig;
const conf_path = path.join(root, esbuildrc);
// 使用默认配置,检查配置文件是否存在,不存在时,中间件失效
if (!fs.existsSync(conf_path)) {
// logger.debug(`[esbuild] esbuildrc: ${conf_path} not found, esbuild middleware disabled`)
return;
}
try {
require(conf_path);
}
catch (e) {
logger_1.default.error(`[esbuild] esbuildrc: ${conf_path} is not valid:`, e);
(0, node_process_1.exit)(1);
}
// 检查esbuild依赖
(0, utils_2.dynamicImport)('esbuild').catch(e => {
logger_1.default.error(`[esbuild] esbuild not found, esbuild middleware disabled`);
(0, node_process_1.exit)(1);
});
const esbuildOptions = [].concat(require(conf_path)).map(option => ({
...option,
...(esbuildConfig.esbuildOptions || utils_1.default_config.esbuildOptions),
}));
const build = async function (store) {
await Promise.all(esbuildOptions.map(async (option) => {
delete option.hot_modules;
await (0, store_1.build_option)({
store, conf, _option: option,
});
}));
};
const watch = async function (store) {
await Promise.all(esbuildOptions.map(async (option) => {
const lib_hash = (0, utils_1.generate_hash)(option.external || [], conf.system_hash);
const hot_modules = option.hot_modules || [];
delete option.hot_modules;
const entryPaths = (0, utils_1.getEntryPaths)(option.entryPoints);
const options = entryPaths.map((entry) => {
return {
...option,
entryPoints: {
[entry.out]: entry.in,
},
};
});
return Promise.all(hot_modules.map(async (moduleId) => {
const filename = (0, utils_1.generate_filename)(external_lib_name, moduleId.replace(/[\\\/]/g, '_'));
(0, utils_1.build_external_file)({
filename,
conf: esbuildConfig,
modules: [moduleId],
lib_hash,
});
await (0, store_1.watch_option)({
store, hot_modules: [], conf, _option: {
...option,
entryPoints: [cache_root + '/' + filename],
},
});
}).concat(options.map((option) => {
return (0, store_1.watch_option)({
store, hot_modules, conf, _option: option,
});
})));
}));
};
return {
async onMemoryInit(store) {
return mode === 'dev' ? await watch(store) : await build(store);
},
async onSet(pathname, data, store) {
const result = {
originPath: pathname,
outputPath: pathname,
data,
};
if (reg_inject.test(pathname) && data) {
result.data = data.toString()
// 原来正则在某些情况下会导致v8(node和chrome)卡死,JavaScriptCore(bun和safari)不会,所以这里用简单正则替换
.replace(reg_replacer || /<script\s.*?src="(.*?)".*?>\s*<\/script\>/g, function (___, src) {
const key = _.pathname_fixer('/' === src.charAt(0) ? src : path.join(path.dirname(pathname), src));
const item = store_1.origin_map.get(key);
let scripts = [];
if (item) {
item.css_paths?.forEach(cssPath => {
scripts.push(`<link rel="stylesheet" href="/${cssPath}">\n`);
});
if (item.lib_hash) {
const sourcefile = (0, utils_1.generate_filename)(external_lib_name, item.lib_hash);
scripts.push(`<script src="/${cache_root}/${sourcefile}"></script>\n`);
}
item.hot_modules?.forEach(moduleId => {
const sourcefile = (0, utils_1.generate_filename)(external_lib_name, moduleId.replace(/[\\\/]/g, '_'));
scripts.push(`<script data-module="${moduleId}" src="/${cache_root}/${sourcefile}"></script>\n`);
});
}
return scripts.join('') + ___;
});
}
return result;
},
async buildWatcher(pathname, eventType, build, store) {
const item = store_1.origin_map.get(pathname);
if (item && item.rebuilds.size > 0) {
for (const rebuild of item.rebuilds) {
await rebuild();
}
}
},
};
}
};
exports.default = middleware_esbuild;