Existem várias maneiras de abordar isso, cada uma com seus próprios prós e contras:
require.main.filename
Em http://nodejs.org/api/modules.html :
Quando um arquivo é executado diretamente do Node, require.main
é definido como module
. Isso significa que você pode determinar se um arquivo foi executado diretamente testandorequire.main === module
Como module
fornece uma filename
propriedade (normalmente equivalente a __filename
), o ponto de entrada do aplicativo atual pode ser obtido verificando require.main.filename
.
Portanto, se você deseja o diretório base para seu aplicativo, pode:
var path = require('path');
var appDir = path.dirname(require.main.filename);
Prós e contras
Isso funcionará muito bem na maioria das vezes, mas se você estiver executando seu aplicativo com um iniciador como pm2 ou executando testes mocha , esse método falhará.
global.X
O nó possui um objeto de espaço para nome global chamado global
- tudo o que você anexa a esse objeto estará disponível em qualquer lugar do seu aplicativo. Portanto, no seu index.js
(ou no app.js
nome do arquivo principal do aplicativo), você pode definir apenas uma variável global:
// index.js
var path = require('path');
global.appRoot = path.resolve(__dirname);
// lib/moduleA/component1.js
require(appRoot + '/lib/moduleB/component2.js');
Prós e contras
Funciona de forma consistente, mas você precisa confiar em uma variável global, o que significa que você não pode reutilizar facilmente componentes / etc.
process.cwd ()
Isso retorna o diretório de trabalho atual. Não confiável em tudo, como é inteiramente dependente do que diretório o processo foi lançado a partir de :
$ cd /home/demo/
$ mkdir subdir
$ echo "console.log(process.cwd());" > subdir/demo.js
$ node subdir/demo.js
/home/demo
$ cd subdir
$ node demo.js
/home/demo/subdir
caminho da raiz do aplicativo
Para solucionar esse problema, criei um módulo de nó chamado app-root-path . O uso é simples:
var appRoot = require('app-root-path');
var myModule = require(appRoot + '/lib/my-module.js');
O módulo app-root-path usa várias técnicas diferentes para determinar o caminho raiz do aplicativo, levando em consideração os módulos instalados globalmente (por exemplo, se o aplicativo estiver em execução, /var/www/
mas o módulo estiver instalado ~/.nvm/v0.x.x/lib/node/
). Não funcionará 100% do tempo, mas funcionará nos cenários mais comuns.
Prós e contras
Funciona sem configuração na maioria das circunstâncias. Também fornece alguns bons métodos de conveniência adicionais (consulte a página do projeto). O maior engodo é que não funcionará se:
- Você está usando um iniciador, como pm2
- E , o módulo não está instalado no
node_modules
diretório do seu aplicativo (por exemplo, se você o instalou globalmente)
Você pode contornar isso definindo uma APP_ROOT_PATH
variável ambiental ou chamando .setPath()
o módulo, mas, nesse caso, provavelmente é melhor usar o global
método
Variável de ambiente NODE_PATH
Se você está procurando uma maneira de determinar o caminho raiz do aplicativo atual, é provável que uma das soluções acima funcione melhor para você. Se, por outro lado, você estiver tentando resolver o problema de carregar módulos de aplicativos de forma confiável, eu recomendo analisar a NODE_PATH
variável ambiental.
O sistema Node's Modules procura módulos em vários locais. Um desses locais é onde process.env.NODE_PATH
pontos . Se você definir essa variável de ambiente, poderá efetuar require
módulos com o carregador de módulos padrão sem outras alterações.
Por exemplo, se você definir NODE_PATH
como /var/www/lib
, o seguinte funcionaria perfeitamente:
require('module2/component.js');
// ^ looks for /var/www/lib/module2/component.js
Uma ótima maneira de fazer isso é usando npm
:
"scripts": {
"start": "NODE_PATH=. node app.js"
}
Agora você pode iniciar o seu aplicativo npm start
e você está dourado. Combino isso com meu módulo enforce-node-path , que impede o carregamento acidental do aplicativo sem NODE_PATH
definir. Para obter ainda mais controle sobre a aplicação de variáveis ambientais, consulte checkenv .
Uma pegadinha: NODE_PATH
deve ser configurada fora do aplicativo do nó. Você não pode fazer algo assim process.env.NODE_PATH = path.resolve(__dirname)
porque o carregador de módulos armazena em cache a lista de diretórios que ele pesquisará antes de o aplicativo ser executado.
[adicionado em 4/6/16] Outro módulo realmente promissor que tenta resolver esse problema é ondulado .