UNPKG

f2e-server3

Version:

f2e-server 3.0

96 lines (88 loc) 3.85 kB
import * as fs from 'node:fs'; import path from "node:path"; import * as _ from '../../utils/misc' import { code_define, code_externals } from "../../utils/templates"; import { VERSION } from "../../utils/engine"; import { EsbuildConfig } from './interface'; import { BuildOptions, BuildResult } from 'esbuild'; import crypto from 'node:crypto'; export const default_config: Required<EsbuildConfig> = { esbuildrc: '.esbuildrc.js', esbuildOptions: {}, build_external: true, with_metafile: false, reg_inject: /index\.html$/, reg_replacer: /<script\s.*?src="(.*?)".*?>\s*<\/script\>/g, cache_root: '.f2e_cache', inject_global_name: '__f2e_esbuild_inject__', external_lib_name: 'external_lib', } export const generate_global_name = (inject_global_name: string, lib_hash: string) => `window.${inject_global_name}${lib_hash ? `_${lib_hash}` : ''}` export const generate_filename = (filename: string, hash: string) => { const ext = path.extname(filename) return `${path.basename(filename, ext)}${hash ? `_${hash}` : ''}.ts` } export const generate_inject_code = (inject_global_name: string, lib_hash: string, is_dev: boolean) => { return _.template(code_define, { VERSION, GLOBAL_NAME: generate_global_name(inject_global_name, lib_hash), is_dev }) } export const generate_externals_code = (inject_global_name: string, external: string[], lib_hash: string) => { return _.template(code_externals, { external, GLOBAL_NAME: generate_global_name(inject_global_name, lib_hash) }) } export const generate_banner_code = (inject_global_name: string, lib_hash: string) => { if (!lib_hash) { return '' } const GLOBAL_NAME = generate_global_name(inject_global_name, lib_hash) return `\nrequire = ${GLOBAL_NAME} && ${GLOBAL_NAME}.require;` } const write_cache_file = (cache_path: string, filename: string, code: string) => { if (!fs.existsSync(cache_path)) { fs.mkdirSync(cache_path, { recursive: true }) } fs.writeFileSync(path.join(cache_path, filename), code) } export const generate_hash = (modules: string[], system_hash: string) => { if (modules.length === 0) { return '' } return crypto.createHash('md5').update(modules.sort().join(',') + system_hash).digest('hex').slice(0, 8) } export interface BuildExternalFileOptions { filename: string; conf: EsbuildConfig; modules: string[]; lib_hash: string; } export const build_external_file = ({ filename, conf, modules, lib_hash }: BuildExternalFileOptions) => { const { cache_root = default_config.cache_root, inject_global_name = default_config.inject_global_name, } = conf if (fs.existsSync(path.join(cache_root, filename))) { // 已经编译过的不再编译 return } const js_code = generate_externals_code(inject_global_name, modules, lib_hash) write_cache_file(cache_root, filename, js_code) } export const getEntryPaths = (entryPoints: BuildOptions['entryPoints']) => { const paths: {in: string, out: string}[] = [] if (Array.isArray(entryPoints)) { for (const entry of entryPoints) { if (typeof entry === 'string') { paths.push({in: entry, out: entry}) } else { paths.push(entry) } } } else if (entryPoints) { Object.entries(entryPoints).forEach((item: [string, string]) => { paths.push({in: item[1], out: item[0]}) }) } return paths } export const build_css_paths = (result: BuildResult, root: string) => { return result?.outputFiles?.filter(_outputFile => _outputFile.path.endsWith('.css')) .map(_outputFile => _.pathname_fixer(path.relative(root, _outputFile.path))) || [] }