f2e-server3
Version:
f2e-server 3.0
232 lines (231 loc) • 9.7 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;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.watch_option = exports.build_option = exports.build_origin_map = exports.origin_map = exports.external_build = exports.save = void 0;
const path = __importStar(require("node:path"));
const fs = __importStar(require("node:fs"));
const _ = __importStar(require("../../utils/misc"));
const utils_1 = require("./utils");
const utils_2 = require("../../utils");
const save = async function (params) {
const { store, result, conf } = params;
const { root, esbuild } = conf;
if (!esbuild)
return;
const with_metafile = esbuild.with_metafile;
const { outputFiles = [], metafile } = result;
for (const outputFile of outputFiles) {
const outputPath = _.pathname_fixer(path.relative(root, outputFile.path));
const meta = metafile?.outputs?.[outputPath];
const originPath = meta?.entryPoint || outputPath;
store.save({
data: outputFile.text,
originPath,
outputPath,
});
/** js文件索引meta信息 */
if (with_metafile && metafile && /\.js$/.test(outputPath)) {
store.save({
originPath: outputPath + '.json',
outputPath: outputPath + '.json',
data: JSON.stringify(metafile, null, 2)
});
}
}
};
exports.save = save;
const external_build = async function ({ conf, store, option, lib_hash, }) {
const { external = [], ..._option } = option;
if (external.length === 0 || !conf.esbuild || !conf.esbuild.build_external) {
return;
}
const { cache_root = utils_1.default_config.cache_root, inject_global_name = utils_1.default_config.inject_global_name, external_lib_name = utils_1.default_config.external_lib_name, } = conf.esbuild;
const filename = (0, utils_1.generate_filename)(external_lib_name, lib_hash);
if (store.origin_map.has(cache_root + '/' + filename)) {
// 已经编译过的不再编译
return;
}
(0, utils_1.build_external_file)({
filename,
conf: conf.esbuild,
modules: external,
lib_hash,
});
const originPath = _.pathname_fixer(cache_root + '/' + filename);
const outputPath = _.pathname_fixer((option.outdir || '') + '/' + filename.replace(/\.ts$/, '.js'));
const cachePath = path.join(cache_root, filename.replace(/\.ts$/, '.js'));
if (fs.existsSync(cachePath)) {
store.save({
data: fs.readFileSync(cachePath, 'utf-8'),
originPath,
outputPath,
});
return;
}
const builder = await (0, utils_2.dynamicImport)('esbuild');
const result = await builder.build({
..._option,
entryPoints: [cache_root + '/' + filename],
bundle: true,
format: 'iife',
banner: {
'js': (0, utils_1.generate_inject_code)(inject_global_name, lib_hash, conf.mode === 'dev'),
},
});
for (const outputFile of result.outputFiles || []) {
if (outputFile.path.endsWith('.js')) {
fs.writeFile(cachePath, outputFile.text, (err) => {
if (err) {
utils_2.logger.error(err);
}
});
store.save({
data: outputFile.text,
originPath,
outputPath,
});
}
}
};
exports.external_build = external_build;
exports.origin_map = new Map();
const build_origin_map = function ({ result, rebuild, store, lib_hash, hot_modules = [], root, }) {
if (!result)
return;
const outputs = result?.metafile?.outputs;
const css_paths = (0, utils_1.build_css_paths)(result, root);
outputs && Object.entries(outputs).map(([filename, meta]) => {
if (filename.endsWith('.js')) {
Object.keys(meta.inputs || {}).forEach(_inputPath => {
if (_inputPath.includes('node_modules'))
return;
const inputPath = _.pathname_fixer(_inputPath);
const found = exports.origin_map.get(inputPath) || {
lib_hash,
css_paths,
hot_modules,
rebuilds: new Set(),
};
if (rebuild) {
found.rebuilds.add(rebuild);
}
found.css_paths = css_paths;
exports.origin_map.set(inputPath, found);
store.ignores.add(inputPath);
});
}
});
};
exports.build_origin_map = build_origin_map;
const build_option = async ({ store, _option, conf, }) => {
if (!conf.esbuild)
return;
const { mode, esbuild: { build_external = utils_1.default_config.build_external, inject_global_name = utils_1.default_config.inject_global_name, } } = conf;
const option = {
write: false,
metafile: true,
sourcemap: true,
..._option,
minify: mode === 'build',
};
const builder = await (0, utils_2.dynamicImport)('esbuild');
const lib_hash = option.external && option.external.length > 0 ? (0, utils_1.generate_hash)(option.external, conf.system_hash) : '';
const with_libs = build_external && option.format === 'iife' && !!lib_hash;
if (with_libs) {
await (0, exports.external_build)({ conf, store, option, lib_hash });
delete option.inject;
}
const GLOBAL_NAME = (0, utils_1.generate_global_name)(inject_global_name, lib_hash);
const result = await builder.build({
...option,
banner: with_libs ? {
...(option.banner || {}),
js: `${option.banner?.js || ''};${(0, utils_1.generate_banner_code)(inject_global_name, lib_hash)}`
} : option.banner,
define: {
'process.env.NODE_ENV': mode === 'dev' ? '"development"' : '"production"',
...(option.define || {}),
'import.meta.hot': `${GLOBAL_NAME}.hot`,
},
});
(0, exports.build_origin_map)({ result, store, lib_hash, hot_modules: [], root: conf.root });
await (0, exports.save)({ store, result, conf });
};
exports.build_option = build_option;
const watch_option = async ({ store, _option, hot_modules = [], conf, }) => {
if (!conf.esbuild)
return;
const { mode, esbuild: { build_external = utils_1.default_config.build_external, inject_global_name = utils_1.default_config.inject_global_name, } } = conf;
const option = {
write: false,
metafile: true,
sourcemap: true,
..._option,
minify: _option.minify || mode === 'build',
};
const builder = await (0, utils_2.dynamicImport)('esbuild');
const lib_hash = option.external && option.external.length > 0 ? (0, utils_1.generate_hash)(option.external, conf.system_hash) : '';
const with_libs = build_external && option.format === 'iife' && !!lib_hash;
if (with_libs) {
await (0, exports.external_build)({ conf, store, option, lib_hash });
delete option.inject;
}
const GLOBAL_NAME = (0, utils_1.generate_global_name)(inject_global_name, lib_hash);
const ctx = await builder.context({
...option,
external: hot_modules.concat(option.external || []),
banner: with_libs ? {
...(option.banner || {}),
js: `${option.banner?.js || ''};${(0, utils_1.generate_banner_code)(inject_global_name, lib_hash)}`
} : option.banner,
define: {
'process.env.NODE_ENV': mode === 'dev' ? '"development"' : '"production"',
...(option.define || {}),
'import.meta.hot': `${GLOBAL_NAME}.hot`,
},
});
const rebuild = async function rebuild() {
try {
const result = await ctx.rebuild();
(0, exports.build_origin_map)({ result, rebuild, store, lib_hash, hot_modules, root: conf.root });
utils_2.logger.debug(`[esbuild] ${JSON.stringify(option.entryPoints)} rebuild`);
await (0, exports.save)({ store, result, conf });
}
catch (error) {
(0, utils_1.getEntryPaths)(option.entryPoints).forEach(({ in: originPath, out: outputPath }) => {
store.save({
error,
originPath,
data: undefined,
outputPath,
});
});
}
};
const result = await ctx.rebuild();
(0, exports.build_origin_map)({ result, rebuild, store, lib_hash, hot_modules, root: conf.root });
await (0, exports.save)({ store, result, conf });
};
exports.watch_option = watch_option;