Nodejs ExpressJS работает только для индекса

У меня есть маршруты в отдельной папке для expressjs. Настройка работает отлично для страницы "index", но не для каких-либо дополнительных маршрутов.

Это мой index.js внутри папки маршрутов.

 module.exports = function(db) {

    return {
        index: function(req, res, next) {
            res.send('index');
        }
    }
}

Это мой файл join.js внутри папки маршрутов.

 module.exports = function(db) {

    return {
        join: function(req, res, next) {
            res.send('join');
        }
    }
}

В моих app.js я определяю свои маршруты следующим образом:

          var routes = require('./routes')(db);
          app.get('/', routes.index);
          app.get('/join', routes.join);

Когда я перехожу к http://localhost:3000, но когда я перехожу к http://localhost:3000/join, я получаю Cannot GET /join

Если я определяю свой маршрут для соединения следующим образом:

 app.get('/join', function(req, res){
     res.send('join 2');
 });

Это работает.

Любая идея, что я делаю неправильно здесь?

Спасибо!

Ответ 1

У меня была аналогичная проблема, но потом вспомнил, что это все "просто javascript", и мне удалось запутать ответ.

Если вы хотите, чтобы ваши маршруты были определены в нескольких файлах (вместо того, чтобы набивать их все в один файл route/index.js), вы можете просто построить объект маршрутов хакерским способом (следующим образом):

var express = require('express')
  , routes = {
       index: require('./routes').index
     , events: require('./routes/events.js').events
  }
  , hbs = require('hbs');

ПРИМЕЧАНИЕ. Вам не нужны выражения express и hbs (первая и последняя строки) там, я просто помещаю их туда, чтобы дать вам небольшой контекст. Этот фрагмент кода появился непосредственно из моего файла app.js.

Обратите внимание на .index и .events, привязанные к вызовам функций require(). Это ключ. Мой файл events.js имеет только один экспорт (события):

exports.events = function(req, res){
  console.log('in events');
  res.render('events', { events: events, title: "EVENTS" });
  console.log('events done');
};

Так как функция require() по существу захватывает файл и требует (импортирует) любые не-частные vars (то есть те, которые прикреплены к специальному объекту exports), и предоставляет их файлу, содержащему вызов require() Я могу просто захватить определенную функцию, которую я требую от файла, который я включаю в вызов require(). Если бы у меня был множественный экспорт, определенный в требуемом файле, я предполагаю, что я мог бы схватить их так (не проверял):

routes = {
    index: require('./routes').index
  , events: require('./routes/events.js').events
  , favorites: require('./routes/events.js').favorites
  , upcoming: require('./routes/events.js').upcoming
}

Я подозреваю, что это даст кому-то с узлом nodeJS или MVC опыт аневризмы, если они прочитают ваш код (я уверен, что он будет включать тот же файл 3 раза, но я не совсем уверен). Может быть, лучше сделать:

routes = {
    index: require('./routes').index
  , events: require('./routes/events.js').events
  , favorites: require('./routes/favorites.js').favorites
  , upcoming: require('./routes/upcoming.js').upcoming
}

В противном случае, почему бы просто не засунуть их в индекс? Не совсем уверен, хотя, это только мой второй день работы с Node и любой из связанных с ним технологий...

Также, вероятно, вам поможет, если вы выполните инструкцию console.log сразу после объявлений var:

console.log(routes);

Ответ 2

Причина, по которой работает файл routes/index.js, а ваши маршруты /join.js не связаны с правилами загрузки модулей Node. Ознакомьтесь с документами для модулей/папок в качестве модулей

В нем говорится, что он попытается загрузить эти файлы в порядок. package.json, index.js, index.node.

Вы можете изменить загружаемый файл, создав файл package.json в каталоге. Установите для свойства main имя нового файла.

Пример того, как заставить маршруты работать так, как вы хотите, находится на другом вопросе.

Ответ 3

Я тестировал аналогичный сценарий, и он работал у меня.

Я предполагаю, что ошибка, вероятно, находится в файле routes.js. Вы, скорее всего, делаете:

routes.index = require('./index')(db);
routes.join = require('./join')(db);

Возможно, вы забыли вызвать метод для join, просто выполнив require(./join). Просто предположим.

Ответ 4

если вы просто скажете

var routes = require('./routes')

По умолчанию node начнет искать индексный файл (будь то index.js или index.node). Если вы хотите использовать свой файл соединения, вам нужно будет прямо сказать:

var join = require('./routes/join')

Теперь я думаю, что join.join должен работать.

Ответ 5

Имела подобную проблему.

Работает только мой маршрут "/". При попытке создать "/about" я получил бы ошибку 404.

Оказывается, когда я использовал экспресс-генератор, он писал:

app.use('/about', ...etc )

Вместо этого он должен был быть:

app.all('/about', ...etc )

i Знайте, что это не та же самая проблема, но это для тех страйков, которые оказываются здесь в поисках того же вопроса, что и проблема "только для индексации...".