Як ESLint реагує на ситуацію з видаленням пакетів з NPM

Після того, як відбулася ситуація з видаленням пакетів з NPM, яка торкнулася величезна кількість користувачів пакетів babel, jscs і багатьох інших (про це можна почитати тут: «A discussion about the breaking of the Internet»), багато розробників Open Source почали міркувати про майбутнє NPM та екосистеми JS в цілому.

Думки розділилися:

Ну а команди великих Open Source пакетів, на які звалилася величезна кількість тікетів в github, всерйоз задумалися про те, як не допустити такої ситуації в майбутньому. Особливо постраждали ті проекти, які часто використовуються в CI, так як саме користувачі CI в першу чергу помітили проблеми з відсутніми залежностями. Одним з таких проектів є ESLint, має близько 70 тисяч установок в день, більшість з яких припадає на CI-складання.

Рішення команди розробників ESLint було досить радикальним, але цілком робочий. Вони вирішили опублікувати пакет ESLint з усіма залежностями. Тобто завантажуючи архів ESLint, утиліта npm скачає і весь робочий node_modules для необхідної версії ESLint.

Докладніше про цю зміну: «ESLint v2.5.0 released».

Перша думка, яка прийшла мені в голову після того, як я дізнався цю новину, була про продуктивності. Що стане з установкою ESLint? Чи стане вона швидше або повільніше. Невеликий експеримент показав, що установка пакета з вбудованими залежностями займає більше часу. У разі ESLint — на 2 секунди (~25%):

npm install eslint@2.4.0 6.22 s user 2.68 s system 108% cpu 8.207 total
npm install eslint@2.5.0 7.70 s user 4.16 s system 109% cpu 10.864 total

Повний висновок
$ rm -Rf node_modules && time npm install eslint@2.4.0 && rm -Rf node_modules && time npm install eslint@2.5.0

eslint@2.4.0 node_modules/eslint
├── path-is-absolute@1.0.0
├── ignore@2.2.19
├── pluralize@1.2.1
├── path-is-inside@1.0.1
├── globals@8.18.0
├── estraverse@4.2.0
├── strip-json-comments@1.0.4
├── esutils@2.0.2
├── progress@1.1.8
├── text-table@0.2.0
├── user-home@2.0.0 (os-homedir@1.0.1)
├── is-resolvable@1.0.0 (tryit@1.0.2)
├── shelljs@0.5.3
├── json-stable-stringify@1.0.1 (jsonify@0.0.0)
├── resolve@1.1.7
├── debug@2.2.0 (ms@0.7.1)
├── doctrine@1.2.0 (esutils@1.1.6, isarray@1.0.0)
├── optionator@0.8.1 (fast-levenshtein@1.1.3, type-check@0.3.2, levn@0.3.0, wordwrap@1.0.0, deep-is@0.1.3, prelude-ls@1.1.2)
├── mkdirp@0.5.1 (minimist@0.0.8)
├── require-uncached@1.0.2 (resolve-from@1.0.1, caller-path@0.1.0)
├── chalk@1.1.1 (escape-string-regexp@1.0.5, supports-color@2.0.0, has-ansi@2.0.0, strip-ansi@3.0.1, ansi-styles@2.2.0)
├── concat-stream@1.5.1 (inherits@2.0.1, typedarray@0.0.6, readable-stream@2.0.6)
├── espree@3.1.3 (acorn@3.0.4, acorn-jsx@2.0.1)
├── is-my-json-valid@2.13.1 (jsonpointer@2.0.0, generate-function@2.0.0, xtend@4.0.1, generate-object-property@1.2.0)
├── inquirer@0.12.0 (ansi-regex@2.0.0, strip-ansi@3.0.1, ansi-escapes@1.3.0, figures@1.5.0, rx-lite@3.1.2, through@2.3.8, cli-width@2.1.0, run-async@0.1.0, cli-cursor@1.0.2, string-width@1.0.1, readline2@1.0.1)
├── table@3.7.8 (slice-ansi@0.0.4, tv4@1.2.7, xregexp@3.1.0, strip-ansi@3.0.1, string-width@1.0.1, bluebird@3.3.4)
├── js-yaml@3.5.5 (esprima@2.7.2, argparse@1.0.7)
├── glob@6.0.4 (inherits@2.0.1, inflight@1.0.4, once@1.3.3, minimatch@3.0.0)
├── file-entry-cache@1.2.4 (object-assign@4.0.1, flat-cache@1.0.10)
├── es6-map@0.1.3 (d@0.1.1, es6-symbol@3.0.2, event-emitter@0.3.4, es6-iterator@2.0.0, es6-set@0.1.4, es5-ext@0.10.11)
├── escope@3.6.0 (esrecurse@4.1.0, es6-weak-map@2.0.1)
└── lodash@4.6.1
npm install eslint@2.4.0 6.22 s user 2.68 s system 108% cpu 8.207 total

eslint@2.5.0 node_modules/eslint
npm install eslint@2.5.0 7.70 s user 4.16 s system 109% cpu 10.864 total

Для включення залежностей в архів використовується налаштування bundledDependencies для package.json (детальніше: «package.json bundledDependencies»). Налаштування ця нехитра: приймає масив імен пакетів, які будуть включені до публікованого архів.

Для автоматизації процесу публікації залежностей, в ESLint використовують невеликий пакет bundle-dependencies, який просто формує bundledDependencies з dependencies і записує в package.json.

По суті даний підхід дещо суперечить ідеям NPM, адже опція bundledDependencies була придумана для того, щоб включати в архів ті залежності, які не опубліковані в реєстрі NPM.

Ми в JSCS ще не вирішили, що ми будемо робити. Буде цікаво спостерігати за тим, як інші команди розробників Open Source проектів відреагують на ситуацію з NPM (і чи будуть реагувати). Подивимося, чи приживеться цей підхід чи знайдуться інші альтернативи.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.