como especificar módulos locais como dependências do pacote npm

269

Eu tenho um aplicativo que possui o conjunto usual de dependências em módulos de terceiros (por exemplo, 'express') especificado no arquivo package.json em dependências. Por exemplo

"express"     : "3.1.1"

Gostaria de estruturar meu próprio código de forma modular e ter um conjunto de módulos locais (ou seja, no sistema de arquivos em que estou atualmente) instalados pelo pacote.json. Eu sei que posso instalar um módulo local executando:

npm install path/to/mymodule

No entanto, não sei como fazer isso acontecer através da estrutura de dependências package.json. Usar a --saveopção neste comando é simplesmente colocar "mymodule": "0.0.0"no meu package.json (não faz referência à localização do caminho do arquivo). Se eu remover a versão instalada do node_modules e tentar reinstalar o package.json, ele falhará (porque procura "mymodule" no registro central e não parece localmente).

Tenho certeza de que é uma maneira de dizer ao "dependencies": {} estrutura que quero que ela seja instalada a partir de um caminho do sistema de arquivos, mas não sei como.

Alguém mais teve este problema? Obrigado.

Sam Adams
fonte
1
Uma pergunta muito boa. É triste perceber que não existe um recurso equivalente package.jsonao que temos em Gemfiles.
Jarl
3
possível duplicata de dependência local em package.json
Kelly

Respostas:

408

npm install agora suporta isso

npm install --save ../path/to/mymodule

Para que isso funcione, mymoduledeve ser configurado como um módulo próprio package.json. Consulte Criando módulos NodeJS .

A partir do npm 2.0, as dependências locais são suportadas nativamente. Veja a resposta de danilopopeye a uma pergunta semelhante . Copiei a resposta dele aqui, já que esta pergunta é muito alta nos resultados de pesquisa na web.

Esse recurso foi implementado na versão 2.0.0 do npm. Por exemplo:

{
  "name": "baz",
  "dependencies": {
    "bar": "file:../foo/bar"
  }
}

Qualquer um dos seguintes caminhos também é válido:

../foo/bar
~/foo/bar
./foo/bar
/foo/bar

sincronizando atualizações

Desde as npm installcópias mymodulepara node_modules, alterações nomymodule fonte 's não será automaticamente visto pelo projeto dependente.

Há duas maneiras de atualizar o projeto dependente com

  • Atualize a versão mymodulee usenpm update : Como você pode ver acima, a package.jsonentrada "dependências" não inclui um especificador de versão como você veria para dependências normais. Em vez disso, para dependências locais, npm updateapenas tenta garantir que a versão mais recente esteja instalada, conforme determinado por mymodule's package.json. Veja a resposta de chriskelly para esse problema específico .

  • Reinstale usando npm install. Isso instalará o que estiver no mymodulecaminho de origem do mesmo, mesmo se for mais antigo ou se houver uma ramificação alternativa, o que for.

Randy the Dev
fonte
2
Isso funcionou para mim. (Acabei de fazer um caminho relativo local como"mymodule":"file:mymoduledir"
Don Rhummy 14/11/16
72
npm install --save ../my-local-repo
Ivan Rave
15
E como usá-lo no projeto? Estou tentando chamá-lo assim import { HelloWorld } from "my-test-lib";, mas recebo o erro "Não consigo encontrar o módulo". Por favor, dê uma olhada em stackoverflow.com/questions/46818083/…
Vitalii Vasylenko 18/17
6
@LucioMollinedo, você pode compartilhar a sintaxe de como importou o módulo local? Tal como acontece com Vitallii, estou recebendo o erro "Não é possível refinar o módulo" comimport { HelloWorld } from "my-test-lib";
Stan James
7
Isso não funciona da mesma como referência a um pacote como dependências não será instalado para o projeto
Vidro canhão
44

Consulte: Dependência local em package.json

Parece que a resposta é npm link: https://docs.npmjs.com/cli/link

jasoncrawford
fonte
5
realmente ligação npm só irá criar os links simbólicos, e não irá modificar o package.json para adicionar a dependência local
Sebastien H.
1
Mas se não for, symlinkcomo o projeto pai saberá reconstruir depois que a dependência terminar de construir?
Jamie Hutber
11

Não consegui encontrar uma maneira elegante no final, então criei um diretório chamado local_modulese adicionei esse bashscript ao package.json em scripts-> pré-instalação

#!/bin/sh
for i in $(find ./local_modules -type d -maxdepth 1) ; do
    packageJson="${i}/package.json"
    if [ -f "${packageJson}" ]; then
        echo "installing ${i}..."
        npm install "${i}"
    fi
done
Sam Adams
fonte
5

Depois de lutar muito com o npm link comando (solução sugerida para o desenvolvimento de módulos locais sem publicá-los em um registro ou manter uma cópia separada na pasta node_modules), criei um pequeno módulo npm para ajudar com esse problema.

A correção requer duas etapas fáceis .

Primeiro:

npm install lib-manager --save-dev

Segundo, adicione isso ao seu package.json:

{  
  "name": "yourModuleName",  
  // ...
  "scripts": {
    "postinstall": "./node_modules/.bin/local-link"
  }
}

Mais detalhes em https://www.npmjs.com/package/lib-manager . Espero que ajude alguém.

Anurag Dutta
fonte
0

Se for aceitável simplesmente publicar seus módulos pré-instalados em node_modules junto com outros arquivos, você pode fazer o seguinte:

// ./node_modules/foo/package.json
{ 
  "name":"foo",
  "version":"0.0.1",
  "main":"index.js"
}

// ./package.json
...
"dependencies": {
  "foo":"0.0.1",
  "bar":"*"
}

// ./app.js
var foo = require('foo');

Você também pode armazenar seu módulo no git e informar ao seu package.json pai para instalar a dependência do git: https://npmjs.org/doc/json.html#Git-URLs-as-Dependencies

Platão
fonte
5
Infelizmente, isso envolveria node_modules com meus módulos locais e módulos de terceiros / contribuídos instalados a partir do registro (por exemplo, conectar) no mesmo diretório. Além de ser confuso do ponto de vista do Git / VCS (ou seja, teria que ignorar tudo em node_modules, exceto aqueles que eu criei), também é uma prática ruim (aqueles que escrevi e não publiquei devem ser mantidos separados dos outros que foram escritos e publicados )
Sam Adams
Quando adiciono um módulo local, faça alterações, que não são vistas pelo meu aplicativo principal. Por que esse é o caso?
Mark Tyers