使用 Express + EJS,如何呈现为静态站点?
Using Express + EJS, how can I render as a static site?
我正在使用 Express Application Generator,并从默认选项中选择 "EJS"。我有一个不错的工作站点,但老实说,我只需要服务器每天更新一次缓存 API。
在其他项目中,当我使用 hexo.js 时,我将所有 EJS 模板呈现到 'public' 文件夹中。
目前 express 可以很好地为我的 EJS 应用程序提供服务,但我如何让它吐出一个完整的静态版本?
查看 EJS 文档,我发现了一些促使我尝试这个的东西:
ejs /home/kyle/code/corona/corona-server/views/analysis.ejs -o test.html
/usr/local/lib/node_modules/ejs/lib/ejs.js:359
throw err;
^
Error: ejs:1
>> 1| <%- include("_partials/base", {
2| page:"analysis",
3| combo:["ionrangeslider"],
4| scripts: ["analysis"],
Could not find the include file "_partials/base"
at getIncludePath (/usr/local/lib/node_modules/ejs/lib/ejs.js:183:13)
at includeFile (/usr/local/lib/node_modules/ejs/lib/ejs.js:309:19)
at include (/usr/local/lib/node_modules/ejs/lib/ejs.js:689:16)
at eval (eval at compile (/usr/local/lib/node_modules/ejs/lib/ejs.js:661:12), <anonymous>:10:17)
at anonymous (/usr/local/lib/node_modules/ejs/lib/ejs.js:691:17)
at Object.exports.render (/usr/local/lib/node_modules/ejs/lib/ejs.js:423:37)
at Immediate.run (/usr/local/lib/node_modules/ejs/bin/cli.js:197:20)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
但无济于事,当 运行 像这样时,它似乎无法处理相对文件路径。
正确的做法是什么?
我最终为此使用了 express 而不是 EJS CLI。而在默认提供的设置中,一个人使用 res.render
,我们可以改为使用 app.render
(res.render
内部使用)。
完成后,我们使用节点 fs
将输出写入文件。
这是我在本地工作的一个切碎版本,虽然这个迭代本身未经测试(应该工作或非常接近)
// make-static.js
var express = require('express');
const fs = require('fs');
const { spawn } = require("child_process");
// note that whatever is in index 0 will be duplicated as 'index' as well
let activePages = ['compare', 'analysis', 'about'];
// `hasApp` can be req, res, or { app }.
let renderPage = (hasApp, pageName, pageTemplate, data) => new Promise(
(resolve, reject) => {
hasApp.app.render(pageTemplate, { data, region:"" }, (err, renderedPage) => {
fs.writeFile(`public/${pageName}.html`, renderedPage, (err) => {
if (err) throw err;
else {
// success case, the file was saved
console.log('Render successful!');
resolve()
}
});
})
}
);
let renderEJS = function(data, hasApp) {
return // feature flag for surge build
Promise.all(
activePages.map((page, i) => {
let renderPromises = [];
if (i === 0) renderPromises.push(renderPage(hasApp, '200', page, data))
renderPromises.push(renderPage(hasApp, page, page, data))
return Promise.all(renderPromises)
})
)
exports.renderEJS = renderEJS;
// app.js, root of express application
/* all the normal stuff, only commented out to draw your attention to the
main focus here
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const routerFor = {
analysis: require('./routes/analysis.js'),
};
*/
var app = express();
require('./utils/make-static').renderEJS
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
/* etc., etc.
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
*/
renderEJS({ params:null, required:"", by:[1,2,3], your:"ejs templates" }, { app })
我正在使用 Express Application Generator,并从默认选项中选择 "EJS"。我有一个不错的工作站点,但老实说,我只需要服务器每天更新一次缓存 API。
在其他项目中,当我使用 hexo.js 时,我将所有 EJS 模板呈现到 'public' 文件夹中。
目前 express 可以很好地为我的 EJS 应用程序提供服务,但我如何让它吐出一个完整的静态版本?
查看 EJS 文档,我发现了一些促使我尝试这个的东西:
ejs /home/kyle/code/corona/corona-server/views/analysis.ejs -o test.html
/usr/local/lib/node_modules/ejs/lib/ejs.js:359
throw err;
^
Error: ejs:1
>> 1| <%- include("_partials/base", {
2| page:"analysis",
3| combo:["ionrangeslider"],
4| scripts: ["analysis"],
Could not find the include file "_partials/base"
at getIncludePath (/usr/local/lib/node_modules/ejs/lib/ejs.js:183:13)
at includeFile (/usr/local/lib/node_modules/ejs/lib/ejs.js:309:19)
at include (/usr/local/lib/node_modules/ejs/lib/ejs.js:689:16)
at eval (eval at compile (/usr/local/lib/node_modules/ejs/lib/ejs.js:661:12), <anonymous>:10:17)
at anonymous (/usr/local/lib/node_modules/ejs/lib/ejs.js:691:17)
at Object.exports.render (/usr/local/lib/node_modules/ejs/lib/ejs.js:423:37)
at Immediate.run (/usr/local/lib/node_modules/ejs/bin/cli.js:197:20)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
但无济于事,当 运行 像这样时,它似乎无法处理相对文件路径。
正确的做法是什么?
我最终为此使用了 express 而不是 EJS CLI。而在默认提供的设置中,一个人使用 res.render
,我们可以改为使用 app.render
(res.render
内部使用)。
完成后,我们使用节点 fs
将输出写入文件。
这是我在本地工作的一个切碎版本,虽然这个迭代本身未经测试(应该工作或非常接近)
// make-static.js
var express = require('express');
const fs = require('fs');
const { spawn } = require("child_process");
// note that whatever is in index 0 will be duplicated as 'index' as well
let activePages = ['compare', 'analysis', 'about'];
// `hasApp` can be req, res, or { app }.
let renderPage = (hasApp, pageName, pageTemplate, data) => new Promise(
(resolve, reject) => {
hasApp.app.render(pageTemplate, { data, region:"" }, (err, renderedPage) => {
fs.writeFile(`public/${pageName}.html`, renderedPage, (err) => {
if (err) throw err;
else {
// success case, the file was saved
console.log('Render successful!');
resolve()
}
});
})
}
);
let renderEJS = function(data, hasApp) {
return // feature flag for surge build
Promise.all(
activePages.map((page, i) => {
let renderPromises = [];
if (i === 0) renderPromises.push(renderPage(hasApp, '200', page, data))
renderPromises.push(renderPage(hasApp, page, page, data))
return Promise.all(renderPromises)
})
)
exports.renderEJS = renderEJS;
// app.js, root of express application
/* all the normal stuff, only commented out to draw your attention to the
main focus here
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
const routerFor = {
analysis: require('./routes/analysis.js'),
};
*/
var app = express();
require('./utils/make-static').renderEJS
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
/* etc., etc.
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
*/
renderEJS({ params:null, required:"", by:[1,2,3], your:"ejs templates" }, { app })