Determine la raíz del proyecto desde una aplicación node.js en ejecución

315

¿Hay una mejor manera que process.cwd()determinar el directorio raíz de un proceso node.js en ejecución? Algo así como el equivalente de Rails.root, pero para Node.js. Estoy buscando algo que sea lo más predecible y confiable posible.

MrEvil
fuente
1
¿Hay alguna posibilidad de que no aceptes la respuesta aceptada, incorrecta,?
Dave Newton
99
intente process.env.PWD... vea mi respuesta a continuación.
Alexander Mills

Respuestas:

624

Hay varias formas de abordar esto, cada una con sus propios pros y contras:

require.main.filename

De http://nodejs.org/api/modules.html :

Cuando un archivo se ejecuta directamente desde Node, require.mainse establece en su module. Eso significa que puede determinar si un archivo se ha ejecutado directamente mediante pruebasrequire.main === module

Debido a que moduleproporciona una filenamepropiedad (normalmente equivalente a __filename), el punto de entrada de la aplicación actual se puede obtener marcando require.main.filename.

Entonces, si desea el directorio base para su aplicación, puede hacer lo siguiente:

var path = require('path');
var appDir = path.dirname(require.main.filename);

Pros contras

Esto funcionará muy bien la mayor parte del tiempo, pero si está ejecutando su aplicación con un iniciador como pm2 o ejecutando pruebas de mocha , este método fallará.

global.X

El nodo tiene un objeto de espacio de nombres global llamado global: todo lo que adjunte a este objeto estará disponible en todas partes en su aplicación. Entonces, en su index.js(o app.jscomo se llame el archivo principal de su aplicación), puede definir una variable global:

// index.js
var path = require('path');
global.appRoot = path.resolve(__dirname);

// lib/moduleA/component1.js
require(appRoot + '/lib/moduleB/component2.js');

Pros contras

Funciona de manera consistente, pero debe confiar en una variable global, lo que significa que no puede reutilizar fácilmente los componentes, etc.

process.cwd ()

Esto devuelve el directorio de trabajo actual. No es fiable en absoluto, ya que es totalmente dependiente de qué directorio el proceso se puso en marcha 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

app-root-path

Para solucionar este problema, he creado un módulo de nodo llamado app-root-path . El uso es simple:

var appRoot = require('app-root-path');
var myModule = require(appRoot + '/lib/my-module.js');

El módulo app-root-path utiliza varias técnicas diferentes para determinar la ruta raíz de la aplicación, teniendo en cuenta los módulos instalados globalmente (por ejemplo, si su aplicación se está ejecutando /var/www/pero el módulo está instalado ~/.nvm/v0.x.x/lib/node/). No funcionará el 100% del tiempo, pero funcionará en los escenarios más comunes.

Pros contras

Funciona sin configuración en la mayoría de las circunstancias. También proporciona algunos buenos métodos de conveniencia adicionales (ver página del proyecto) La mayor desventaja es que no funcionará si:

  • Estás usando un lanzador, como pm2
  • Y , el módulo no está instalado dentro del node_modulesdirectorio de su aplicación (por ejemplo, si lo instaló globalmente)

Puede solucionar esto configurando una APP_ROOT_PATHvariable ambiental o llamando .setPath()al módulo, pero en ese caso, probablemente sea mejor usar el globalmétodo.

NODE_PATH variable ambiental

Si está buscando una manera de determinar la ruta raíz de la aplicación actual, es probable que una de las soluciones anteriores funcione mejor para usted. Si, por otro lado, está tratando de resolver el problema de cargar módulos de aplicaciones de manera confiable, le recomiendo que analice la NODE_PATHvariable ambiental.

El sistema de módulos de nodo busca módulos en una variedad de ubicaciones. Una de estas ubicaciones es donde process.env.NODE_PATHapunta . Si configura esta variable de entorno, puede requiremodificar los módulos con el cargador de módulos estándar sin ningún otro cambio.

Por ejemplo, si establece NODE_PATHen /var/www/lib, lo siguiente funcionaría bien:

require('module2/component.js');
// ^ looks for /var/www/lib/module2/component.js

Una excelente manera de hacer esto es usar npm:

"scripts": {
    "start": "NODE_PATH=. node app.js"
}

Ahora puedes iniciar tu aplicación con npm starty eres dorado. Combino esto con mi módulo enforce-node-path , que evita cargar accidentalmente la aplicación sin NODE_PATHconfigurarla. Para obtener aún más control sobre la aplicación de variables ambientales, consulte checkenv .

One gotcha: NODE_PATH must establecerse fuera de la aplicación del nodo. No puede hacer algo así process.env.NODE_PATH = path.resolve(__dirname)porque el cargador de módulos almacena en caché la lista de directorios que buscará antes de que se ejecute su aplicación.

[añadido 4/6/16] Otro módulo realmente prometedor que intenta resolver este problema es ondulado .

inxilpro
fuente
1
@Kevin en este caso, mocha es el punto de entrada de su aplicación. Este es solo un ejemplo de por qué es tan difícil encontrar la "raíz del proyecto": depende mucho de la situación y de lo que quiere decir con "raíz del proyecto".
inxilpro
1
@Kevin lo entiendo completamente. Lo que quiero decir es que el concepto de "raíz del proyecto" es mucho más fácil de entender para un humano que una computadora . Si desea un método infalible, debe configurarlo. El uso require.main.filenamefuncionará la mayor parte del tiempo, pero no todo el tiempo.
inxilpro
2
Relacionado tangencialmente: esta es una forma increíblemente inteligente de organizar su proyecto Node para que no tenga que preocuparse tanto por este problema: allanhortle.com/2015/02/04/…
inxilpro
1
No sé si hubo un cambio en pm2 o un cambio con Node.js pero require.main.filenameparece funcionar con pm2. No sé sobre moca.
Justin Warkentin
8
path.parse(process.mainModule.filename).dir
Cory Robinson
53

__dirnameno es global; es local para el módulo actual, por lo que cada archivo tiene su propio valor local y diferente.

Si desea el directorio raíz del proceso en ejecución, probablemente quiera usarlo process.cwd().

Si desea previsibilidad y confiabilidad, entonces probablemente deba exigir a su aplicación que se establezca una determinada variable de entorno. Su aplicación busca MY_APP_HOME(o lo que sea) y si está allí, y la aplicación existe en ese directorio, entonces todo está bien. Si no está definido o el directorio no contiene su aplicación, debería salir con un error que le indicará al usuario que cree la variable. Se puede configurar como parte de un proceso de instalación.

Puede leer las variables de entorno en el nodo con algo como process.env.MY_ENV_VARIABLE.

izb
fuente
2
Si se usa con precaución, esto podría funcionar bastante bien. Pero sería dar diferentes resultados cuando se hace bin/server.jsfrente cd bin && server.js. (suponiendo que estos archivos js estén marcados como ejecutables)
Myrne Stol
1
Usar me process.cwd()ha funcionado de maravilla, incluso cuando realizo pruebas de mocha. ¡Gracias!
Diogo Eichert
49

1- crea un archivo en la raíz del proyecto llámalo settings.js

2- dentro de este archivo agrega este código

module.exports = {
    POST_MAX_SIZE : 40 , //MB
    UPLOAD_MAX_FILE_SIZE: 40, //MB
    PROJECT_DIR : __dirname
};

3- dentro de node_modules crea un nuevo módulo llamado "configuración" y dentro del módulo index.js escribe este código:

module.exports = require("../../settings");

4- y cuando quieras tu directorio de proyectos solo usa

var settings = require("settings");
settings.PROJECT_DIR; 

de esta manera tendrá todos los directorios de proyectos relacionados con este archivo;)

Alnamrouti Fareed
fuente
33
-1: Para cargar el archivo de configuración, necesita una ruta, para luego obtener la ruta de referencia a ese archivo. Sin resolver nada ...
goliatone
2
Votado por tomarse el tiempo de revisar y editar. Todavía se siente frágil, pero eso podría deberse a que no hay una mejor manera de lograr esto
goliatone
8
Algo que los usuarios querrán tener en cuenta con este enfoque es que a node_modulesmenudo se excluye del control de versiones. Entonces, si trabaja con un equipo o alguna vez necesita clonar su repositorio, tendrá que encontrar otra solución para mantener ese archivo de configuración sincronizado.
Travesty3
@ Travesty3 el módulo de configuración es en realidad un módulo vacío que exporta el contenido de un archivo en la raíz del proyecto: P
Fareed Alnamrouti
@goliatone Con su solución puede obtener el archivo desde cualquier lugar sin conocer su ruta, todo lo que tiene que saber es "configuración". Sin él, tendría que saber explícitamente cuántas carpetas debe retroceder hasta llegar al directorio del proyecto. Esto funciona porque el nodo busca automáticamente node_modules y siempre sabe dónde está.
26

la forma más fácil de obtener la raíz global ( suponiendo que use NPM para ejecutar su aplicación node.js 'npm start', etc. )

var appRoot = process.env.PWD;

Si desea verificar de forma cruzada lo anterior

Supongamos que desea realizar una verificación cruzada process.env.PWDcon la configuración de su aplicación node.js. si desea que algunas pruebas de tiempo de ejecución verifiquen la validez process.env.PWD, puede verificarlo con este código (que escribí, que parece funcionar bien). Puede verificar el nombre de la última carpeta en appRoot con npm_package_name en su archivo package.json, por ejemplo:

    var path = require('path');

    var globalRoot = __dirname; //(you may have to do some substring processing if the first script you run is not in the project root, since __dirname refers to the directory that the file is in for which __dirname is called in.)

    //compare the last directory in the globalRoot path to the name of the project in your package.json file
    var folders = globalRoot.split(path.sep);
    var packageName = folders[folders.length-1];
    var pwd = process.env.PWD;
    var npmPackageName = process.env.npm_package_name;
    if(packageName !== npmPackageName){
        throw new Error('Failed check for runtime string equality between globalRoot-bottommost directory and npm_package_name.');
    }
    if(globalRoot !== pwd){
        throw new Error('Failed check for runtime string equality between globalRoot and process.env.PWD.');
    }

También puede usar este módulo NPM: require('app-root-path')que funciona muy bien para este propósito

Alexander Mills
fuente
55
Esto funciona muy bien en (la mayoría) de los sistemas Unix. Tan pronto como desee que su módulo / aplicación npm funcione en Windows, PWDno está definido y esto falla.
Jeremy Wiebe
1
process.cwd()
Muhammad Umer
@MuhammadUmer ¿por qué process.cwd()siempre sería lo mismo que la raíz del proyecto?
Alexander Mills
si lo llamas en el archivo raíz, sería
Muhammad Umer
14

He descubierto que esto funciona de manera consistente para mí, incluso cuando la aplicación se invoca desde una subcarpeta, como puede ser con algunos marcos de prueba, como Mocha:

process.mainModule.paths[0].split('node_modules')[0].slice(0, -1);

Por qué funciona

En el tiempo de ejecución, el nodo crea un registro de las rutas completas de todos los archivos cargados. Los módulos se cargan primero y, por lo tanto, en la parte superior de este registro. Al seleccionar el primer elemento del registro y devolver la ruta antes del directorio 'node_modules', podemos determinar la raíz de la aplicación.

Es solo una línea de código, pero en aras de la simplicidad (mi bien), lo coloqué en una caja negra en un módulo NPM:

https://www.npmjs.com/package/node-root.pddivine

¡Disfrutar!

Patricio
fuente
1
process.mainModule obsoleto desde: v14.0.0 - use require.main.paths[0].split('node_modules')[0].slice(0, -1);en su lugar.
RobC
10

Todos estos "directorios raíz" en su mayoría necesitan resolver alguna ruta virtual a una ruta de pila real, por lo que puede ser que debería mirar path.resolve?

var path= require('path');
var filePath = path.resolve('our/virtual/path.ext');
Konstantin Isaev
fuente
9

Tan simple como agregar esta línea a su módulo en la raíz, generalmente es app.js

global.__basedir = __dirname;

Entonces _basedir será accesible a todos sus módulos.

didxga
fuente
8

Tal vez pueda intentar recorrer hacia arriba __filenamehasta encontrar un package.jsony decidir que es el directorio principal al que pertenece su archivo actual.

kvz
fuente
7

En realidad, encuentro la solución quizás trivial también para los más robustos: simplemente coloque el siguiente archivo en el directorio raíz de su proyecto: root-path.js que tiene el siguiente código:

import * as path from 'path'
const projectRootPath = path.resolve(__dirname)
export const rootPath = projectRootPath
Avi Tshuva
fuente
4

Una técnica que he encontrado útil cuando uso express es agregar lo siguiente a app.js antes de configurar cualquiera de sus otras rutas

// set rootPath
app.use(function(req, res, next) {
  req.rootPath = __dirname;
  next();
});

app.use('/myroute', myRoute);

No es necesario usar globales y tiene la ruta del directorio raíz como una propiedad del objeto de solicitud.

Esto funciona si su app.js está en la raíz de su proyecto que, por defecto, lo está.

Ben Davies
fuente
4

Agregue esto en algún lugar hacia el inicio de su archivo de aplicación principal (por ejemplo, app.js):

global.__basedir = __dirname;

Esto establece una variable global que siempre será equivalente al directorio base de su aplicación. Úselo como cualquier otra variable:

const yourModule = require(__basedir + '/path/to/module.js');

Sencillo...

Pankaj Shinde
fuente
3

Sé que este ya es demasiado tarde. Pero podemos obtener la URL raíz por dos métodos

1er método

var path = require('path');
path.dirname(require.main.filename);

2do método

var path = require('path');
path.dirname(process.mainModule.filename);

Enlace de referencia: - https://gist.github.com/geekiam/e2e3e0325abd9023d3a3

VIKAS KOHLI
fuente
3

Hay una INIT_CWDpropiedad en process.env. Esto es con lo que estoy trabajando actualmente en mi proyecto.

const {INIT_CWD} = process.env; // process.env.INIT_CWD 
const paths = require(`${INIT_CWD}/config/paths`);

Buena suerte...

Akash
fuente
1
Funcionó de maravilla para un paquete que manipula el proyecto desde el que se llama como un paso posterior a la instalación. Sin embargo, aún no lo he probado en otra capa de dependencia, donde un proyecto usa una dependencia que usa mi paquete.
JamesDev
1
@JamesDev, INIT_CWDresuelve a directorypartir del cual npm-scriptse ejecutó el.
Akash
2

si desea determinar la raíz del proyecto a partir de una aplicación node.js en ejecución, simplemente puede hacerlo también.

process.mainModule.path
Vincent Lab
fuente
1

En la parte superior del archivo principal, agregue:

mainDir = __dirname;

Luego, úselo en cualquier archivo que necesite:

console.log('mainDir ' + mainDir);
  • mainDirse define globalmente, si lo necesita solo en el archivo actual, use __dirnameen su lugar.
  • archivo principal es por lo general en la carpeta raíz del proyecto y se nombra como main.js, index.js, gulpfile.js.
Dariusz Sikorski
fuente
1

Yo uso esto.

Para mi módulo llamado mymodule

var BASE_DIR = __dirname.replace(/^(.*\/mymodule)(.*)$/, '$1')

vbranden
fuente
1

Hazlo sexy 💃🏻.

const users = require('../../../database/users'); // 👎 what you have
// OR
const users = require('$db/users'); // 👍 no matter how deep you are
const products = require('/database/products'); // 👍 alias or pathing from root directory


Tres pasos simples para resolver el problema del camino feo.

  1. Instala el paquete: npm install sexy-require --save
  2. Incluya require('sexy-require')una vez en la parte superior de su archivo de aplicación principal.

    require('sexy-require');
    const routers = require('/routers');
    const api = require('$api');
    ...
  3. Paso opcional La configuración de ruta se puede definir en el .pathsarchivo en el directorio raíz de su proyecto.

    $db = /server/database
    $api-v1 = /server/api/legacy
    $api-v2 = /server/api/v2
sultán
fuente
Parece decente, lástima que tuviera un nombre tan ridículo.
JHH
@JHH bueno ... tenía que encontrar un nombre mejor
sultán el
1

Esto reducirá el árbol de directorios hasta que contenga un node_modulesdirectorio, que generalmente indica la raíz del proyecto:

const fs = require('fs')
const path = require('path')

function getProjectRoot(currentDir = __dirname.split(path.sep)) {
  if (!currentDir.length) {
    throw Error('Could not find project root.')
  }
  const nodeModulesPath = currentDir.concat(['node_modules']).join(path.sep)
  if (fs.existsSync(nodeModulesPath) && !currentDir.includes('node_modules')) {
    return currentDir.join(path.sep)
  }
  return this.getProjectRoot(currentDir.slice(0, -1))
}

También se asegura de que no haya ninguna node_modulesen la ruta devuelta, ya que eso significa que está contenida en una instalación de paquete anidado.

Julien
fuente
1

process.mainModuleestá en desuso desde v 14.0.0. Cuando se refiera a la respuesta, utilice require.main , el resto aún se mantiene.

process.mainModule.paths
  .filter(p => !p.includes('node_modules'))
  .shift()

Obtenga todas las rutas en los módulos principales y filtre aquellas con "node_modules", luego obtenga la primera de la lista de rutas restante. El comportamiento inesperado no arrojará un error, solo unundefined .

Funciona bien para mí, incluso cuando llama, es decir $ mocha.

Andre Figueiredo
fuente
0

Crea una función en app.js

/*Function to get the app root folder*/

var appRootFolder = function(dir,level){
    var arr = dir.split('\\');
    arr.splice(arr.length - level,level);
    var rootFolder = arr.join('\\');
    return rootFolder;
}

// view engine setup
app.set('views', path.join(appRootFolder(__dirname,1),'views'));
Karthik M
fuente
0

Simplemente puede agregar la ruta del directorio raíz en la variable de la aplicación express y obtener esta ruta de la aplicación. Para esto, agregue app.set('rootDirectory', __dirname);su archivo index.js o app.js. Y úselo req.app.get('rootDirectory')para obtener la ruta del directorio raíz en su código.

Pulkit Aggarwal
fuente
0

Antigua pregunta, lo sé, sin embargo, no hay ninguna mención para usar progress.argv. La matriz argv incluye una ruta completa y un nombre de archivo (con o sin extensión .js) que se utilizó como parámetro para ser ejecutado por el nodo. Como esto también puede contener banderas, debe filtrar esto.

Este no es un ejemplo que puede usar directamente (debido a que uso mi propio marco) pero creo que le da una idea de cómo hacerlo. También utilizo un método de caché para evitar que llamar a esta función estrese demasiado el sistema, especialmente cuando no se especifica ninguna extensión (y se requiere una verificación de la existencia del archivo), por ejemplo:

node myfile

o

node myfile.js

Esa es la razón por la que lo guardo en caché, vea también el código a continuación.


function getRootFilePath()
{
        if( !isDefined( oData.SU_ROOT_FILE_PATH ) )
        {
            var sExt = false;

            each( process.argv, function( i, v )
            {
                 // Skip invalid and provided command line options
                if( !!v && isValidString( v ) && v[0] !== '-' )
                {
                    sExt = getFileExt( v );

                    if( ( sExt === 'js' ) || ( sExt === '' && fileExists( v+'.js' )) )
                    {

                        var a = uniformPath( v ).split("/"); 

                         // Chop off last string, filename
                        a[a.length-1]='';

                         // Cache it so we don't have to do it again.
                        oData.SU_ROOT_FILE_PATH=a.join("/"); 

                         // Found, skip loop
                        return true;
                    }
                }
            }, true ); // <-- true is: each in reverse order
        }

        return oData.SU_ROOT_FILE_PATH || '';
    }
}; 
Codebeat
fuente
0

Encontrar la ruta raíz de una aplicación electrónica podría ser complicado. Debido a que la ruta raíz es diferente para el proceso principal y el procesador en diferentes condiciones, como la producción, el desarrollo y las condiciones empaquetadas.

He escrito un paquete npm electron-root-path para capturar la ruta raíz de una aplicación de electrones.

$ npm install electron-root-path

or 

$ yarn add electron-root-path


// Import ES6 way
import { rootPath } from 'electron-root-path';

// Import ES2015 way
const rootPath = require('electron-root-path').rootPath;

// e.g:
// read a file in the root
const location = path.join(rootPath, 'package.json');
const pkgInfo = fs.readFileSync(location, { encoding: 'utf8' });
Ganesh Rathinavel
fuente
0

Esto lo hara:

path.join(...process.argv[1].split(/\/|\\/).slice(0, -1))
Rafi Henig
fuente
0

Funciona para mi

process.env.PWD
Manoj Rana
fuente
0

Preámbulo

Esta es una pregunta muy antigua, pero parece que todavía se tocó el nervio en 2020 como en 2012. Revisé todas las otras respuestas y no pude encontrar una técnica (tenga en cuenta que esto tiene sus limitaciones, pero todas las demás no son aplicable en todas las situaciones también).

Proceso hijo GIT +

Si está utilizando GIT como su sistema de control de versiones, el problema de determinar la raíz del proyecto se puede reducir a (que consideraría la raíz correcta del proyecto; después de todo, desearía que su VCS tenga el alcance de visibilidad más completo posible) :

ruta raíz del repositorio retreive

Como debe ejecutar un comando CLI para hacerlo, necesitaremos generar un proceso secundario. Además, como es muy poco probable que la raíz del proyecto cambie a mitad del tiempo de ejecución, podemos usar la versión síncrona de las child_processAPI del módulo al inicio.

Me pareció spawnSync()el más adecuado para el trabajo. En cuanto al comando real para ejecutar, git worktree(con una --porcelainopción para facilitar el análisis) es todo lo que necesitamos para recuperar la ruta raíz absoluta.

En la muestra, opté por devolver una matriz de rutas porque podría haber más de un árbol de trabajo (aunque es probable que tengan rutas comunes) solo para estar seguro. Tenga en cuenta que, como utilizamos un comando CLI, la shellopción debe establecersetrue (la seguridad no debería ser un problema ya que no hay entradas no confiables).

Enfoque de comparación y retrocesos

Comprendiendo que en una situación en la que VCS puede ser inaccesible, he incluido un par de retrocesos después de analizar documentos y otras respuestas. En resumen, las soluciones propuestas se reducen a (excluyendo módulos de terceros y paquetes específicos):

El | Solución | Ventaja | Problema principal |
El | ------------------------ | ----------------------- | -------------------------------- |
El | `__nombre de archivo` | apunta al archivo del módulo | relativo al módulo |
El | `__dirname` | apunta al módulo dir | igual que `__filename` |
El | caminata de árbol `node_modules` | raíz casi garantizada | caminar en un árbol complejo si está anidado |
El | `path.resolve (". ")` | root si CWD es root | igual que `process.cwd ()` |
El | `process.argv [1]` | igual que `__filename` | igual que `__filename` |
El | `process.env.INIT_CWD` | apunta al directorio `npm run` | requiere el lanzamiento de `npm` && CLI |
El | `process.env.PWD` | apunta al directorio actual | relativo a (es el) directorio de lanzamiento |
El | `process.cwd ()` | igual que `env.PWD` | `process.chdir (ruta)` en tiempo de ejecución |
El | `require.main.filename` | root si `=== módulo` | falla en los módulos `require`d |

De la tabla de comparación anterior, los más universales son dos enfoques:

  • require.main.filenamecomo una manera fácil de obtener root si require.main === modulese cumple
  • node_modulescaminata de árbol propuesta recientemente utiliza otra suposición:

si el directorio del módulo tiene node_modulesdir dentro, es probable que sea la raíz

Para la aplicación principal obtendrá la raíz de la aplicación y para el módulo, la raíz del proyecto.

Fallback 1. Caminata por el árbol

Mi implementación utiliza un enfoque más laxo al detenerse una vez que se encuentra un directorio de destino, ya que para un módulo dado su raíz es la raíz del proyecto. Uno puede encadenar las llamadas o extenderlo para configurar la profundidad de búsqueda:

/**
 * @summary gets root by walking up node_modules
 * @param {import("fs")} fs
 * @param {import("path")} pt
 */
const getRootFromNodeModules = (fs, pt) =>

    /**
     * @param {string} [startPath]
     * @returns {string[]}
     */
    (startPath = __dirname) => {

        //avoid loop if reached root path
        if (startPath === pt.parse(startPath).root) {
            return [startPath];
        }

        const isRoot = fs.existsSync(pt.join(startPath, "node_modules"));

        if (isRoot) {
            return [startPath];
        }

        return getRootFromNodeModules(fs, pt)(pt.dirname(startPath));
    };

Fallback 2. Módulo principal

La segunda implementación es trivial

/**
 * @summary gets app entry point if run directly
 * @param {import("path")} pt
 */
const getAppEntryPoint = (pt) =>

    /**
     * @returns {string[]}
     */
    () => {

        const { main } = require;

        const { filename } = main;

        return main === module ?
            [pt.parse(filename).dir] :
            [];
    };

Implementación

Sugeriría usar el andador de árboles como respaldo porque es más versátil:

const { spawnSync } = require("child_process");
const pt = require('path');
const fs = require("fs");

/**
 * @summary returns worktree root path(s)
 * @param {function : string[] } [fallback]
 * @returns {string[]}
 */
const getProjectRoot = (fallback) => {

    const { error, stdout } = spawnSync(
        `git worktree list --porcelain`,
        {
            encoding: "utf8",
            shell: true
        }
    );

    if (!stdout) {
        console.warn(`Could not use GIT to find root:\n\n${error}`);
        return fallback ? fallback() : [];
    }

    return stdout
        .split("\n")
        .map(line => {
            const [key, value] = line.split(/\s+/) || [];
            return key === "worktree" ? value : "";
        })
        .filter(Boolean);
};

Desventajas

Lo más obvio es tener GIT instalado e inicializado, lo que puede ser indeseable / inverosímil (nota al margen: tener GIT instalado en servidores de producción no es infrecuente, ni es inseguro ). Puede estar mediado por retrocesos como se describe anteriormente.

Notas

  1. Un par de ideas para una mayor extensión del enfoque 1:
    • introducir config como parámetro de función
    • export la función para convertirlo en un módulo
    • verificar si GIT está instalado y / o inicializado

Referencias

  1. git worktree referencia
  2. spawnSync referencia
  3. require.main referencia
  4. path.dirname() referencia
Oleg Valter
fuente
0

Sencillo: require('path').resolve('./')

Vansuita Jr.
fuente
-1

Tratar path._makeLong('some_filename_on_root.js');

ejemplo:

cons path = require('path');
console.log(path._makeLong('some_filename_on_root.js');

Eso devolverá la ruta completa desde la raíz de su aplicación de nodo (misma posición de package.json)

Las leyes x
fuente
-1

Solo usa:

 path.resolve("./") ... output is your project root directory
aligatorr89
fuente
esto funciona muy bien! path.resolve (".") también funciona
Noel Schenk
Eso solo da el directorio actual, que puede no ser el directorio raíz.
Orad
-1
path.dirname(process.mainModule.filename);
Kapil Chhipa
fuente