如何使用 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;