index.js 记录视图路径以确保部分可见
import express from 'express';
import bodyParser from 'body-parser';
import path from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';
import mustacheExpress from 'mustache-express';
import dotenv from 'dotenv';
import homeRouter from './home/router.js';
import jobsRouter from './jobs/router.js';
import errors from './errors/errors.js';
dotenv.config();
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const app = express();
// Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, '..', 'public')));
// Configure mustache
app.set('views', [
path.join(__dirname, 'home'), // Home templates
path.join(__dirname, 'jobs'), // Jobs templates
path.join(__dirname, 'errors'), // Error templates
path.join(__dirname, 'site/partial-views'),
]);
console.log('Views set to:', app.get('views'));
app.set('view engine', 'mustache');
app.engine('mustache', mustacheExpress());
// Routes
app.use('/', homeRouter);
app.use('/jobs', jobsRouter);
// Error handling middleware
app.use(errors.notFound);
app.use(errors.internalServerError);
app.use(errors.emailError);
export default app;
带有视图日志的终端
[nodemon] starting `node ./app/server.js`
Views set to: [
'C:\\Users\\Keegan\\source\\repos\\my-website\\app\\home',
'C:\\Users\\Keegan\\source\\repos\\my-website\\app\\jobs',
'C:\\Users\\Keegan\\source\\repos\\my-website\\app\\errors',
'C:\\Users\\Keegan\\source\\repos\\my-website\\app\\site\\partial-views'
]
Server running on port 3000
Connected to MySQL database
终端出现错误
node:internal/errors:540
throw error;
^
TypeError [ERR_INVALID_ARG_TYPE]: The "paths[0]" argument must be of type string. Received an instance of Array
at Object.resolve (node:path:198:9)
at C:\Users\Keegan\source\repos\my-website\node_modules\mustache-express\mustache-express.js:99:24
at C:\Users\Keegan\source\repos\my-website\node_modules\async\dist\async.js:247:13
at eachOfArrayLike (C:\Users\Keegan\source\repos\my-website\node_modules\async\dist\async.js:507:13)
at eachOf (C:\Users\Keegan\source\repos\my-website\node_modules\async\dist\async.js:627:16)
at awaitable (C:\Users\Keegan\source\repos\my-website\node_modules\async\dist\async.js:212:32)
at _asyncMap (C:\Users\Keegan\source\repos\my-website\node_modules\async\dist\async.js:245:16)
at Object.map (C:\Users\Keegan\source\repos\my-website\node_modules\async\dist\async.js:750:16)
at Object.awaitable [as map] (C:\Users\Keegan\source\repos\my-website\node_modules\async\dist\async.js:212:32)
at loadAllPartials (C:\Users\Keegan\source\repos\my-website\node_modules\mustache-express\mustache-express.js:94:8) {
code: 'ERR_INVALID_ARG_TYPE'
}
Node.js v22.12.0
[nodemon] app crashed - waiting for file changes before starting...
目录
my-website/
----app/
--------index.js
--------server.js
--------db.js
--------config.js
--------jobs/router.js, jobs.mustache
--------home/router.js, home.mustache
--------errors/errors.js, erorrs.mustache
--------site/partial-views/head.mustache
----public/
家.胡子
<html lang="en" data-bs-theme="auto">
{{> head}}
</html>
home/router.js
import express from 'express';
import connection from '../db.js';
const router = express.Router();
router.get('/', (req, res, next) => {
const query = 'SELECT id, title, location, salary, posted FROM jobs';
connection.query(query, (err, results) => {
if (err) {
return next(err);
}
res.render('home', { jobs: results });
});
});
export default router;
home.mustache 是目前唯一尝试使用部分的模板。删除 home.mustache 中的第 1 行 {{> head}} 并手动将 head.mustache 的内容复制到其位置即可消除错误,并且网站可以正确呈现“/”根端点。
感谢您的时间和反馈!
我找到了一个解决方案,但它并没有完全解决为什么问题代码不被接受的问题。我当前的解决方案是将部分视图路径直接添加到 Mustache Express 构造函数中,如下所示。
const mustache = mustacheExpress(path.join(__dirname, 'site', 'partial-views'));
app.engine('mustache', mustache);
这确保了express知道这个目录。 然后就可以删除了
path.join(__dirname, '站点/部分视图'),
app.set('views', [
path.join(__dirname, 'home'), // Home templates
path.join(__dirname, 'jobs'), // Jobs templates
path.join(__dirname, 'errors'), // Error templates
path.join(__dirname, 'site/partial-views'),
]);
这是可行的,但对于为什么原始代码不起作用仍然存在困惑,并且不确定这是否是优雅/预期的解决方案。