UNPKG

f2e-server3

Version:

f2e-server 3.0

159 lines (158 loc) 7.56 kB
"use strict"; 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;