You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:路径配置错误

  1. 视图路径错误:当前模块在public/js/下,__dirname指向public/js,path.join(__dirname, 'views')会解析为public/js/views,但实际视图目录在项目根目录的views下,导致找不到Pug文件。
  2. 静态资源路径错误:app.use('/public', express.static(path.join(__dirname, '/public')))会解析为public/js/public,和实际静态资源目录不符。
  3. 文件读取路径错误:./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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 12:10:38