前言

ejs在默认状况下只是一个出现工具,只是负责根据传入的参数进行模板渲染。然而,在应用过程中(hexo-renderer-ejs),我心愿在模板中应用require引入内部模块,应用__dirname__filename变量,即便这个用法是不举荐的

做法

通过批改ejs的源码来实现反对,我应用的版本是ejs@^2.6.1。
关上node_modules/ejs/lib/ejs.js文件,在结尾增加:

47 var fs = require('fs');48 var path = require('path');49 var utils = require('./utils');50 + var { Module, createRequireFromPath } = require('module')

找到Template.prototype中的compile函数,批改其中的returnedFn

    675 var returnedFn = opts.client ? fn : function anonymous(data) {      - var include = function (path, includeData) {      + var include = function (_path, includeData) {        var d = utils.shallowCopy({}, data);        if (includeData) {          d = utils.shallowCopy(d, includeData);        }        const customModule = new Module()        + d.__filename = getIncludePath(_path, opts)        + customModule.id = d.__dirname = path.dirname(d.__filename)        + d.module = customModule        + d.require = createRequireFromPath(d.__filename)        - return includeFile(path, opts)(d);        + return includeFile(_path, opts)(d);      };      + const customModule = new Module()      + customModule.id = customModule.path = data.__dirname = path.dirname(opts.filename)      + data.module = customModule      + data.__filename = opts.filename      + data.require = createRequireFromPath(data.__filename)      return fn.apply(opts.context, [data || {}, escapeFn, include, rethrow]);695 };
如果node的版本是 v12.2.0或以上,将createRequireFromPath改为createRequire 参考文档