visual tutorial tools studio proyecto nodejs node for crear node.js

node.js - tutorial - npm



Determine la raíz del proyecto a partir de una aplicación node.js en ejecución (20)

¿Hay una forma mejor que process.cwd() para determinar el directorio raíz de un proceso node.js en ejecución? Algo parecido al de Rails.root , pero para Node.js. Estoy buscando algo que sea tan predecible y confiable como sea posible.


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 simples pasos 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 la ruta se puede definir en el archivo .paths en el directorio raíz de su proyecto.

    $db = /server/database $api-v1 = /server/api/legacy $api-v2 = /server/api/v2


1- crear un archivo en la raíz del proyecto llamarlo 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- adentro node_modules cree un nuevo módulo con el nombre "settings" y dentro del módulo index.js escriba este código:

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

4- y en cualquier momento que desee su directorio de proyectos solo use

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

de esta manera tendrá todos los directorios del proyecto relativos a este archivo;)


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. Úsalo como cualquier otra variable:

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

Sencillo...


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

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

node myfile

o

node myfile.js

Esa es la razón por la que lo caché, ver 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 || ''''; } };


En la parte superior del archivo principal agregue:

mainDir = __dirname;

Entonces utilízalo en cualquier archivo que necesites:

console.log(''mainDir '' + mainDir);

  • mainDir se define globalmente, si solo lo necesita en el archivo actual, use __dirname en __dirname lugar.
  • El archivo principal suele estar en la carpeta raíz del proyecto y se denomina main.js , index.js , gulpfile.js .

En realidad, encuentro la solución quizás trivial también para la más robusta: 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


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

require.main.filename

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

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

Debido a que el module proporciona una propiedad de filename (normalmente equivalente a __filename ), el punto de entrada de la aplicación actual se puede obtener al verificar require.main.filename .

Entonces, si quieres el directorio base para tu aplicación, puedes hacer:

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

Pros contras

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

global.X

Node tiene un objeto de espacio de nombres global llamado global : todo lo que adjunte a este objeto estará disponible en cualquier parte de su aplicación. Por lo tanto, en su index.js (o app.js o como se llame su archivo de aplicación principal), 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 tiene que 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 confiable en absoluto, ya que depende completamente del directorio desde donde se inició el proceso:

$ 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 usa 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 ejecuta en /var/www/ pero el módulo se instala en ~/.nvm/v0.xx/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 métodos de conveniencia adicionales agradables (vea la 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 directorio node_modules su aplicación (por ejemplo, si lo instaló globalmente)

Puede APP_ROOT_PATH esto configurando una variable de entorno APP_ROOT_PATH o llamando a .setPath() en el módulo, pero en ese caso, probablemente esté mejor usando el método global .

Variable ambiental NODE_PATH

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ás tratando de resolver el problema de cargar los módulos de la aplicación de manera confiable, te recomiendo que busques en la variable de entorno NODE_PATH .

El sistema de módulos de Node busca módulos en una variedad de ubicaciones. Una de estas ubicaciones es donde process.env.NODE_PATH puntos . Si establece esta variable de entorno, puede require módulos con el cargador de módulos estándar sin ningún otro cambio.

Por ejemplo, si establece NODE_PATH en /var/www/lib , lo siguiente funcionará bien:

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

Una buena manera de hacerlo es usando npm :

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

Ahora puedes iniciar tu aplicación con npm start y estás dorado. Combino esto con mi módulo de enforce-node-path , que evita la carga accidental de la aplicación sin establecer NODE_PATH . Para obtener aún más control sobre la aplicación de variables ambientales, vea checkenv .

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

[agregado 4/6/16] Otro módulo realmente prometedor que intenta resolver este problema es wavy .


He encontrado 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. Seleccionando el primer elemento del registro y devolviendo 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 por razones de simplicidad (mi bien), lo encajé en un módulo NPM:

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

¡Disfrutar!


Pruebe 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 (la misma posición de package.json)


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


Solo usa:

path.resolve("./") ... output is your project root directory


Tal vez puede intentar desplazarse hacia arriba desde __filename hasta encontrar un package.json , y decidir que ese es el directorio principal al que pertenece su archivo actual.


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

var path= require(''path''); var filePath = path.resolve(''our/virtual/path.ext");


Una técnica que he encontrado útil al usar 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 utilizar 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, de forma predeterminada, es.


Yo uso esto.

Para mi módulo llamado mymodule

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


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

var appRoot = process.env.PWD;

Si desea realizar una verificación cruzada de lo anterior

Supongamos que desea realizar una comprobación cruzada de process.env.PWD con la configuración de su aplicación node.js. Si desea que algunas pruebas de tiempo de ejecución comprueben la validez de process.env.PWD , puede realizar una comprobación cruzada con este código (que escribí, que parece funcionar bien). Puede cotejar el nombre de la última carpeta en appRoot con el 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


para obtener la ruta del archivo actual:

define en ese archivo:

var get_stack = function() { var orig = Error.prepareStackTrace; Error.prepareStackTrace = function(_, stack) { return stack; }; var err = new Error; Error.captureStackTrace(err, arguments.callee); var stack = err.stack; Error.prepareStackTrace = orig; return stack; };

uso en ese archivo:

console.log(get_stack()[0].getFileName());

API:
StackTrace


__dirname no es global; es local al módulo actual, por lo que cada archivo tiene su propio valor local diferente.

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

Si desea predecibilidad y confiabilidad, entonces probablemente necesite que su aplicación requiera que se establezca una determinada variable de entorno. Su aplicación busca MY_APP_HOME (o lo que sea) y si está ahí, 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 indique al usuario que cree la variable. Podría establecerse 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 .


Crear 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''));


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 lista de rutas restantes. Un comportamiento inesperado no arrojará un error, solo un undefined .

Funciona bien para mí, incluso cuando llamo por ejemplo $ mocha .