Этот урок описывает сборку mx из исходников 0e08e7af. Она сообщает mx 0.1.1; публикация соответствующего выпуска ещё не подтверждена. Наличие этой версии в выводе не доказывает, что публичный архив или npm-пакет содержит те же команды. Для установки сначала проверьте готовность выбранного пути.
Создайте приложение из кеша
mx new hello создаёт приложение на Hyperscript и Mercury UI из локального кеша модулей. Сначала заполните кеш при доступной сети. Если у вас уже настроена доверенная база контрольных сумм, сохраните эту настройку. Для первого заполнения без подписанной базы установщик использует такое разовое исключение:
MXNOSUMDB='registry.npmjs.org/fiberfx/*' mx mod cache
Это явный выбор доверия: для перечисленных пакетов Mercury контрольные суммы принимаются без подтверждения подписанной базой. Исключение действует только в этом запуске; не переносите его в постоянные настройки оболочки. Без настроенной базы или такого исключения первое заполнение может завершиться отказом. Просмотрите итог команды, включая отдельное сообщение о загрузке компилятора TypeScript.
Затем, в каталоге для нового проекта:
mx new hello
cd hello
mx verify
mx dev
Откройте адрес, который напечатал сервер, и проверьте работу страницы. После остановки сервера через Ctrl-C выполните mx build. Генератор создаёт package.json, mx.mod, mx.sum, index.html, src/main.tsx и установленное хранилище зависимостей. Версии Hyperscript и UI берутся из кеша; они не зашиты в команду. Эта сборка записывает mx 0.1.1 в новый mx.mod. Не меняйте версии в существующих mx.mod и mx.work только ради совпадения с номером исполняемого файла.
Непустой каталог и отсутствующие модули в кеше дают отказ с кодом 1. Не удаляйте существующий проект: выберите другое имя. Отсутствующее имя даёт код 2. Создание и работа без сети возможны после заполнения нужных кешей, а не на пустой машине.
Проверьте и исправьте исходники
Выполните эти команды из корня отдельного учебного проекта без зависимостей, описанного в следующем разделе:
mx lint
mx fmt --check
mx typecheck
mx quality
lint ищет проблемы в коде; fmt --check проверяет оформление без записи. typecheck проверяет проект TypeScript и требует конфигурацию, описанную ниже. quality выполняет все три проверки, даже если одна уже завершилась ошибкой, и возвращает наибольший код завершения.
Для исправлений используйте:
mx lint --fix
mx fmt
mx quality --fix
lint --fix применяет безопасные автоматические исправления, fmt перезаписывает оформление. quality --fix совмещает исправление lint и форматирование, затем оценивает результат. Исправление одной проблемы не означает успех всей проверки: например, лишнее переименование импорта устраняется автоматически, а debugger остаётся ошибкой. Просмотрите diff и повторите проверки; повторное форматирование уже оформленного файла не должно давать новых изменений.
| Код | Результат этих проверок |
|---|---|
| 0 | проверка выполнена, ошибок нет; предупреждения возможны |
| 1 | найдены ошибки или требуется форматирование |
| 2 | неверные аргументы |
| 3 | инструмент недоступен либо проверку не удалось выполнить |
Для автоматизации добавьте --json. Отдельная команда возвращает объект с полями stage, outcome, detail, files, fixed, findings; quality — массив результатов этапов. Оценивайте и JSON, и код процесса. Формат ответа относится к этим командам, а не ко всему mx.
Проверьте типы проекта
mx typecheck
mx typecheck --root /path/to/app
mx typecheck tsconfig.json
Без явного файла команда требует tsconfig.json в корне проекта.
Для первого упражнения создайте отдельный каталог course-typecheck с подкаталогом src и четырьмя файлами. Этот проект не использует зависимости:
package.json:
{"name":"course-typecheck","type":"module"}
mx.mod:
module registry.npmjs.org/course-typecheck
mx 0.1.1
tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"skipLibCheck": true
},
"include": ["src"]
}
src/main.ts:
export const value: number = 1;
Из каталога course-typecheck выполните mx typecheck. Ожидается код 0: один файл проверен, ошибок и предупреждений нет; файлы проекта не изменяются. skipLibCheck: true исключает проверку содержимого файлов деклараций, но не ошибки собственного кода.
Теперь добавьте src/type-error.ts:
export const x: number = "s";
Повторный mx typecheck должен вернуть код 1 с TS2322: строку нельзя присвоить переменной типа number. Удалите только созданный для упражнения src/type-error.ts и выполните mx quality --json; все три этапа должны пройти с кодом 0.
mx запускает отдельный нативный компилятор TypeScript 7.0.2. Его архив закреплён контрольной суммой SHA-256 и хранится в tools внутри кеша модулей. mx mod cache пытается загрузить его заранее и отдельно сообщает неудачу; заполненные пакеты ещё не доказывают наличие компилятора. При первой проверке загрузка также возможна, если сеть разрешена.
Импорты разрешает mx. Временная конфигурация ссылается на найденные модули и их декларации, не использует node_modules и автоматически подключаемые ambient-типы. Проверка не записывает конфигурацию или скомпилированные файлы в проект.
Если MXPROXY=off или цепочка содержит только file:// и off, загрузка компилятора запрещена. Уже закешированный компилятор можно использовать без сети; отсутствующий даёт unavailable и код 3. Архив с неверной контрольной суммой даёт could not run и код 3. Код 1 означает найденные ошибки типов, а не отсутствие компилятора. При коде 3 восстановите нужный инструмент или конфигурацию и повторите проверку.
Проверьте созданное приложение
Вернитесь в приложение hello из первого раздела. Создайте в его корне tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"jsx": "react-jsx",
"jsxImportSource": "@fiberfx/hyperscript",
"strict": true,
"skipLibCheck": true
},
"include": [
"src"
]
}
Выполните mx typecheck из каталога hello. Для использованных в упражнении пакетов Hyperscript и UI 4.1.1 ожидается typecheck: 0 errors, 0 warnings in 1 file и код 0. Строгая проверка остаётся включённой: mx находит декларации пакетов и подключает типы для обслуживаемых им импортов CSS.
Добавьте src/planted.ts со строкой export const x: number = "s"; и повторите проверку. Ожидается TS2322 в строке 1, столбце 14 и код 1. Удалите только этот учебный файл: следующая проверка снова должна завершиться с кодом 0. Проверка типов не меняет файлы проекта. Правила кеширования компилятора из предыдущего упражнения действуют и здесь.
mx test
usage: mx test [<path>...] [--root <dir>] [--timeout <seconds>] [--filter <words>]
mx test выполняет тесты модуля в браузере без графического интерфейса, который mx запускает сам, используя тот же граф, который обслуживает mx dev. Успех не предполагается: каждый результат должен вернуться в mx. Запуск без тестов, с потерянным отчётом или без завершения считается неуспешным.
- Какие файлы. Все файлы
*.test.*или*.spec.*с расширениемjs,mjs,jsx,ts,mtsилиtsxпод корнем. Вnode_modules,dist,targetиcoverageпоиск не выполняется. Если файлов нет:mx test: no tests under <root>, код 1. - Сначала импорты. Если импорты тестового файла не разрешаются, до запуска браузера фиксируется ошибка с его именем:
FAIL <url> > (its imports): <why>. Остальные файлы продолжают выполняться. - Браузер. Его задаёт
MX_BROWSER. Иначе mx ищет самый новый Chromium, затем headless shell Playwright вPLAYWRIGHT_BROWSERS_PATH,~/Library/Caches/ms-playwrightили~/.cache/ms-playwright. --timeoutограничивает весь запуск, по умолчанию 120 с:the run didn't end within <n> s. Отдельно определяется зависание страницы, которая молчит ещё 30 с после истечения тайм-аутов всех её тестов; оставшаяся часть этого файла не выполняется.--filter <words>оставляет тесты, у которых<file> > <name>содержит заданный текст, а остальные считает исключёнными фильтром.
| Код завершения | Значение |
|---|---|
| 0 | все тесты прошли |
| 1 | тест упал, ни один не выполнялся или запуск нарушен |
| 2 | ошибка использования |
| 3 | проверку выполнить не удалось: браузер не найден |
Код 3 никогда не означает успех. mx перечисляет проверенные пути, затем выводит Set MX_BROWSER to a Chromium binary..
Что импортирует тестовый файл
Тестовый файл импортирует из vitest, но карта импортов страницы направляет этот импорт в собственную среду выполнения mx, а не в Vitest. Она предоставляет:
describe,itиtest, а также хукиbeforeAll,afterAll,beforeEachиafterEach;expectс проверками;vi:vi.fn,vi.spyOn,vi.stubGlobal, подменённые таймеры (vi.useFakeTimers,vi.advanceTimersByTime,vi.runAllTimersи другие), а такжеvi.setSystemTime;expectTypeOfиassertType, которые ничего не проверяют во время выполнения: типы относятся к работе компилятора;- собственный
visitmx.
Как и в Vitest, тесту отводится 5 с, хуку — 10 с. vi.mock отсутствует: его вызов выбрасывает vi.mock is not in mx test: a module is mocked by import map, later (mercury.mx.13).
Управление страницей через visit
async function visit(url, { width = 0, height = 0, scale = 1, mobile = false, scheme = null, ready = null } = {})
visit открывает страницу HTTP-origin в браузере текущего запуска через протокол DevTools, эмулируя заданные размер области просмотра, масштаб, мобильный режим и scheme как prefers-color-scheme. Промис разрешается, когда CSS-селектор ready находит элемент, а без него — после загрузки страницы. Если width или height не заданы, сохраняются размеры браузера.
Возвращённый объект предоставляет два метода:
evaluate(fn, ...args)выполняетfnна этой странице и разрешает промис её JSON-значением либо отклоняет его выброшенной ошибкой;close()закрывает страницу.
Незакрытая страница visit закрывается после завершения её тестового файла. Если DevTools браузера перестаёт работать, mx завершает файл с указанием его имени.
Как читать результат запуска
Одна строка на тест, затем итоговые числа:
ok <file> > <name>
skip <file> > <name>
FAIL <file> > <name>: <message>
mx test: <passed> passed, <failed> failed, of <total>
По карте исходников компилятора стек ошибки привязывается к исходной строке. Запуск также проверяет собственную полноту:
- если число тестов со страниц не совпадает с числом полученных отчётов, выводится
the pages counted N tests and M reports arrivedи запуск считается неуспешным; - при
--filterвыводится число исключённых тестов; - если фильтр исключил все тесты, выводится
no tests ran: the filter matched none, код завершения — 1.
mx lsap
usage: mx lsap [--mcp] | mx lsap --version
mx lsap запускает языковой сервер Hyperscript, hyperscript-lsap, который должен быть установлен в том же каталоге, что и mx. Другой сервер mx не запускает и запасного варианта не использует. Он передаёт серверу собственный путь через HYPERSCRIPT_LSAP_MX, чтобы импорты разрешались этим экземпляром mx, затем завершается с кодом сервера. Во время сеанса stdout сервера несёт протокол, поэтому сам mx туда ничего не пишет.
Релиз, собранный release.sh, содержит сервер: hyperscript-lsap-<target> лежит рядом с mx-<target>. Его нужно установить в тот же каталог, что и mx, под именем hyperscript-lsap. Исключение — Windows. Сервер поддерживает только Unix, поэтому Windows-релиз содержит лишь mx, а mx lsap отказывает с The language server isn't built for Windows in this release.
--mcpпередаётся серверу без изменений.--versionвыводит версии mx и установленного сервера. Смотрите фактический вывод своей установки: версии двух программ не обязаны совпадать. Например, проверенный архив вывел:
mx 0.1.1
hyperscript-lsap 0.1.0
Если рядом с mx нет сервера, команда завершается с кодом 1 и выводит Error: mx lsap found no language server beside mx., проверенный путь и Put hyperscript-lsap in <dir>: a release of mx ships it there..
Сервер написан на Rust. Сейчас это перенесённый языковой сервер TypeScript, собранный по правилам Mercury; собственные сведения Mercury он пока не предоставляет.
mx run
У mx run две формы, выбор между которыми определяется каталогом.
Задача. Если в package.json текущего каталога есть скрипт с указанным именем, mx run <name> запускает его как кешируемую задачу. Ключ — sha256 от:
- скрипта, его аргументов и положения модуля в рабочей области;
NODE_ENVи имён, перечисленных вMXRUN_ENV;- sha256 каждого входного файла и используемых инструментов.
При попадании в кеш mx проверяет каждый сохранённый объект, восстанавливает выходные файлы и воспроизводит журнал: mx run: <member> <task>: hit <key>, restored N files. При промахе указывается первое различие: mx run: <member> <task>: miss (<why>). Сохраняются только результаты с кодом 0. Каталог задач задаёт MXRUN_CACHE; без него используется $XDG_CACHE_HOME/mx/run, а если эта переменная не задана — ~/.cache/mx/run. MXCACHE относится к модулям и не меняет каталог задач.
На macOS и Linux два кеша имеют разные назначения:
| Переменная | Назначение | Каталог по умолчанию |
|---|---|---|
MXCACHE |
модули и инструменты, включая TypeScript | ~/.mercury/modules |
MXRUN_CACHE |
результаты задач mx run |
$XDG_CACHE_HOME/mx/run, иначе ~/.cache/mx/run |
Флаги ставятся перед именем скрипта:
| Флаг | Действие |
|---|---|
--no-cache |
выполнить скрипт, не читая и не сохраняя запись кеша |
--verify |
при попадании в кеш повторно выполнить задачу и сверить выходные файлы с сохранёнными |
-r, --recursive |
выполнить задачу у каждого участника рабочей области |
--filter <member> |
выполнить задачу у названных по каталогу или имени пакета участников и у всех участников, от которых они зависят |
-j <n> |
число параллельных задач; по умолчанию число процессоров, но не более 4 |
-r и --filter требуют mx.work: mx run: -r and --filter need an mx.work at or above <dir>. Скрипт mx test никогда не кешируется, поскольку mx test читает всю рабочую область из исходников: mx run: <member> <task>: uncached: mx test reads the workspace from source.
Хост. Любое другое имя сохраняет форму для хоста: mx run <command> [args] собирает хост (MX3), затем передаёт управление команде, сохраняя её сигналы и код завершения. Пример из исходников mx — mx run mix phx.server.
Если имя не задано, mx run отвечает mx run: a command is required.
Подготовьте архив пакета
Из каталога библиотеки с корректным package.json и готовыми выходными файлами:
mx pack --npm
Можно передать несколько каталогов: mx pack --npm <package dir>…. Команда записывает архивы .tgz в .mx/pack/ каждого пакета. Состав определяется package.json, включая files и карту экспортов; одинаковые входные файлы дают одинаковые байты архива.
Затем mx проверяет архив на отдельном потребителе вне рабочих областей: устанавливает пакет и peer-зависимости, разрешает экспортируемые пути, импорты доступных через них модулей и импорты деклараций типов. Для зависимостей нужны подходящие прокси или заполненный кеш; проверка может обращаться к сети.
Отсутствующие, неверные или устаревшие результаты сборки дают отказ с кодом 1. Если в пакете есть скрипт build, выполните mx run build и повторите упаковку. Архив, не прошедший проверку потребителем, удаляется. Существование .tgz само по себе не заменяет успешный итог команды.
Если добавить в package.json скрипт "pack": "mx pack --npm", mx run pack может восстановить архив из кеша задачи, но проверка потребителем выполняется заново и при попадании в кеш. Упаковка ничего не публикует: отправка в реестр — отдельное действие.