前言
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 参考文档