Gostaria de exigir meus arquivos sempre pela raiz do meu projeto e não em relação ao módulo atual.
Por exemplo, se você consultar a https://github.com/visionmedia/express/blob/2820f2227de0229c5d7f28009aa432f9f3a7b5f9/examples/downloads/app.js linha 6, verá
express = require('../../')
Isso é muito ruim na IMO. Imagine que eu gostaria de colocar todos os meus exemplos mais próximos da raiz apenas em um nível. Isso seria impossível, porque eu teria que atualizar mais de 30 exemplos e muitas vezes dentro de cada exemplo. Para isso:
express = require('../')
Minha solução seria ter um caso especial para raiz: se uma string começa com $, então é relativa à pasta raiz do projeto.
Qualquer ajuda é apreciada, obrigado
Atualização 2
Agora estou usando o require.js, que permite escrever de uma maneira e funciona tanto no cliente quanto no servidor. O Require.js também permite criar caminhos personalizados.
Atualização 3
Agora, mudei para o webpack + gulp e utilizei o Enhanced-require para manipular módulos no lado do servidor. Veja aqui a justificativa: http://hackhat.com/p/110/module-loader-webpack-vs-requirejs-vs-browserify/
Respostas:
E sobre:
Ele requer o arquivo como se fosse exigido no arquivo js principal, portanto funciona muito bem desde que o arquivo js principal esteja na raiz do seu projeto ... e isso é algo que eu aprecio.
fonte
Há uma seção realmente interessante no Manual do Browserify :
fonte
node_modules
pasta é que ela torna mais difícil a arma nuclear (rm -rf node_modules
) pastagit clean
sintaxe, sempre é possívelrm -rf node_modules && git checkout node_modules
- certifique-se de quegit stash
haja alguma alteração nosnode_modules
subdiretórios.Eu gosto de criar uma nova
node_modules
pasta para código compartilhado, depois deixar o nó e exigir fazer o que faz melhor.por exemplo:
Por exemplo, se você estiver dentro,
car/index.js
você poderequire('helper')
e o nó o encontrará!Como o node_modules funciona
O nó possui um algoritmo inteligente para resolver módulos que é único entre plataformas rivais.
Se você
require('./foo.js')
partir/beep/boop/bar.js
, o nó irá procurar./foo.js
no/beep/boop/foo.js
. Caminhos que começam com./
ou../
são sempre locais para o arquivo que chamarequire()
.Se, no entanto, você precisar de um nome não relativo, como
require('xyz')
from/beep/boop/foo.js
, o nó pesquisará esses caminhos em ordem, parando na primeira correspondência e gerando um erro se nada for encontrado:Para cada
xyz
diretório existente, o nó procurará primeiro umxyz/package.json
para ver se"main"
existe um campo. O"main"
campo define qual arquivo deve ser carregado se você forrequire()
o caminho do diretório.Por exemplo, se
/beep/node_modules/xyz
é a primeira correspondência e/beep/node_modules/xyz/package.json
possui:as exportações de
/beep/node_modules/xyz/lib/abc.js
serão retornadas porrequire('xyz')
.Se não houver
package.json
ou nenhum"main"
campo,index.js
será assumido:fonte
A grande imagem
Parece "muito ruim", mas reserve um tempo. É, de fato, muito bom. Os explícitos
require()
oferecem uma total transparência e facilidade de entendimento, como uma lufada de ar fresco durante o ciclo de vida do projeto.Pense da seguinte maneira: você está lendo um exemplo, mergulhando os pés no Node.js e decidiu que é "uma IMO muito ruim". Vocês são os líderes da comunidade Node.js., pessoas que registraram mais horas escrevendo e mantendo aplicativos Node.js. Qual é a chance do autor cometer um erro tão novo? (E eu concordo, do meu passado em Ruby e Python, parece a princípio um desastre.)
Há muito hype e contra-hype ao redor do Node.js. Porém, quando a poeira baixar, reconheceremos que módulos explícitos e pacotes "locais em primeiro lugar" foram os principais fatores de adoção.
O caso comum
Obviamente,
node_modules
no diretório atual, o pai, o avô, o bisavô etc. são pesquisados. Portanto, os pacotes que você instalou já funcionam dessa maneira. Geralmente você poderequire("express")
de qualquer lugar do seu projeto e funciona bem.Se você se encontra carregando arquivos comuns da raiz do seu projeto (talvez porque sejam funções utilitárias comuns), essa é uma grande pista de que é hora de criar um pacote. Os pacotes são muito simples: mova seus arquivos para dentro
node_modules/
e coloque umpackage.json
lá. Voila! Tudo nesse espaço de nome é acessível em todo o seu projeto. Pacotes são a maneira correta de colocar seu código em um espaço para nome global.Outras soluções alternativas
Pessoalmente, não uso essas técnicas, mas elas respondem à sua pergunta e, é claro, você conhece sua própria situação melhor do que eu.
Você pode definir
$NODE_PATH
a raiz do seu projeto. Esse diretório será pesquisado quando vocêrequire()
.Em seguida, você pode comprometer e exigir um arquivo local comum de todos os seus exemplos. Esse arquivo comum simplesmente reexporta o arquivo true no diretório dos avós.
examples / downloads / app.js (e muitos outros similares)
exemplos / downloads / express.js
Agora, quando você realoca esses arquivos, o pior caso é consertar o módulo de um calço .
fonte
Dê uma olhada no node-rfr .
É simples assim:
fonte
Se você estiver usando fios em vez de npm, poderá usar áreas de trabalho .
Digamos que tenho uma pasta
services
que desejo exigir mais facilmente:Para criar um espaço de trabalho do Yarn, crie um
package.json
arquivo dentro deservices folder
:No seu package.json principal, adicione:
Execute a
yarn install
partir da raiz do projeto.Em qualquer lugar do seu código, você pode:
em vez de algo como:
fonte
IMHO, a maneira mais fácil é definir sua própria função como parte do
GLOBAL
objeto. CrieprojRequire.js
na raiz do seu projeto com o seguinte conteúdo:No seu arquivo principal, antes de
require
qualquer módulo específico do projeto:Depois disso, funciona para mim:
@ Totty, eu vim com outra solução, que poderia funcionar no caso que você descreveu nos comentários. A descrição será
tl;dr
, então é melhor eu mostrar uma imagem com a estrutura do meu projeto de teste .fonte
prj/some
deprj/other
(apenas testadarequire('prj/some'
). Todos os módulos comuns do seu aplicativo podem ir até lá (por exemplo, camada de banco de dados). Não fará diferença onde você está, digamoslib
. Tente e veja se é adequado.Eu uso
process.cwd()
em meus projetos. Por exemplo:Pode valer a pena notar que isso resultará em
require
um caminho absoluto, embora eu ainda precise encontrar problemas com isso.fonte
Há uma boa discussão sobre esse assunto aqui .
Encontrei o mesmo problema de arquitetura: querer uma maneira de fornecer ao meu aplicativo mais organização e espaços de nomes internos, sem:
No final, decidi organizar meu código usando convenções de nomenclatura de arquivos em vez de diretórios. Uma estrutura seria algo como:
Então no código:
ou apenas
e dependências externas estão disponíveis no node_modules como de costume:
Dessa forma, todo o código do aplicativo é hierarquicamente organizado em módulos e disponível para todos os outros códigos relativos à raiz do aplicativo.
A principal desvantagem é que, em um navegador de arquivos, você não pode expandir / recolher a árvore como se ela estivesse realmente organizada em diretórios. Mas eu gosto que seja muito explícito sobre a origem de todo o código e não use nenhuma 'mágica'.
fonte
../x/x
que já é legível.Supondo que a raiz do seu projeto seja o diretório de trabalho atual, isso deve funcionar:
fonte
config = require('./config.js');
também é válido.Eu tentei muitas dessas soluções. Acabei adicionando isso ao topo do meu arquivo principal (por exemplo, index.js):
Isso adiciona a raiz do projeto ao NODE_PATH quando o script é carregado. Isso me permite exigir qualquer arquivo no meu projeto, referenciando seu caminho relativo a partir da raiz do projeto, como
var User = require('models/user')
. Esta solução deve funcionar desde que você esteja executando um script principal na raiz do projeto antes de executar qualquer outra coisa no seu projeto.fonte
Algumas das respostas estão dizendo que a melhor maneira é adicionar o código ao node_module como um pacote, eu concordo e provavelmente é a melhor maneira de perder a
../../../
necessidade, mas nenhuma delas realmente fornece uma maneira de fazê-lo.da versão,
2.0.0
você pode instalar um pacote a partir de arquivos locais, o que significa que você pode criar uma pasta na raiz com todos os pacotes que desejar,portanto, em package.json, você pode adicionar o
modules
(oufoo
ebar
) como um pacote sem publicar ou usar um servidor externo como este:Depois disso
npm install
, você poderá acessar o códigovar foo = require("foo")
, assim como em todos os outros pacotes.mais informações podem ser encontradas aqui:
https://docs.npmjs.com/files/package.json#local-paths
e aqui como criar um pacote:
https://docs.npmjs.com/getting-started/creating-node-modules
fonte
Você poderia usar um módulo que eu criei , Undot . Não é nada avançado, apenas um ajudante para que você possa evitar o inferno com simplicidade.
Exemplo:
fonte
Você pode definir algo assim no seu app.js:
e sempre que desejar exigir algo da raiz, não importa onde esteja, basta usar o requireFromRoot em vez do exigido pela baunilha. Funciona muito bem para mim até agora.
fonte
requireFromRoot = ((root) => (resource) => require(`${root}/${resource}`))(__dirname);
. Adoro a solução, mas você realmente precisa vincular __dirname assim?require
esta função?Aqui está o caminho real que estou fazendo há mais de 6 meses. Eu uso uma pasta chamada node_modules como minha pasta raiz no projeto, dessa forma, ela sempre procurará essa pasta de qualquer lugar que chamo de requisito absoluto:
Isso é mais útil quando você está aninhado em pastas e é muito menos trabalhoso alterar o local de um arquivo se estiver definido de maneira absoluta. Eu uso apenas 2 que o parente exige em todo o meu aplicativo .
fonte
node_modules
em/src
, e deixar/node_modules
para os fornecedores para manter as coisas separadas. Então, eu tenho/src/node_modules
para o código local e/node_modules
para os fornecedores.NODE_PATH
variável de ambienteA maneira mais fácil de conseguir isso é criando um link simbólico na inicialização do aplicativo
node_modules/app
(ou o que você chamar) que aponta para../app
. Então você pode simplesmente ligarrequire("app/my/module")
. Links simbólicos estão disponíveis em todas as principais plataformas.No entanto, você ainda deve dividir seu material em módulos menores e de manutenção que são instalados via npm. Você também pode instalar seus módulos particulares via git-url, portanto não há razão para ter um diretório de aplicativos monolítico.
fonte
Em seu próprio projeto, você pode modificar qualquer arquivo .js usado no diretório raiz e adicionar seu caminho a uma propriedade da
process.env
variável Por exemplo:Depois, você pode acessar a propriedade em qualquer lugar:
fonte
Outra resposta:
Imagine esta estrutura de pastas:
testes
Em seguida, no test.js , você precisa exigir arquivos como este:
e no main.js :
Agora você pode usar o babel e o babel-plugin-module-resolver com isso. arquivo babelrc para configurar 2 pastas raiz:
Agora você pode exigir arquivos da mesma maneira nos testes e no src :
e se você quiser usar a sintaxe do módulo es6 :
então você importa arquivos nos testes e src assim:
fonte
Acabei de encontrar este artigo que menciona o app-module-path . Ele permite que você configure uma base como esta:
fonte
O
examples
diretório não pôde conter umnode_modules
com um link simbólico para a raiz do projetoproject -> ../../
, permitindo assim que os exemplos sejam usadosrequire('project')
, embora isso não remova o mapeamento, ele permite que a fonte use emrequire('project')
vez derequire('../../')
.Eu testei isso e funciona com a v0.6.18.
Listagem de
project
diretório:O conteúdo de
index.js
atribui um valor a uma propriedade doexports
objeto e chamaconsole.log
com uma mensagem informando que era necessário. O conteúdo detest.js
érequire('project')
.fonte
require('project.a')
? Eu acho que isso pode significarrequire('project/a')
, emborarequire('project').a
também seja possível?node_modules
diretório no pai mais próximo do arquivo e o link seria o mesmo para os dois. Veja nodejs.org/api/…project/node_modules/project -> ../
.Se alguém está procurando outra maneira de contornar esse problema, aqui está minha própria contribuição para o esforço:
A idéia básica: você cria um arquivo JSON na raiz do projeto que mapeia seus caminhos de arquivos para nomes abreviados (ou obtém use-automapper para fazer isso por você). Você pode solicitar seus arquivos / módulos usando esses nomes. Igual a:
Então tem isso.
fonte
O que eu gosto de fazer é aproveitar como o nó é carregado no diretório node_module para isso.
Se alguém tentar carregar o módulo "coisa", alguém faria algo como
O nó procurará o diretório 'thing' no diretório 'node_module'.
Como o node_module normalmente está na raiz do projeto, podemos aproveitar essa consistência. (Se node_module não estiver na raiz, você terá outras dores de cabeça auto-induzidas.)
Se entrarmos no diretório e depois voltarmos a ele, podemos obter um caminho consistente para a raiz do projeto do nó.
Então, se quisermos acessar o diretório / happy, faríamos isso.
Embora seja um pouco hacky, no entanto, sinto que se a funcionalidade de como o node_modules carrega mudar, haverá problemas maiores para lidar. Esse comportamento deve permanecer consistente.
Para esclarecer, eu faço isso, porque o nome do módulo não importa.
Eu usei recentemente para angular2. Eu quero carregar um serviço da raiz.
fonte
src/app/my.service
, também pode configurar o VSC para usar importações não relativas para arquivos datilografados.Escrevi este pequeno pacote que permite exigir pacotes pelo caminho relativo da raiz do projeto, sem introduzir variáveis globais ou substituir os padrões de nó
https://github.com/Gaafar/pkg-require
Funciona assim
fonte
Só quero acompanhar a ótima resposta de Paolo Moretti e Browserify. Se você estiver usando um transpilador (por exemplo, babel, texto datilografado) e tiver pastas separadas para código-fonte e código transpilado, como
src/
edist/
, poderá usar uma variação das soluções comonode_modules
Com a seguinte estrutura de diretórios:
então você pode deixar babel etc transpilar
src
diretório paradist
diretório.ligação simbólica
Usando o link simbólico, podemos nos livrar de alguns níveis de aninhamento:
Uma ressalva com babel --copy-files A
--copy-files
bandeira debabel
não lida bem com links simbólicos. Pode continuar navegando no..
link simbólico e recusando a ver arquivos intermináveis. Uma solução alternativa é usar a seguinte estrutura de diretórios:Dessa forma, o código abaixo
src
ainda seráapp
resolvidosrc
, enquanto o babel não verá mais links simbólicos.fonte
Eu estava procurando exatamente a mesma simplicidade para exigir arquivos de qualquer nível e encontrei o apelido de módulo .
Basta instalar:
Abra seu arquivo package.json, aqui você pode adicionar aliases para seus caminhos, por exemplo
E use seus aliases simplesmente:
fonte
eu criei um módulo de nó chamado "rekiure"
permite que você exija sem o uso de caminhos relativos
é super fácil de usar
fonte
Estamos prestes a tentar uma nova maneira de resolver esse problema.
Tomando exemplos de outros projetos conhecidos como spring e guice, definiremos um objeto "context" que conterá toda a declaração "require".
Este objeto será passado para todos os outros módulos para uso.
Por exemplo
Isso exige que escrevamos cada módulo como uma função que recebe opts, o que nos parece uma prática recomendada de qualquer maneira.
e então você se referirá ao contexto em vez de exigir coisas.
var module1Ref = context.moduel1;
Se desejar, você pode escrever facilmente um loop para executar as instruções de solicitação
Isso deve facilitar a vida quando você deseja zombar (testes) e também resolve seu problema ao longo do caminho, tornando seu código reutilizável como um pacote.
Você também pode reutilizar o código de inicialização do contexto, separando a declaração de beans dele. por exemplo, seu
main.js
arquivo pode parecer tãoEsse método também se aplica a bibliotecas externas, sem necessidade de codificar seus nomes toda vez que exigimos - no entanto, será necessário um tratamento especial, pois suas exportações não são funções que esperam contexto.
Posteriormente, também podemos definir beans como funções - o que nos permitirá
require
diferentes módulos de acordo com o ambiente - mas que estão fora do escopo desse segmento.fonte
Eu estava tendo problemas com esse mesmo problema, então escrevi um pacote chamado include .
Inclua identificadores para descobrir a pasta raiz do seu projeto, localizando o arquivo package.json, e depois passe o argumento do caminho que você o fornece ao require () nativo sem toda a confusão relativa do caminho. Imagino que isso não seja um substituto para o require (), mas uma ferramenta para exigir o manuseio de arquivos ou bibliotecas não empacotados / de terceiros. Algo como
Espero que isso possa ser útil.
fonte
Se o arquivo js do ponto de entrada do aplicativo (ou seja, aquele em que você realmente executa o "nó") estiver no diretório raiz do projeto, você poderá fazer isso com muita facilidade com o módulo rootpath npm . Basta instalá-lo via
... na parte superior do arquivo js do ponto de entrada, adicione:
A partir desse ponto, todas as chamadas necessárias agora são relativas à raiz do projeto - por exemplo,
require('../../../config/debugging/log');
torna-serequire('config/debugging/log');
(onde a pasta de configuração está na raiz do projeto).fonte
Em linhas simples, você pode chamar sua própria pasta como módulo:
Para isso, precisamos: módulo global e app-module-path
aqui "App-module-path" é o módulo, ele permite adicionar diretórios adicionais ao caminho de pesquisa do módulo Node.js. E "global" é qualquer coisa que você anexar a esse objeto estará disponível em qualquer lugar do seu aplicativo.
Agora dê uma olhada neste trecho:
__dirname é o diretório atual em execução do nó. Você pode fornecer seu próprio caminho aqui para procurar o caminho pelo módulo.
fonte