При использовании NPM (или пряжи) для управления зависимостями JavaScript для проекта рекомендуется устанавливать зависимости локально в проекте, чтобы несколько проектов NPM в системе не имели конфликтующих зависимостей или версий зависимостей. Однако лучше отказаться от этого шаблона и использовать глобально установленную версию зависимости, если верны следующие случаи:
- Зависимость огромна или установка занимает чрезвычайно много времени.
- Это единственный проект NPM (или один из очень немногих тесно связанных проектов NPM) в системе (например, работающий внутри контейнера докеров).
Один из случаев, когда выполняются оба этих критерия, - это создание контейнера докеров для проекта BuckleScript (или ReasonML).
BuckleScript - это прежде всего компилятор, который компилирует код OCaml или ReasonML в JavaScript. Следовательно, может показаться, что bs-platform (зависимость NPM BuckleScript) должна требоваться только как devDependency и использоваться в процессе сборки. Однако bs-platform также содержит некоторый код, который необходимо включить в проект во время выполнения. Следовательно, bs-platform должна быть включена в проект либо как зависимость, либо как peerDependency.
Самый простой вариант включить bs-платформу в проект - это добавить ее в поле dependencies файла package.json и разрешить NPM (или yarn) установить ее локально в каталог node_modules проекта. Этот метод отлично работает на машине разработки, где зависимости npm кэшированы и должны быть установлены снова только в том случае, если пакет удален из локального каталога node_modules. Однако при установке зависимостей npm в контейнер докеров любое изменение файла package.json приведет к полной установке всех пакетов npm. Обычно это не проблема для небольших зависимостей npm, установка которых занимает менее нескольких секунд, но bs-platform устанавливает и компилирует компилятор OCaml с нуля. На моей быстрой машине этот процесс занимает более 6 минут. На моих более медленных машинах этот процесс занимает почти полчаса. Ожидание сборки докер-контейнера более 6 минут всякий раз, когда какие-либо изменения в файле package.json недопустимы. Особенно во время разработки, когда package.json меняется почти все время.
Итак, теперь ситуация такова: у нас есть зависимость, установка которой занимает чрезвычайно много времени, И этот проект является единственным проектом NPM, работающим в системе (то есть контейнером докеров). Похоже, у нас есть идеальный кандидат для того, чтобы отказаться от передовой практики установки зависимости локально и вместо этого установить зависимость глобально заранее. Это позволит нам установить bs-платформу один раз и кэшировать ее как слой докеров. Затем любые изменения в package.json произойдут на следующем уровне докеров без необходимости переустановки bs-platform.
Затем, поскольку нам нужно разрешить глобально установленную зависимость во время выполнения, мы включаем ее как peerDependency в package.json. Это проинформирует наш инструмент сборки (Webpack 4), что для проекта требуется bs-платформа, НО она уже должна быть установлена в системе.
Наконец, мы настраиваем webpack для разрешения bs-platform как глобально установленной зависимости вместо локально установленной зависимости, добавляя следующие строки в webpack.config.js:
resolve: {
alias: {
'bs-platform': path.resolve(
execSync('npm root -g').toString().trim(),
'bs-platform'
)
}
},
Когда мы будем готовы построить проект ReasonML, мы запустим:
bsb -make-world webpack --mode production
который выведет наш окончательный файл JavaScript для отправки в браузер клиента.
Первоначально опубликовано на сайте craigc0de.blogspot.com 25 сентября 2018 г.