Pull to refresh

Comments 28

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

UFO just landed and posted this here
UFO just landed and posted this here

А вы думаете, что если процесс ничего не «сервит» по HTTP, так у него какой-то другой алгоритм в require?:)

UFO just landed and posted this here

Даже если вас беспокоит именно этот момент, то существуют плагины, которые занимаются именно этим — запускают express или какой-то веб-сервер, всякий livereload/browsersync и т.п.:)

UFO just landed and posted this here
k12th все правильно сказал. Автор статьи на примере вэб-сервера показывает влияние места вызова require на время работы скрипта. Это не значит, что это относится только к вэб-серверам и любые другие примеры в комментариях к статье не релевантны.
UFO just landed and posted this here
Следуя Вашим аналогиям
Название статьи: «Вред кукурузы».
Содержимое статьи: «Я покормил свою ондатру кукурузой и ей поплохело. Кукуруза – плохо.».
k12th написал комментарий: «Кукуруза не всегда вредна. Страусам бывает полезно есть кукурузу.».
И тут приходите вы и говорите «При чем тут страусы? Автор кормил ондатру!».

Если статья называется «Вред кукурузы», то она, очевидно, про вред кукурузы.
UFO just landed and posted this here
Название статьи «Правильное использование require в node.js». Никаких ондатр тут нет и в помине. Ондатр автор упомянул лишь в качестве примера. Не понимаю, почему это вызывает у вас такие затруднения.
UFO just landed and posted this here

Статья больше в контексте сервера (как сказали комментарием ниже) — это наиболее частый сценарий при использовании node.js.


Если же использовать node.js, как, например, bash-скрипт, то тогда нет большой необходимости использовать require в начале файла, потому что при исполнении скрипта синхронные операции могут быть вполне ожидаемы и даже необходимы.
Но опять же — это ситуативно, и может запутать, если на вашем проекте серверный код написан с вынесением require вверх файла, а в node.js-скриптах уже по месту востребования. Лично я бы везде придерживался одного стиля — стараться использовать require/exports только вверху.

Такая большая разница в результатах кроется в работе функции require.


Мне кажется разница во времени здесь не столько из-за особенностей работы require, сколько из-за того, что во втором случае он будет вызван один раз для каждого модуля в момент инициализации скрипта, а в первом случае каждый раз при запросе GET /not_imported.
UFO just landed and posted this here
Справедливости ради, можно было упомянуть в минусах commonjs невозможность статического анализа и, как следствие, отсутствие tree-shaking и прочего.

Это вопрос не в рамках статьи, но если говорить, про tree-shaking, то CommonJS предполагает разбиение на маленькие модули, которые будут непосредственно импортироваться (тот же lodash). Например, хелперы будут выглядеть, как множество отдельный файлов с одним методом. Фактически tree-shaking делается "руками", поэтому нельзя сказать, что это минус. Скорее специфика CommonJS.

Ну почему, Вы в предисловии статьи приводите заключение в виде плюсов и минусов commonjs, причем явно упоминая о том, что в es6-модулях все импорты должны быть на верхнем уровне. Такое ограничение сделано как раз для возможности статического анализа, потому как require внутри функции или, например, по условию проанализировать не получится. Так что можно было бы в минусах упомянуть каких преимуществ лишается разработчик без статического анализа.

Про «множество отдельных файлов с одним методом» все же не соглашусь. Если в модуле 200 функций, нужно завести 200 файлов? Достаточно непрактично. Таким образом, учитывая, что, как я упомянул выше, require внутри функции не анализируется, то, так как по схожей причине невозможно понять, вызывается ли функция, ничего не остается, как включать и функцию и подключаемый внутри нее модуль. Хотя это легко избегается с помощью es6-модулей.
а если мне надо в начале загрузки пройтись по файлам и зареквайрить их в объект, потом этот объект експортировать.
Как это сделать с помощью import?

Если правильно понял, то что-то такое:


import a from 'a';
import b from 'b';
import c from 'c';

export default { a, b, c }

Больше вопрос возникает — где такое может реально понадобиться? На практике не помню, чтобы встречал подобное, поэтому интересно было бы посмотреть на пример использования.

Например есть файлики с роутами типо user.js, main.js, api.js… не знаю… любые роуты которые потом используються через middlewares
app.use('/users', userRouter);

для того чтобы не плодить кучу import a from 'a', import b from 'b'; на старте синхронно читаем файлики и помещяем все в один обьект чтоб потом зареквайрить 1 раз, а если понадобиться новый роут то просто создаеться файлик и описывается что нужно.
export const routes = {}
fs.readdirSync(__dirname)
.filter(file => /* фильтруем только что нужно */)
.forEach(file => {
// реквайрим
const r = require(file);
routes[path.parse(file).name.toLowerCase()] = r.router;
});


я не знаю, правильно это или нет, но с import в forEach так сделать нельзя.
Тут вопрос не в практичности, а в идеологии.
Используя динамический require, Вы рискуете нарваться на runtime-ошибку (отсутствие файла, поврежденный контент и т.д.), когда, подключая все нужные файлы заранее на верхнем уровне, можно было бы избежать ненужных проверок на существование, целостность и т.д.
Опять же, теряется статический анализ.

Есть пропозиция export * from 'something'. Когда будет в стандарте — неизвестно, но для бабеля плагин есть.

Это не совсем то, такой экспорт «пробрасывает» все экспорты из подключаемого модуля. Полезен, если нужно объединить несколько модулей в одном, например в index.js. Есть одно важное уточнение — экспорты пробрасываются только именные, default нет.
Sign up to leave a comment.

Articles