Pull to refresh

Comments 17

Мне кажется или эта библиотека делает несколько не то же самое что и AMD/LMD?
да, она собирает кучу файлов в один, собственно делает то что делает описанная YAMD, если я правильно понял статью.
AMD/YAMD это менеджер модулей. А представленная штука просто производит конкатенацию.
Во первых там не просто конкатенация.
Во вторых YAMD то же производит конкатенацию.
Ну не просто конкатенацию. Как минимум, она следит за тем, чтобы каждый файл подключился в сборку только один раз. Ещё умеет «вырезать» файлы из сборки. Есть у вас файл common.js, в котором подключаются общие файлы, в bundle.js можно указать, что файлы из common.js подключать не надо.

Из совсем специфического есть условная сборка и возможность делить файлы на логические блоки.
нужно запустить python yamd.py path/to/library

Не хотите переписать сборщик под nodejs?
Я работаю с несколькими проектами одновременно каждый over 9000 SLoC.
Почему я бы не стал использовать yamd:

1) [critical] Отвутствие явного импорта
— Если модуль большой, то невозможно найти те модули, которые использует данный модуль
— Любой валидатор по умолчанию будет ругаться на использование незадекларированной в этом файле глобальной переменной в нашем случае math
— При удалении/перемещении модуля сложно найти концы
— Я бы устал искать откуда какая часть пришла

console.info(math.add(7,2));
console.info(math.multiply(7,2)); // откуда пришел math?

2) Завязка на файловую систему
— Проблемы с глубокой вложенностью модулей. Что если у нас /a/b/c/d.js?
— Файловая систему диктует имена экспорта у модулей

3) Модуль можно убить через expose
— expose ожидает синхронную декларацию, но разработчик может задекларировать такой модуль асинхронно
setTimeout(expose, 0, 42);

4) [critical] Все модули выполняются при старте, а не по требованию
5) Проблема с циклической зависимостью — это чаще всего ошибка проектирования
Функции нужно объединить в один модуль. Если никак, то можно обойтись и без tableLookup: использовать другой формат экспорта — в случае с CommonJS:
exports.steps = steps;

6) [critical] Модули не изолированы
// Этот модуль сломет все
files = null;

7) Модуль не может вернуть не объект
8) Лишний код если собираются 2+ библиотеки модулей

Посмотрите еще раз на существующие модульные системы. Я уверен, что они могут решить все ваши проблемы.

как вы разрабатываете сложные JS библиотеки
В двух проектах используется огромная общая библиотека модулей. Все модули — CоmmonJS. Проекты собирабтся на LMD. Сторонние модули транслируются в CommonJS при сборке.

PS Путь JavaScript модуля
Уважаемый автор LMD, у вас в профиле написано «С удовольствием отвечу на ваши вопросы про JavaScript», а мне нужен небольшой ликбез по организации JS-кода. Я уже отправлял вам вопрос (на azazel private), но не получил ответа. Могу ли я повторить пиьсмо на ящик, указанный на вашем сайте?
Мне кажется что по ссылке выше информации для начала достаточно. Так же там есть несколько интересных ссылок в конце статьи.
Это очень станно, но ваше письмо от 31 мая получено, отмечано как прочитанное, но я почему-то не ответил на него. Хотя регулярно отвечаю на все письма. Отметил его как не прочитанное и обязательно отвечу.
Спасибо за критику, это очень круто, особенно за #6 — классическая ошибка при метапрограммировании)

Если модуль большой, то невозможно найти те модули, которые использует данный модуль

Можно раскрыть мысль, почему это важно, я согласен, что очень часто нужна информация, где используется данный модуль, но не помню случая, когда задавался вопросом, кого он использует. Возможно, это просто вопрос привычки?

PS Вашу статью читал, она великолепна и всеобъемлюща, подробно описывает модули с технической точки зрения, но почему то после её прочтения у меня не сложилось понимания как нужно проектировать библиотеки используя современный модульный подход в JS. Именно поэтому мне и пришла в голову идея yamd — попытаться сделать систему похожей на java/c# (насколько это возможно), чтобы переиспользовать свой опыт этих языков.
Любое подключение внешней зависомости это своеобразный «контракт». И лучше, когда этот контракт явный.

use, import, require — это все способы декларации этого контракта. Кроме того, что этот statement/expression это директива интерпретатору/компилятору это еще и сигнал тому, кто читает этот код: этот модуль имеет внешние зависимости, можно использовать такие-то функции из такого-то списка, зависимости могут «намекнуть» на поведение модуля, исключают конфликты имен. Плюс мы имеем всякие плюшки вроде возможности статически анализировать модули для автокомплитов и прочих целей.

export, module.exports — это так же части этого контракта, но уже на поставку ресурсов.

import * from 'lib/dom-promise';
import * from 'lib/super-duper-abstract-module';

export class PromisedModule extends Module {
    fetch () {
        return new Promise(function () {
            // do stuff
        });
    }
}

Если удалить импорты, то появляется куча вопросов: Module и Promise — ты кто такой? Какой у него интерфейс? Где посмотреть код? Класс абстрактный? На какую спеку опирается интерфейс Promise?

не помню случая, когда задавался вопросом, кого он использует
Если вы используете постоянно одинаковые модули, то вы наверняка знаете их интерфейс. Но как быть тому кто будет читать ваш код? Вы должны позаботиться о том, чтобы ваш код был максимально доступным, иначе никто не будет его использовать. «контракт» — это часть доступности.

как нужно проектировать библиотеки используя современный модульный подход в JS
Эта статья должна ответить на ваши вопросы blog.izs.me/post/48281998870/unix-philosophy-and-node-js
Только ComonJS, только хардкор :)

Пишем на coffee, жмем clinch-ем и вуаля!
Получается что-то типа такого — демо и исходники.
Sign up to leave a comment.

Articles