Como substituir versões de dependência aninhadas do NPM?

290

Eu gostaria de usar o grunt-contrib-jasminepacote NPM. Tem várias dependências. Parte do gráfico de dependência fica assim:

─┬ grunt-contrib-jasmine@0.4.1
  ├─┬ grunt-lib-phantomjs@0.2.0
   ├─┬ phantomjs@1.8.2-2

Infelizmente, há um erro nesta versão phantomjsque impede a instalação correta no Mac OS X. Isso foi corrigido na versão mais recente.

Como posso grunt-lib-phantomjsusar uma versão mais recente do phantomjs?

Algum contexto adicional:

georgebrock
fonte
Basta git cloneou garfo módulo necessário. Você também pode remover aninhado phantomjsmanualmente.
Aleksei Zabrodskii 04/04
3
grunt-contrib-jasmineestá em 0.5.1, que usa [email protected], que usa [email protected]:)
gustavohenke

Respostas:

238

Você pode usar a funcionalidade npm shrinkwrap , a fim de substituir qualquer dependência ou subdependência .

Acabei de fazer isso em um projeto difícil. Precisávamos de uma versão mais recente do connect, desde 2.7.3. estava causando problemas para nós. Então, eu criei um arquivo chamado npm-shrinkwrap.json:

{
  "dependencies": {
    "grunt-contrib-connect": {
      "version": "0.3.0",
      "from": "[email protected]",
      "dependencies": {
        "connect": {
          "version": "2.8.1",
          "from": "connect@~2.7.3"
        }
      }
    }
  }
}

O npm deve buscá-lo automaticamente durante a instalação do projeto.

(Consulte: https://nodejs.org/en/blog/npm/managing-node-js-dependencies-with-shrinkwrap/ )

tuxpiper
fonte
7
Quando faço isso, apenas a grunt-contrib-connectdependência e seus filhos estão instalados. Todas as minhas outras dependências no package.json não estão instaladas.
IDVB
5
Eu tive o mesmo problema que o @iDVB. Acabei editando o node_modulesdiretório para que o despejo completo de dependência do shrinkwrap fosse exatamente o que eu queria, não apenas substituindo. Mas ainda é um tipo de solução dolorosa.
Kobold
2
@Domi, este arquivo é criado executando o npm shrinkwrap, as entradas não são adicionadas à mão
glasspill
13
Infelizmente, como é mencionado nesse bug, com o npm4, a abordagem minimalista não funciona mais. (Ao excluir node_modules, a execução de uma instalação com um mínimo de retração parece deixar devDependenciesintacta, embora seja ignorada dependencies, mas a execução de outra instalação remove os itens não explícitos; portanto, por enquanto, é importante executar npm shrinkwrappara obter um arquivo completo, modificar a parte em questão e em seguida, executar npm installnovamente)
Brett Zamir
6
npm 6.4 irá apenas substituir o arquivo shrinkwrap e usar as dependências desatualizadas
ShadSterling
83

Para aqueles a partir de 2018 e além, usando o npm versão 5 ou posterior: edite seu package-lock.json: remova a biblioteca da "requires"seção e adicione-a em "dependências".

Por exemplo, você deseja que o deglobpacote use a globversão do pacote em 3.2.11vez da versão atual. Você abre package-lock.jsone vê:

"deglob": {
  "version": "2.1.0",
  "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.0.tgz",
  "integrity": "sha1-TUSr4W7zLHebSXK9FBqAMlApoUo=",
  "requires": {
    "find-root": "1.1.0",
    "glob": "7.1.2",
    "ignore": "3.3.5",
    "pkg-config": "1.1.1",
    "run-parallel": "1.1.6",
    "uniq": "1.0.1"
  }
},

Remova "glob": "7.1.2",de "requires", adicione "dependencies"com a versão apropriada:

"deglob": {
  "version": "2.1.0",
  "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.0.tgz",
  "integrity": "sha1-TUSr4W7zLHebSXK9FBqAMlApoUo=",
  "requires": {
    "find-root": "1.1.0",
    "ignore": "3.3.5",
    "pkg-config": "1.1.1",
    "run-parallel": "1.1.6",
    "uniq": "1.0.1"
  },
  "dependencies": {
    "glob": {
      "version": "3.2.11"
    }
  }
},

Agora remova sua node_modulespasta, execute npm installe ela adicionará partes ausentes à "dependencies"seção.

izogfif
fonte
4
Isso é legal, desde que npm installfuncione uma vez. No meu caso, as edições são necessárias, pois o dep aninhado está causando uma falha.
Ppsler #
59
este será removido quando você executar npm iem vez de editar o seu pacote-lock.json e adicionando a dependência criança "dependências" lá, adicionar a dependência da criança à sua package.json "dependências" seção
trickpatty
6
Eu criei uma biblioteca que faz exatamente isso para você automaticamente: github.com/rogeriochaves/npm-force-resolutions
Rogério Chaves
14
Funciona, mas se eu executar npm installnovamente, todas as alterações package-lock.jsonserão revertidas e a versão ruim do dep será recuperada.
2rs2ts
14
Eu corro npm cie isso não toca opackage-lock.json
sschoof
0

Eu tive um problema em que uma das dependências aninhadas tinha uma vulnerabilidade de auditoria npm, mas ainda queria manter a versão da dependência pai. a solução npm shrinkwrap não funcionou para mim, então o que fiz para substituir a versão de dependência aninhada:

  1. Remova a dependência aninhada na seção 'required' em package-lock.json
  2. Adicione a dependência atualizada em DevDependencies em package.json, para que os módulos que a exigem ainda possam acessá-la.
  3. npm i
Ethan Yang
fonte
-1

O NPM shrinkwrap oferece uma boa solução para esse problema. Ele nos permite substituir a versão de uma dependência específica de um submódulo específico.

Essencialmente, quando você executa a instalação do npm, o npm primeiro procura no diretório raiz para verificar se existe um arquivo npm-shrinkwrap.json. Caso isso aconteça, ele será usado primeiro para determinar as dependências do pacote e, em seguida, voltar ao processo normal de trabalho com os arquivos package.json.

Para criar um npm-shrinkwrap.json, tudo que você precisa fazer é

 npm shrinkwrap --dev

código:

{
  "dependencies": {
    "grunt-contrib-connect": {
      "version": "0.3.0",
      "from": "[email protected]",
      "dependencies": {
        "connect": {
          "version": "2.8.1",
          "from": "connect@~2.7.3"
        }
      }
    }
  }
}
Murtaza Hussain
fonte
3
Isso é diferente da resposta atualmente aceita? Essa resposta tem dois comentários anteriores, sugerindo que as versões mais recentes do npm requerem etapas manuais adicionais ou fazem coisas indesejáveis ​​com esta solução. Não é esse o caso?
Fabio Beltramini
-1

Encontrei uma solução que funcionou para mim.

Assim. Primeiro edite seu arquivo npm-shrinkwrap.json conforme recomendado em todas as outras soluções.

Então, (no Windows):

  • Clique com o botão direito do mouse no arquivo 'npm-shrinkwrap.json'
  • Propriedades
  • Em Atributos, selecione 'Somente leitura'. Isso impedirá que o npm modifique o arquivo mpn-shrinkwrap.json.

As outras soluções propostas são boas o suficiente se você estiver executando a operação 'npm install' apenas uma vez. Mas após a primeira 'instalação do npm', o arquivo 'npm-shrinkwrap.json' é modificado novamente como antes da sua modificação.

Shlomo Sfez
fonte
-1: isso exigiria que você desbloqueie o arquivo novamente toda vez que desejar fazer alterações. Nesses casos, você perderia as edições manuais no arquivo shrinkwrap de qualquer maneira. Além disso, qualquer pessoa que colabore no seu código também precisa habilitar esse hack.
thomaux 31/03