如何使用 Pug 加载外部 CSS 文件
How to load external CSS file with Pug
我正在尝试将 css 文件和图像加载到我的哈巴狗文件中,但都没有加载。感觉就像我已经尝试了所有我能找到的方法却没有解决方案。我的 css 和图像在 public 文件夹中,用 express 设置为静态。我很感激我能得到的任何帮助。
文件夹结构如下:
server.js
views
checklist.pug
routes
checklist.js
public
images
logo.png
stylesheets
checklist.css
pdfs
server.js
require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const app = express();
const checklists = require('./routes/checklists');
const port = 3000;
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// View engine
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(express.static(path.join(__dirname, 'public')));
// Routes
app.use('/checklists', checklists);
app.listen(port, () => {
console.log(`Server started on port ${port}...`);
});
checklist.pug
html(lang='en')
head
link(href='stylesheets/checklist.css' rel='stylesheet')
link(rel='preconnect' href='https://fonts.googleapis.com')
link(rel='preconnect' href='https://fonts.gstatic.com' crossorigin)
link(href='https://fonts.googleapis.com/css2?family=Roboto&display=swap' rel='stylesheet')
body
div(class='checklist-title')
img(src='images/logo.png' alt='Logo...')
checklist.js
const express = require('express');
const aws = require('aws-sdk');
const { v4 } = require('uuid');
const puppeteer = require('puppeteer');
const pug = require('pug');
const dynamodb_config = require('../config/dynamodb/dynamo_config');
aws.config.update(dynamodb_config);
const { validateChecklist } = require('../middleware/validation');
const authenticateToken = require('../middleware/authenticateToken');
const router = express.Router();
const docClient = new aws.DynamoDB.DocumentClient();
const TABLE_NAME = 'Checklists';
// Generate html from checklist object, convert to pdf and send in response
router.get('/:id/pdf', authenticateToken, (req, res) => {
// Get the checklist and make sure the user owns it
const params = {
TableName: TABLE_NAME,
Key: {
id: req.params.id
}
}
docClient.get(params, async (err, data) => {
if (err) {
console.error(err);
res.status(500);
res.json({
error: err
});
}
else {
// Check that an item was found
if (typeof data.Item != 'undefined') {
// An item was found
// Check that the user who sent the request is the owner of the item
if (req.username == data.Item.createdBy) {
// CODE TO GENERATE CHECKLIST HERE
try {
const checklist = {
checklist: data.Item
}
// render html
const compiledFunction = pug.compileFile('views/checklist.pug');
const htmlContent = compiledFunction(checklist);
// convert html to pdf and save file
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setContent(htmlContent, { waitUntil: 'networkidle2' });
await page.pdf({ path: `pdfs/${req.username}.pdf`, printBackground: true });
await browser.close();
res.status(200);
res.json({
message: 'success'
});
}
catch (err) {
console.error(err);
}
}
else {
// User does not own the item
console.error('You are not authorized to access that item');
res.status(403);
res.json({
error: 'You are not authorized to access that item'
});
}
}
else {
// No item was found
console.error(`A checklist with id ${req.params.id} could not be found`);
res.status(404);
res.json({
error: `A checklist with id ${req.params.id} could not be found`
});
}
}
});
});
module.exports = router;
所以就像@OldGeezer 说的那样,问题最终还是出在了木偶师身上。由于我使用 puppeteer 中的 page.setContent() 函数将 html 内容直接加载到浏览器中,而不是为其提供 html 文件的路径,因此我图像的相对路径都不是或 css 有效。我最终解决它的方法是使用 puppeteer 中的 page.goto(path) 函数加载我在 public 文件夹中创建的空 html 文件,然后使用 page.setContent () 函数加载我想要的 html 。这允许浏览器在正确的目录中通过它们的相对路径加载外部文件。
server.js
views
checklist.pug
routes
checklist.js
public
empty.html
images
logo.png
stylesheets
checklist.css
pdfs
checklist.js
const express = require('express');
const aws = require('aws-sdk');
const { v4 } = require('uuid');
const puppeteer = require('puppeteer');
const pug = require('pug');
const dynamodb_config = require('../config/dynamodb/dynamo_config');
aws.config.update(dynamodb_config);
const { validateChecklist } = require('../middleware/validation');
const authenticateToken = require('../middleware/authenticateToken');
const router = express.Router();
const docClient = new aws.DynamoDB.DocumentClient();
const TABLE_NAME = 'Checklists';
// Generate html from checklist object, convert to pdf and send in response
router.get('/:id/pdf', authenticateToken, (req, res) => {
// Get the checklist and make sure the user owns it
const params = {
TableName: TABLE_NAME,
Key: {
id: req.params.id
}
}
docClient.get(params, async (err, data) => {
if (err) {
console.error(err);
res.status(500);
res.json({
error: err
});
}
else {
// Check that an item was found
if (typeof data.Item != 'undefined') {
// An item was found
// Check that the user who sent the request is the owner of the item
if (req.username == data.Item.createdBy) {
// CODE TO GENERATE CHECKLIST HERE
try {
const checklist = {
checklist: data.Item
}
// render html
const compiledFunction = pug.compileFile('views/checklist.pug');
const htmlContent = compiledFunction(checklist);
// convert html to pdf and save file
const browser = await puppeteer.launch();
const page = await browser.newPage();
// go to empty html file
await page.goto('file://' + __dirname + '/../public/empty.html');
await page.setContent(htmlContent, { waitUntil: 'networkidle2' });
await page.pdf({ path: `pdfs/${req.username}.pdf`, printBackground: true });
await browser.close();
res.status(200);
res.json({
message: 'success'
});
}
catch (err) {
console.error(err);
}
}
else {
// User does not own the item
console.error('You are not authorized to access that item');
res.status(403);
res.json({
error: 'You are not authorized to access that item'
});
}
}
else {
// No item was found
console.error(`A checklist with id ${req.params.id} could not be found`);
res.status(404);
res.json({
error: `A checklist with id ${req.params.id} could not be found`
});
}
}
});
});
module.exports = router;
我正在尝试将 css 文件和图像加载到我的哈巴狗文件中,但都没有加载。感觉就像我已经尝试了所有我能找到的方法却没有解决方案。我的 css 和图像在 public 文件夹中,用 express 设置为静态。我很感激我能得到的任何帮助。
文件夹结构如下:
server.js
views
checklist.pug
routes
checklist.js
public
images
logo.png
stylesheets
checklist.css
pdfs
server.js
require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const app = express();
const checklists = require('./routes/checklists');
const port = 3000;
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// View engine
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(express.static(path.join(__dirname, 'public')));
// Routes
app.use('/checklists', checklists);
app.listen(port, () => {
console.log(`Server started on port ${port}...`);
});
checklist.pug
html(lang='en')
head
link(href='stylesheets/checklist.css' rel='stylesheet')
link(rel='preconnect' href='https://fonts.googleapis.com')
link(rel='preconnect' href='https://fonts.gstatic.com' crossorigin)
link(href='https://fonts.googleapis.com/css2?family=Roboto&display=swap' rel='stylesheet')
body
div(class='checklist-title')
img(src='images/logo.png' alt='Logo...')
checklist.js
const express = require('express');
const aws = require('aws-sdk');
const { v4 } = require('uuid');
const puppeteer = require('puppeteer');
const pug = require('pug');
const dynamodb_config = require('../config/dynamodb/dynamo_config');
aws.config.update(dynamodb_config);
const { validateChecklist } = require('../middleware/validation');
const authenticateToken = require('../middleware/authenticateToken');
const router = express.Router();
const docClient = new aws.DynamoDB.DocumentClient();
const TABLE_NAME = 'Checklists';
// Generate html from checklist object, convert to pdf and send in response
router.get('/:id/pdf', authenticateToken, (req, res) => {
// Get the checklist and make sure the user owns it
const params = {
TableName: TABLE_NAME,
Key: {
id: req.params.id
}
}
docClient.get(params, async (err, data) => {
if (err) {
console.error(err);
res.status(500);
res.json({
error: err
});
}
else {
// Check that an item was found
if (typeof data.Item != 'undefined') {
// An item was found
// Check that the user who sent the request is the owner of the item
if (req.username == data.Item.createdBy) {
// CODE TO GENERATE CHECKLIST HERE
try {
const checklist = {
checklist: data.Item
}
// render html
const compiledFunction = pug.compileFile('views/checklist.pug');
const htmlContent = compiledFunction(checklist);
// convert html to pdf and save file
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setContent(htmlContent, { waitUntil: 'networkidle2' });
await page.pdf({ path: `pdfs/${req.username}.pdf`, printBackground: true });
await browser.close();
res.status(200);
res.json({
message: 'success'
});
}
catch (err) {
console.error(err);
}
}
else {
// User does not own the item
console.error('You are not authorized to access that item');
res.status(403);
res.json({
error: 'You are not authorized to access that item'
});
}
}
else {
// No item was found
console.error(`A checklist with id ${req.params.id} could not be found`);
res.status(404);
res.json({
error: `A checklist with id ${req.params.id} could not be found`
});
}
}
});
});
module.exports = router;
所以就像@OldGeezer 说的那样,问题最终还是出在了木偶师身上。由于我使用 puppeteer 中的 page.setContent() 函数将 html 内容直接加载到浏览器中,而不是为其提供 html 文件的路径,因此我图像的相对路径都不是或 css 有效。我最终解决它的方法是使用 puppeteer 中的 page.goto(path) 函数加载我在 public 文件夹中创建的空 html 文件,然后使用 page.setContent () 函数加载我想要的 html 。这允许浏览器在正确的目录中通过它们的相对路径加载外部文件。
server.js
views
checklist.pug
routes
checklist.js
public
empty.html
images
logo.png
stylesheets
checklist.css
pdfs
checklist.js
const express = require('express');
const aws = require('aws-sdk');
const { v4 } = require('uuid');
const puppeteer = require('puppeteer');
const pug = require('pug');
const dynamodb_config = require('../config/dynamodb/dynamo_config');
aws.config.update(dynamodb_config);
const { validateChecklist } = require('../middleware/validation');
const authenticateToken = require('../middleware/authenticateToken');
const router = express.Router();
const docClient = new aws.DynamoDB.DocumentClient();
const TABLE_NAME = 'Checklists';
// Generate html from checklist object, convert to pdf and send in response
router.get('/:id/pdf', authenticateToken, (req, res) => {
// Get the checklist and make sure the user owns it
const params = {
TableName: TABLE_NAME,
Key: {
id: req.params.id
}
}
docClient.get(params, async (err, data) => {
if (err) {
console.error(err);
res.status(500);
res.json({
error: err
});
}
else {
// Check that an item was found
if (typeof data.Item != 'undefined') {
// An item was found
// Check that the user who sent the request is the owner of the item
if (req.username == data.Item.createdBy) {
// CODE TO GENERATE CHECKLIST HERE
try {
const checklist = {
checklist: data.Item
}
// render html
const compiledFunction = pug.compileFile('views/checklist.pug');
const htmlContent = compiledFunction(checklist);
// convert html to pdf and save file
const browser = await puppeteer.launch();
const page = await browser.newPage();
// go to empty html file
await page.goto('file://' + __dirname + '/../public/empty.html');
await page.setContent(htmlContent, { waitUntil: 'networkidle2' });
await page.pdf({ path: `pdfs/${req.username}.pdf`, printBackground: true });
await browser.close();
res.status(200);
res.json({
message: 'success'
});
}
catch (err) {
console.error(err);
}
}
else {
// User does not own the item
console.error('You are not authorized to access that item');
res.status(403);
res.json({
error: 'You are not authorized to access that item'
});
}
}
else {
// No item was found
console.error(`A checklist with id ${req.params.id} could not be found`);
res.status(404);
res.json({
error: `A checklist with id ${req.params.id} could not be found`
});
}
}
});
});
module.exports = router;