ejs在默認狀況下只是一個呈現工具,只是負責依據傳入的參數進行模板渲染。然而,在使用過程當中(hexo-renderer-ejs),我但願在模板中使用require引入外部模塊,使用__dirname,__filename變量,即便這個用法是不推薦的。html
經過修改ejs的源碼來實現支持,我使用的版本是ejs@^2.6.1。
打開node_modules/ejs/lib/ejs.js文件,在開頭添加:node
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:api
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 參考文檔