2016-12-21 2 views
8

Так что мне нужно прочитать package.json перед установкой нового пакета через npm.Найдите файл package.json из сценария npm, который работает в preinstall

Зачем читать package.json в первую очередь?

Я использую npm для компонентов CSS, которые индивидуально версируются и могут иметь взаимные зависимости. (Нет Javascript не поставляется)

В поисках конфликта версий для связки зависимостей мне нужно определить, когда package A требует package [email protected] и package Bpackage [email protected] требует и борьбы с ним.

Npm (начиная с версии 3) рассматривает эти проблемы, вставляя конфликтующий модуль глубже внутри дерева. Теперь вы получаете обе версии одного и того же модуля. CSS имеет глобальное пространство имен, а mixin (в случае Sasss) переписывает друг друга и разбивает ваш CSS.

Этого плоский вопрос зависимости прекрасно изложен в НОМ блоги: http://blog.npmjs.org/post/101775448305/npm-and-front-end-packaging

Даже не принимая во внимание нашего конкретного случая использования он поражает меня как странно, что вы не имеете доступ к package.json в preinstall и postinstall сценариев. Кажется, они просто предназначены для этого случая.

То, что я пытался

Мои package.json пакета я устанавливаю выглядит следующим образом:

{ 
    "name": "testmodule", 
    "version": "0.3.6", 
    "description": "TODO", 
    "scripts": { 
     "preinstall": "npm i some-script && some-script", 
    }, 
    "author": "TODO", 
    "license": "MIT" 
} 

Внутри этого some-script пакет я бегу:

console.log(process.cwd()); 
console.log(__dirname); 

Я затем запустить:

~/path/to/folder $ npm i testmodule 

Это приведет:

$ npm i testmodule 

> [email protected] preinstall /path/to/folder/node_modules/.staging/testmodule-5cc9d333 
> some-script 

/path/to/folder/node_modules/.staging/test-module-5cc9d333 
/path/to/folder/node_modules/.staging/test-module-5cc9d333/node_modules/some-script 

Теперь я полностью понимаю, что я не могу получить доступ к корню, где npm i пробежалась, потому что мой сценарий был запущен подпроцесс НПМ и имеет совершенно другой корень.

Я тогда подумал npm root должен следить, где фактический корень был для меня и передал, что в качестве параметра моего сценария из внутри testmodule package.json:

{ 
     "name": "testmodule", 
     "version": "0.3.6", 
     "description": "TODO", 
     "scripts": { 
       "preinstall": "npm i some-script && some-script \"$(npm root)\"", 
     }, 
     "author": "TODO", 
     "license": "MIT" 
} 

К сожалению, это также по умолчанию обратно к постановка путь:

/path/to/folder/node_modules/.staging/testmodule-5cc9d333/node_modules 

Я подал an issue с реестром, но не держит мои надежды на них, чтобы добраться до этого времени. Также мой сценарий должен работать над более старыми установками npm.

В то же время я придумал что-то вроде, что внутри моего some-script:

let pgkPath = process.cwd().split('/node_modules/')[0]; 

Это вернет /path/to/folder/, который является правильным, но делает предположение, что никто не запускает npm i внутри папки кстати имени node_modules. .. Кажется взломанным.

Вопрос

Как я могу получить доступ путь к package.json внутри НПМ скрипт, который запускается с помощью Preinstall? Для меня это кажется чем-то не слишком возмутительным, чтобы просить?

+1

Это звучит очень похоже на [проблема XY] (http://meta.stackexchange.com/a/66378) - то, что вы пытаетесь сделать, что требует от вас, чтобы прочитать, что 'package.json' к быть с? И не «Я пытаюсь получить значение' ... 'out», * почему ты это делаешь? Потому что есть хорошая ставка, есть лучший способ сделать то, что вам нужно, о котором вы просто не знали. –

+0

Хорошая точка. Я добавлю это к вопросу. Спасибо за указание. – Dominik

+2

Чувак, что? Это буквально то, что NPM уже делает для вас, это одна из самых важных вещей, которые она делает, на самом деле, потому что, если вам нужно было это сделать вручную, это была бы неразрешимая проблема. В каком архаичном примере реального мира вы столкнулись с тем, что NPM не управляет параллельным управлением версиями правильно в дереве зависимостей? В приведенном примере NPM будет * не * перезаписывать одну версию другой, она увидит конфликт версий и обе версии будут глубже в дереве. –

ответ

2

Я не понимаю вашего потребительной случай полностью, но ответить на ваш конкретный вопрос о нахождении родителя package.json из Preinstall сценария:

$(cd .. && npm prefix) Pass в качестве аргумента в сценарий, а затем загрузить ./package.json.

npm prefix возвращает ближайший родительский каталог содержать package.json файл, который при запуске из каталога .., должен возвращать путь НОГО ПАКЕТА родителя.

{ 
     "name": "testmodule", 
     "version": "0.3.6", 
     "description": "TODO", 
     "scripts": { 
      "preinstall": "npm i some-script && some-script \"$(cd .. && npm prefix)\"", 
     }, 
     "author": "TODO", 
     "license": "MIT" 
} 
+0

очень приятно! благодаря! – Dominik