Necesito un módulo que se instaló a través de npm. Quiero acceder a un archivo .js subordinado a ese módulo (para que pueda subclasificar un método Constructor en él). No puedo (bueno, no quiero) modificar el código del módulo, así que no tengo un lugar para extraer su __dirname.
Soy consciente de la siguiente pregunta, pero se trata de obtener la ruta de un módulo sobre el que uno tiene control de código (por lo tanto, __dirname es la solución): En Node.js, ¿cómo puedo saber la ruta de este módulo?
~~~
Aún mejor sería obtener la información del módulo cargado del módulo
Respuestas:
Si entiendo correctamente su pregunta, debe usar require.resolve () :
Ejemplo:
var pathToModule = require.resolve('module');
fuente
require.resolve () es una respuesta parcial. La respuesta aceptada puede funcionar para muchos módulos de nodo, pero no funcionará para todos.
require.resolve("moduleName")
no le da el directorio donde está instalado el módulo; le da la ubicación del archivo definido en elmain
atributo en el módulopackage.json
.Eso podría ser
moduleName/index.js
o podría sermoduleName/lib/moduleName.js
. En el último caso,path.dirname(require.resolve("moduleName"))
devolverá un directorio que quizás no desee o no espere:node_modules/moduleName/lib
La forma correcta de obtener la ruta completa a un módulo específico es resolviendo el nombre del archivo:
let readmePath = require.resolve("moduleName/README.md");
Si solo desea el directorio para el módulo (tal vez vaya a realizar muchas
path.join()
llamadas), resuelva elpackage.json
, que siempre debe estar en la raíz del proyecto, y pase apath.dirname()
:let packagePath = path.dirname(require.resolve("moduleName/package.json"));
fuente
package.json
archivo. ¿No deberías usarlopath.join('moduleName', 'package.json')
por ser compatible con Windows?require.resolve
es independiente de la plataforma, al igualrequire
que no es necesario usarlopath.join
const path = require('path');
antes de usarpath.dirname
.require.resolve('@scope/module')
que me da algo como/path/to/@scope/module/dist/index.js
, sin embargo, si intento ejecutarlorequire.resolve('@scope/module/package.json')
, arroja unMODULE_NOT_FOUND
error. Estoy en el nodo 14.4.0, y el módulo que estoy tratando de resolver tiene"type": "module"
en su package.json unexports
campo que no incluyepackage.json
. No estoy seguro si eso tiene algo que ver con eso ...type: module
, aparentementepackage.json
tiene que ser expuesto explícitamente en elexports
campo. Pensé que la nueva función ESM de Node no bloqueaba larequire
resolución de rutas como de costumbre, pero aparentemente lo hace.FYI,
require.resolve
devuelve el identificador del módulo de acuerdo con CommonJS. En node.js, este es el nombre del archivo. En webpack, este es un número.En la situación del paquete web , aquí está mi solución para averiguar la ruta del módulo:
const pathToModule = require.resolve('module/to/require'); console.log('pathToModule is', pathToModule); // a number, eg. 8 console.log('__webpack_modules__[pathToModule] is', __webpack_modules__[pathToModule]);
Luego
__webpack_modules__[pathToModule]
obtuve información como esta:(function(module, exports, __webpack_require__) { eval("module.exports = (__webpack_require__(6))(85);\n\n//////////////////\n// WEBPACK FOOTER\n// delegated ./node_modules/echarts/lib/echarts.js from dll-reference vendor_da75d351571a5de37e2e\n// module id = 8\n// module chunks = 0\n\n//# sourceURL=webpack:///delegated_./node_modules/echarts/lib/echarts.js_from_dll-reference_vendor_da75d351571a5de37e2e?"); /***/ })
Resultó que necesitaba scripts antiguos del archivo de compilación dll anterior (para una velocidad de compilación más rápida), por lo que mi archivo de módulo actualizado no funcionó como esperaba. Finalmente reconstruí mi archivo dll y resolví mi problema.
Ref: Uso
require.resolve
para obtener la ruta del archivo resuelta (nodo)fuente
Espero entender correctamente sus necesidades: obtener el archivo de punto de entrada de algún módulo. Digamos que desea obtener el punto de entrada del
jugglingdb
módulo:node > require('module')._resolveFilename('jugglingdb') '/usr/local/lib/node_modules/jugglingdb/index.js'
Como puede ver, esta no es una forma "oficial" de obtener este tipo de información sobre el módulo, por lo que el comportamiento de esta función puede cambiar de una versión a otra. Lo encontré en la fuente del nodo: https://github.com/joyent/node/blob/master/lib/module.js#L280
fuente
De acuerdo con la solución @anatoliy, en MacOS X, encontré las rutas de búsqueda haciendo
require('module')._resolveLookupPaths('myModule')
entonces obtengo las rutas de búsqueda resueltas
[ 'myModule', [ '/Users/admin/.node_modules', '/Users/admin/.node_libraries', '/usr/local/lib/node' ] ]
mientras que el
require('module')._resolveFilename('myModule')
no resolverá el módulo que estaba buscando de todos modos, de hecho lo loco es que
_load
no resolverá el módulo:> require('module')._load('myModule') Error: Cannot find module 'myModule' at Function.Module._resolveFilename (module.js:440:15) at Function.Module._load (module.js:388:25) at repl:1:19 at sigintHandlersWrap (vm.js:32:31) at sigintHandlersWrap (vm.js:96:12) at ContextifyScript.Script.runInContext (vm.js:31:12) at REPLServer.defaultEval (repl.js:308:29) at bound (domain.js:280:14) at REPLServer.runBound [as eval] (domain.js:293:12) at REPLServer.<anonymous> (repl.js:489:10)
mientras que la
require
voluntad:> require('myModule')
pero no tengo este módulo en
myProject/node_modules/ myProject/node_modules/@scope/ /usr/local/lib/node_modules/ /usr/local/lib/node_modules/@scope /usr/local/lib/node_modules/npm/node_modules/ /usr/local/lib/node_modules/npm/node_modules/@scope $HOME/.npm/ $HOME/.npm/@scope/
Entonces, ¿dónde está este módulo?
Primero tuve que hacer un
$ sudo /usr/libexec/locate.updatedb
Luego después de un café lo hicelocate myModule
o mejorlocate myModule/someFile.js
et voilà, resulta que estaba en una carpeta principal de mi proyecto, es decir, fuera de la carpeta raíz de mi proyecto:
por lo que no se puede evitar
rm -rf ../../node_modules/myModule/
y un fresconpm install
.Puedo argumentar que nadie
npm
recibió instrucciones de escanear mi computadora en busca de módulos en otro lugar que no sea la carpeta raíz del proyecto donde se suponía que debía ejecutarse o en la ruta de búsqueda de módulos predeterminada.fuente
Esto es quizás lo que estás buscando, comprueba:
fuente
La respuesta de Jason fue la mejor respuesta, hasta que Node.js ESM y el
exports
campo salieron.Ahora que Node admite paquetes con un
exports
campo que de forma predeterminada evitará que los archivos como sepackage.json
puedan resolver a menos que el autor del paquete decida explícitamente exponerlos, el truco en la respuesta de Jason fallará para los paquetes que no exponen explícitamentepackage.json
.Hay un paquete llamado
resolve-package-path
que hace el truco.He aquí cómo usarlo:
const resolvePkg = require('resolve-package-path') console.log(resolvePkg('@some/package'))
que dará como resultado algo como
independientemente de lo que
exports
contenga el campo del paquete .fuente