refactor(node/eejs): convert to ESM (1 file)

Self-referential exports.X pattern replaced by a module-private `eejs` object
that's also the default export. __dirname shimmed via import.meta.url.
`require` (used by templates as args.require) preserved via createRequire.
This commit is contained in:
SamTV12345 2026-04-26 13:06:45 +02:00
parent 4e6d073213
commit fb7f2e22a3

View file

@ -17,67 +17,83 @@
/* Basic usage:
*
* require("./index").require("./path/to/template.ejs")
* import eejs from './index.js';
* eejs.require("./path/to/template.ejs")
*/
import ejs from 'ejs';
import fs from 'fs';
const hooks = require('../../static/js/pluginfw/hooks');
import hooks from '../../static/js/pluginfw/hooks.js';
import path from 'node:path';
// @ts-ignore
import resolve from 'resolve';
import settings from '../utils/Settings';
import {pluginInstallPath} from '../../static/js/pluginfw/installer'
import settings from '../utils/Settings.js';
import { pluginInstallPath } from '../../static/js/pluginfw/installer.js';
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
import { createRequire } from 'node:module';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const requireFromHere = createRequire(import.meta.url);
const templateCache = new Map();
exports.info = {
__output_stack: [],
block_stack: [],
file_stack: [],
args: [],
interface EejsInfo {
__output_stack: any[];
__output?: any;
block_stack: string[];
file_stack: { path: string }[];
args: any[];
}
const eejs: any = {
info: {
__output_stack: [],
block_stack: [],
file_stack: [],
args: [],
} as EejsInfo,
};
const getCurrentFile = () => exports.info.file_stack[exports.info.file_stack.length - 1];
const getCurrentFile = () => eejs.info.file_stack[eejs.info.file_stack.length - 1];
exports._init = (b: any, recursive: boolean) => {
exports.info.__output_stack.push(exports.info.__output);
exports.info.__output = b;
eejs._init = (b: any, _recursive: boolean) => {
eejs.info.__output_stack.push(eejs.info.__output);
eejs.info.__output = b;
};
exports._exit = (b:any, recursive:boolean) => {
exports.info.__output = exports.info.__output_stack.pop();
eejs._exit = (_b: any, _recursive: boolean) => {
eejs.info.__output = eejs.info.__output_stack.pop();
};
exports.begin_block = (name:string) => {
exports.info.block_stack.push(name);
exports.info.__output_stack.push(exports.info.__output.get());
exports.info.__output.set('');
eejs.begin_block = (name: string) => {
eejs.info.block_stack.push(name);
eejs.info.__output_stack.push(eejs.info.__output.get());
eejs.info.__output.set('');
};
exports.end_block = () => {
const name = exports.info.block_stack.pop();
const renderContext = exports.info.args[exports.info.args.length - 1];
const content = exports.info.__output.get();
exports.info.__output.set(exports.info.__output_stack.pop());
const args = {content, renderContext};
eejs.end_block = () => {
const name = eejs.info.block_stack.pop();
const renderContext = eejs.info.args[eejs.info.args.length - 1];
const content = eejs.info.__output.get();
eejs.info.__output.set(eejs.info.__output_stack.pop());
const args = { content, renderContext };
hooks.callAll(`eejsBlock_${name}`, args);
exports.info.__output.set(exports.info.__output.get().concat(args.content));
eejs.info.__output.set(eejs.info.__output.get().concat(args.content));
};
exports.require = (name:string, args:{
e?: Function,
require?: Function,
}, mod:{
filename:string,
paths:string[],
}) => {
eejs.require = (
name: string,
args: { e?: any; require?: Function },
mod: { filename: string; paths: string[] }
) => {
if (args == null) args = {};
let basedir = __dirname;
let paths:string[] = [];
let paths: string[] = [];
if (exports.info.file_stack.length) {
if (eejs.info.file_stack.length) {
basedir = path.dirname(getCurrentFile().path);
}
if (mod) {
@ -89,26 +105,31 @@ exports.require = (name:string, args:{
* Add the plugin install path to the paths array
*/
if (!paths.includes(pluginInstallPath)) {
paths.push(pluginInstallPath)
paths.push(pluginInstallPath);
}
const ejspath = resolve.sync(name, {paths, basedir, extensions: ['.html', '.ejs']});
const ejspath = resolve.sync(name, { paths, basedir, extensions: ['.html', '.ejs'] });
args.e = exports;
args.require = require;
args.e = eejs;
args.require = requireFromHere;
const cache = settings.maxAge !== 0;
const template = cache && templateCache.get(ejspath) || ejs.compile(
const template =
(cache && templateCache.get(ejspath)) ||
ejs.compile(
'<% e._init({get: () => __output, set: (s) => { __output = s; }}); %>' +
`${fs.readFileSync(ejspath).toString()}<% e._exit(); %>`,
{filename: ejspath});
{ filename: ejspath }
);
if (cache) templateCache.set(ejspath, template);
exports.info.args.push(args);
exports.info.file_stack.push({path: ejspath});
eejs.info.args.push(args);
eejs.info.file_stack.push({ path: ejspath });
const res = template(args);
exports.info.file_stack.pop();
exports.info.args.pop();
eejs.info.file_stack.pop();
eejs.info.args.pop();
return res;
};
export default eejs;