В глобальном масштабе местоположение node_modules для проекта

Если я пишу

var moment = require('moment');

в моем проекте Node тратит много времени на поиск в местах, которые фактически не содержат файл, как показывает этот вывод dtruss.

       PID/THRD  RELATIVE SYSCALL(args)                 = return
 7079/0x7cf313:   1244530 stat64("/Users/burke/code/api/api/models/node_modules/moment\0", 0x7FFF5FBFE5D8, 0x9)          = -1 Err#2
 7079/0x7cf313:   1244575 stat64("/Users/burke/code/api/api/models/node_modules/moment.js\0", 0x7FFF5FBFE578, 0x9)               = -1 Err#2
 7079/0x7cf313:   1244595 stat64("/Users/burke/code/api/api/models/node_modules/moment.json\0", 0x7FFF5FBFE578, 0x9)             = -1 Err#2
 7079/0x7cf313:   1244612 stat64("/Users/burke/code/api/api/models/node_modules/moment.node\0", 0x7FFF5FBFE578, 0x9)             = -1 Err#2
 7079/0x7cf313:   1244628 stat64("/Users/burke/code/api/api/models/node_modules/moment.coffee\0", 0x7FFF5FBFE578, 0x9)           = -1 Err#2
 7079/0x7cf313:   1244663 open("/Users/burke/code/api/api/models/node_modules/moment/package.json\0", 0x0, 0x1B6)                = -1 Err#2
 7079/0x7cf313:   1244694 stat64("/Users/burke/code/api/api/models/node_modules/moment/index.js\0", 0x7FFF5FBFE578, 0x1B6)               = -1 Err#2
 7079/0x7cf313:   1244713 stat64("/Users/burke/code/api/api/models/node_modules/moment/index.json\0", 0x7FFF5FBFE578, 0x1B6)             = -1 Err#2
 7079/0x7cf313:   1244729 stat64("/Users/burke/code/api/api/models/node_modules/moment/index.node\0", 0x7FFF5FBFE578, 0x1B6)             = -1 Err#2
 7079/0x7cf313:   1244745 stat64("/Users/burke/code/api/api/models/node_modules/moment/index.coffee\0", 0x7FFF5FBFE578, 0x1B6)           = -1 Err#2
 7079/0x7cf313:   1244767 stat64("/Users/burke/code/api/api/node_modules/moment\0", 0x7FFF5FBFE5D8, 0x1B6)               = -1 Err#2
 7079/0x7cf313:   1244788 stat64("/Users/burke/code/api/api/node_modules/moment.js\0", 0x7FFF5FBFE578, 0x1B6)            = -1 Err#2
 7079/0x7cf313:   1244805 stat64("/Users/burke/code/api/api/node_modules/moment.json\0", 0x7FFF5FBFE578, 0x1B6)          = -1 Err#2
 7079/0x7cf313:   1244821 stat64("/Users/burke/code/api/api/node_modules/moment.node\0", 0x7FFF5FBFE578, 0x1B6)          = -1 Err#2
 7079/0x7cf313:   1244837 stat64("/Users/burke/code/api/api/node_modules/moment.coffee\0", 0x7FFF5FBFE578, 0x1B6)                = -1 Err#2
 7079/0x7cf313:   1244862 open("/Users/burke/code/api/api/node_modules/moment/package.json\0", 0x0, 0x1B6)               = -1 Err#2
 7079/0x7cf313:   1244887 stat64("/Users/burke/code/api/api/node_modules/moment/index.js\0", 0x7FFF5FBFE578, 0x1B6)              = -1 Err#2
 7079/0x7cf313:   1244904 stat64("/Users/burke/code/api/api/node_modules/moment/index.json\0", 0x7FFF5FBFE578, 0x1B6)            = -1 Err#2
 7079/0x7cf313:   1244920 stat64("/Users/burke/code/api/api/node_modules/moment/index.node\0", 0x7FFF5FBFE578, 0x1B6)            = -1 Err#2
 7079/0x7cf313:   1244936 stat64("/Users/burke/code/api/api/node_modules/moment/index.coffee\0", 0x7FFF5FBFE578, 0x1B6)          = -1 Err#2
 7079/0x7cf313:   1244964 stat64("/Users/burke/code/api/node_modules/moment\0", 0x7FFF5FBFE5D8, 0x1B6)           = 0 0
 7079/0x7cf313:   1244990 stat64("/Users/burke/code/api/node_modules/moment.js\0", 0x7FFF5FBFE578, 0x1B6)                = -1 Err#2
 7079/0x7cf313:   1245015 stat64("/Users/burke/code/api/node_modules/moment.json\0", 0x7FFF5FBFE578, 0x1B6)              = -1 Err#2
 7079/0x7cf313:   1245038 stat64("/Users/burke/code/api/node_modules/moment.node\0", 0x7FFF5FBFE578, 0x1B6)              = -1 Err#2
 7079/0x7cf313:   1245488 madvise(0x1008AE000, 0x21000, 0x9)             = 0 0
 7079/0x7cf313:   1245503 stat64("/Users/burke/code/api/node_modules/moment.coffee\0", 0x7FFF5FBFE578, 0x9)              = -1 Err#2
 7079/0x7cf313:   1245612 open("/Users/burke/code/api/node_modules/moment/package.json\0", 0x0, 0x1B6)           = 11 0

Есть ли способ сделать Node не тратить столько времени на поиск в местах, где нет каталога node_modules? Например, я мог бы установить какую-то переменную окружения CHECK_HERE_FIRST=$HOME/code/api/node_modules, и если требование не для относительного пути, это будет первое место, которое проверит Node.

Я могу изменить все мои строки require для загрузки относительного импорта, но это кажется громоздким для большого проекта.

Ответ 1

Это поведение (создание слишком большого количества статов) было удалено (см. PR) из io.js v2.3.1, оно будет доступно в следующая главная версия node.js.

Ответ 2

Я не думаю, что есть элегантный способ сделать это без изменения require, чего следует избегать. Если вы беспокоитесь о проблемах с производительностью, это может помочь вам спать по ночам, зная, что это происходит только один раз из-за кэширования модулей.

Возможно, вы можете require все модули, которые вам нужны во время запуска вашего приложения.

Ответ 3

Согласно node docs, нет способа изменить это поведение

Если идентификатор модуля, переданный require(), не является родным модулем и не начинается с '/', '../' или './', то node начинается в родительском каталоге текущий модуль и добавляет /node_modules, и пытается загрузить модуль из этого местоположения.

Если он там не найден, он перемещается в родительский каталог и т.д., пока не будет достигнут корень файловой системы.

Следует отметить, что загруженные модули кэшируются, поэтому производительность не должна быть проблемой. Если вы используете Express, этот процесс загрузки выполняется только при запуске.