En Node.js, ¿hay alguna forma de solicitar un archivo del mismo paquete sin usar rutas relativas? Por ejemplo, aquí hay un fragmento de código de ESLint .
const rule = require("../../../lib/rules/accessor-pairs"), { RuleTester } = require("../../../lib/rule-tester"); El hecho de que tengamos que caminar todo el camino hasta el árbol ../../../ para llegar a la raíz no solo es molesto. También es frágil, porque no puedo mover el código sin actualizar todas las referencias de dependencia.
Sin embargo, de alguna manera, los desarrolladores de Node.js parecen haber vivido con él durante los últimos 10 años. No puedo encontrar nada en los documentos o Stack Overflow que resuelva este problema que no sea una dependencia de terceros llamada require-self . Tampoco he podido encontrar una declaración definitiva de que el uso de rutas relativas es la única forma no pirateada de que un archivo requiera otro archivo en el mismo módulo .
Si hay una forma de especificar una ruta relativa a la raíz del paquete en los Módulos ECMAScript (ESM) pero no en CommonJS (CJS), o viceversa, también me gustaría saberlo.
Para ser claro, no creo que haya una solución al problema. Si hay genial. De lo contrario, estoy buscando confirmación con una referencia autorizada.
No necesariamente el mismo paquete : si está escribiendo bibliotecas, esto no será útil, pero si está escribiendo la "aplicación final", lo que realmente se ejecuta:
Una opción:
Si la variable de entorno NODE_PATH se establece en una lista delimitada por dos puntos de rutas absolutas, entonces Node.js buscará módulos en esas rutas si no se encuentran en otro lugar.
Así que puedes hacer cualquiera de:
1.
export NODE_PATH=. node app.js NODE_PATH=. node app.js // app.js (or whatever your entry point is) before *any* require() calls process.env.NODE_PATH = __dirname; require('module').Module._initPaths();O, de otra manera:
El objeto Módulo que representa el script de entrada cargado cuando se inició el proceso de Node.js.
https://nodejs.org/api/modules.html#modules_require_main
Así que solo puedes hacer:
const rule = require.main.require("./lib/rules/accessor-pairs")en cualquier momento que desee que sea relativo a la raíz (suponiendo que así es como tiene estructurado su proyecto).
Puede usar el nombre del paquete como un "enlace simbólico" a la raíz del paquete.
Ejemplo: el paquete foo importa el script de bar en relación con la raíz del paquete foo .
paquete.json
{ "dependencies": { "foo": "file:./foo" } }índice.js
const foo = require('foo'); console.log(foo.bar); // prints "hello"foo/index.js
const bar = require('foo/bar'); // import relative to the package root module.exports = { bar: bar }foo/bar.js
module.exports = 'hello';Si usas vscode entonces estás de suerte - !!!! jsconfig.json en la raíz del proyecto maneja esto magistralmente para commonjs, es6, amd, umd, etc.
El archivo jsconfig.json especifica los archivos raíz y las opciones para las funciones proporcionadas por el servicio de lenguaje JavaScript.
jsconfig.json
{ "compilerOptions": { "module": "commonjs", "baseUrl": ".", "paths": { "@rules/*": ["path/to/lib/rules/"] } } }y luego usar el alias:
const rule = require('@rules/accessor-pairs'), { RuleTester } = require('@rules/rule-tester');Leer más: https://code.visualstudio.com/docs/languages/jsconfig