NodeJS 如何从ExpressJS路由保存渲染的html视图文件

s4n0splo  于 2022-12-29  发布在  Node.js
关注(0)|答案(2)|浏览(111)

我已经使用ExpressJSPUG构建了一个静态网站的几个页面,以获得模板引擎的优势。
但是现在我需要导出所有ExpressJSRoutes呈现的所有原始HTML。
有没有软件包可以帮我做到这一点?或者我必须编写自定义命令,迭代所有的Routes,并保存渲染输出?
如果定制命令是唯一的方法,那么如何迭代所有routes并获得渲染输出?

ahy6op9u

ahy6op9u1#

我找不到任何库或资源来实现我想要的东西,但是用我的一些脏代码、黑客和软件包,我能够导出所有的路由。

**注意:**我没有编写node命令来导出html,而是添加了一个路由来触发操作,下面是该路由的代码:

app.use('/export_templates', router.get('/', async function (req, res, next) {
  const endpoints = listEndpoints(app);
  const failedEndpoints = [];

  for (const i in endpoints) {
    const endpoint = endpoints[i];

    if (endpoint.path == '/export_templates') {
      continue;
    }

    try {
      const res = await axios.get('http://'+req.headers.host+''+endpoint.path+'?export=true');
    }
    catch(error) {
      failedEndpoints.push(endpoint.path);
    }
  }

  res.json({
    "status": "succes",
    "message": "Please check templates folder for the latest exported html templates",
    "failed": failedEndpoints
  })
}));

基本上,此路由会迭代并使用export=true参数向所有可用路由发出请求。
然后在每个route view函数中,一个条件检查export参数是否可用,然后调用exportTemplateFile函数,将pug模板位置和新文件名作为函数参数。如果请求不包含export参数,则请求的路由将简单地输出什么模板。
示例路线:

router.get('/', function(req, res, next) {
  if (req.query.export) {
    exportTemplateFile('views/index.pug', 'index.html');
  }

  res.render('index.pug');
});

下面是完成导出过程的2 util函数的代码

function createTemplateFile(filename) {
  fs.open(filename,'r',function(err, fd){
    if (err) {
      fs.writeFile(filename, '', function(err) {
          if(err) {
              console.log(err);
          }
      });
    }
  });
}

function exportTemplateFile(templateLocation, templateName) {
  const html = pretty(pug.renderFile(templateLocation));

  createTemplateFile('templates/'+templateName);

  var stream = fs.createWriteStream('templates/'+templateName);
  stream.once('open', function (fd) {
    stream.write(html);
    stream.end();
  });
}

createTemplateFile函数只是在文件不存在时创建一个新文件。
exportTemplateFile函数将HTML保存在pug呈现的html变量中,并使用pretty包对其进行修饰,然后覆盖新的模板文件。

**注意:**在我的例子中,所有的pug模板都是静态的,所以我不需要向pug.renderFile函数传递任何上下文,但是如果你需要在pug模板中使用任何上下文,你可以简单地把它和模板位置一起传递。

3duebb1j

3duebb1j2#

同样答案的编辑版本。
首先,非常感谢你解决了这个问题。我已经对你的代码做了一些修改,因为每个新的错误。
下面是ejs用户使用async和await函数的代码

const express = require('express')
const ejs = require('ejs')
const fs = require('fs')
const app = express()
const port = 3000

//set the templating engine as ejs
app.set('view engine', 'ejs');

function createTemplateFile(filename) {
    fs.open(filename,'r',function(err, fd){
      if (err) {
        fs.writeFile(filename, '', function(err) {
            if(err) {
                console.log(err);
            }
        });
      }
    });
  }
  
  async function exportTemplateFile(templateLocation, templateName) {
    var html = await ejs.renderFile(templateLocation);
  
    createTemplateFile('templates/'+templateName);
  
    var stream = fs.createWriteStream('templates/'+templateName);
    stream.once('open', function (fd) {
      stream.write(`${html}`);
      stream.end();
    });
  }

app.get('/', (req, res, next) => {
  res.render('./pages/home')
    exportTemplateFile('views/pages/home.ejs', 'index.html');
    console.log('file rendered and saved successfully')
})

app.listen(port, () => {
  console.log(`App is listening on port ${port}`)
})

相关问题