Express导出函数中app.get无法解析文件路径?技术求助
问题:Express导出函数中结合Pug渲染视图功能异常
我正在学习Node.js,查阅过同类问题但未找到适配自身场景的方案。尝试在导出函数中使用Express的app.get方法,结合Pug渲染视图,但功能异常,怀疑问题与文件路径相关。
文件结构
App server.js public js -current module.js music views index.pug
完整代码
module.exports.defaultAlbumReader = function () { var dirArray = new Array() var globalFileCount = 0 var pathArray = [] var jsmediatags = require('jsmediatags') const path = require('path') var express = require('express') var app = express() const fs = require('fs') const { error } = require('console') app.use('/public', express.static(path.join(__dirname, '/public'))) // app.use('/public/Music', express.static(path.join(__dirname, '/public'))); // app.use( express.static(path.join(__dirname, 'public'))); // app.use('/public', express.static('public')); app.set('views',path.join(__dirname,'views')); app.set('view engine', 'pug'); var filesToCount = fs.readdirSync( './public/Music/Pink_Floyd/WishYouWereHere/' ) globalFileCount = filesToCount.length console.log('number of files: ' + globalFileCount) var songsAlbumOrder = new Array(globalFileCount) var index = new Array(globalFileCount) var files = fs.readdirSync('./public/Music/Pink_Floyd/WishYouWereHere/') //sort the files in order of track number ascending function awaitableSortingEngine (file) { return new Promise(function (resolve, reject) { jsmediatags.read('./public/Music/Pink_Floyd/WishYouWereHere/' + file, { onSuccess: function (tag) { var tags = tag.tags var track = tags.track console.log(tags.track) if (track.length < 4) { var trackNum = track.slice(0, 1) } else if (track.length == 4) { var trackNum = track.slice(0, 1) } else { var trackNum = track.slice(0, 2) } var arrayIndex = trackNum - 1 songsAlbumOrder[arrayIndex] = file resolve(songsAlbumOrder) }, onError: function (error) { console.log(':(', error.type, error.info) reject('error: file was rejected') } }) }) } async function getArray (files) { for (const file of files) { var data = await awaitableSortingEngine(file) // console.log(data) } // setTimeout((data),1000) return data } async function displayData () { var data = await getArray(files) // console.log(promises.all(data)) // data.then((arrayResult)=>{console.log(arrayResult)}); // console.log(data) return data } var ordered = displayData() // console.log(orderedArray) ordered.then(result => sendToFront(result)) function sendToFront (fileArray) { console.log('moooo') for (const file of fileArray) { jsmediatags.read('./public/Music/Pink_Floyd/WishYouWereHere/' + file, { onSuccess: function (tag) { var tags = tag.tags console.log(tags.title) // console.log('made it') // var base64Url=Buffer.from(tags.picture.data).toString("base64"); // var base64Url=Buffer.from(base64String).toString("base64"); // var artInfo="data:"+tags.picture.format+";base64,"+base64Url; // console.log(`data:${tags.picture.format};base64,`); // var songRow=[tags.artist,tags.track,tags.album,tags.title,tags.year]; app.get('/', (req, res) => { res.render('index', { temp: tags.artist }) console.log('yayyyyyy') }) }, onError: function (error) { console.log(':(', error.type, error.info) } }) } } }
程序输出
number of files: 5 server started at localhost port:3000 3/5 data:image/jpeg;base64, 5/5 1/5 2/5 4/5 moooo Welcome to the Machine Shine On You Crazy Diamond (Parts I-V) Have A Cigar Wish You Were Here Shine On You Crazy Diamond (Parts VI-IX) done
核心问题代码
app.get('/', (req, res) => { res.render('index', { temp: tags.artist }) console.log('yayyyyyy') })
问题分析与修复方案
核心问题1:路由注册逻辑错误
你把app.get('/')放在了jsmediatags.read的成功回调里,并且循环执行了5次:
- 重复注册同一个路由,最终只有最后一次注册的路由生效(只会渲染最后一个文件的
artist) - 路由注册是异步完成的,服务器启动后用户提前访问会返回404
核心问题2:路径配置错误
- 视图路径错误:当前模块在
public/js/下,__dirname指向public/js,path.join(__dirname, 'views')会解析为public/js/views,但实际视图目录在项目根目录的views下,导致找不到Pug文件。 - 静态资源路径错误:
app.use('/public', express.static(path.join(__dirname, '/public')))会解析为public/js/public,和实际静态资源目录不符。 - 文件读取路径错误:
./public/Music/...是相对路径,相对的是Node进程启动目录,而非当前模块目录,容易出现路径找不到的问题。
修复步骤
1. 调整路由注册逻辑
先一次性读取并整理所有歌曲元数据,再统一注册路由,把所有数据传给Pug模板:
// 替换原sendToFront函数逻辑 function sendToFront(fileArray) { console.log('moooo') const songsData = [] const readPromises = fileArray.map(file => { return new Promise((resolve, reject) => { jsmediatags.read(path.join(__dirname, '../../public/Music/Pink_Floyd/WishYouWereHere/', file), { onSuccess: (tag) => { songsData.push(tag.tags) resolve() }, onError: (error) => { console.log(':(', error.type, error.info) resolve() } }) }) }) // 所有元数据读取完成后,注册一次路由 Promise.all(readPromises).then(() => { app.get('/', (req, res) => { res.render('index', { temp: songsData[0]?.artist || 'Unknown', songs: songsData // 可以把所有歌曲数据传给模板 }) console.log('yayyyyyy') }) }) }
2. 修正路径配置
建议把Express实例的配置(视图、静态资源)统一放在项目根目录的server.js中,模块只负责业务逻辑:
// server.js const express = require('express') const path = require('path') const app = express() const albumReader = require('./public/js/current module.js') // 统一配置视图和静态资源 app.set('views', path.join(__dirname, 'views')) app.set('view engine', 'pug') app.use('/public', express.static(path.join(__dirname, 'public'))) // 传入app实例给模块 albumReader.defaultAlbumReader(app) app.listen(3000, () => { console.log('server started at localhost port:3000') }) // 模块文件修改导出函数,接收app参数 module.exports.defaultAlbumReader = function (app) { // ... 其余逻辑不变,移除模块内部的app创建和配置代码 ... }
3. 使用绝对路径读取文件
所有文件操作改用绝对路径,避免相对路径的不确定性:
// 替换原fs.readdirSync的相对路径 const musicDir = path.join(__dirname, '../../public/Music/Pink_Floyd/WishYouWereHere/') var filesToCount = fs.readdirSync(musicDir) var files = fs.readdirSync(musicDir)
内容的提问来源于stack exchange,提问作者thinker123
相关产品推荐
相关产品推荐

