Saya membutuhkan modul yang diinstal melalui npm. Saya ingin mengakses file .js bawahan ke modul itu (jadi saya bisa membuat subclass metode Konstruktor di dalamnya). Saya tidak bisa (yah, tidak mau) memodifikasi kode modul, jadi tidak punya tempat untuk mengekstrak __dirname-nya.
Saya mengetahui pertanyaan berikut, tetapi ini tentang mendapatkan jalur modul yang memiliki kontrol kode (karenanya, __dirname adalah solusinya): Di Node.js, bagaimana saya dapat mengetahui jalur modul `ini`?
~~~
Bahkan lebih baik mendapatkan info modul yang dimuat modul
Jawaban:
Jika saya benar-benar memahami pertanyaan Anda, Anda harus menggunakan require.resolve () :
Contoh:
var pathToModule = require.resolve('module');
sumber
Requirement.resolve () adalah jawaban parsial. Jawaban yang diterima mungkin berfungsi untuk banyak modul node, tetapi tidak akan berfungsi untuk semuanya.
require.resolve("moduleName")
tidak memberi Anda direktori tempat modul diinstal; ini memberi Anda lokasi file yang ditentukan dalammain
atribut di modulpackage.json
.Bisa jadi
moduleName/index.js
atau bisa jugamoduleName/lib/moduleName.js
. Dalam kasus terakhir,path.dirname(require.resolve("moduleName"))
akan mengembalikan direktori yang mungkin tidak Anda inginkan atau harapkan:node_modules/moduleName/lib
Cara yang benar untuk mendapatkan jalur lengkap ke modul tertentu adalah dengan menyelesaikan nama file:
let readmePath = require.resolve("moduleName/README.md");
Jika Anda hanya menginginkan direktori untuk modul (mungkin Anda akan membuat banyak
path.join()
panggilan), selesaikanpackage.json
- yang harus selalu berada di root proyek - dan teruskan kepath.dirname()
:let packagePath = path.dirname(require.resolve("moduleName/package.json"));
sumber
package.json
file tersebut. Tidakkah seharusnya Anda menggunakanpath.join('moduleName', 'package.json')
karena kompatibel dengan Windows?require.resolve
adalah platform agnostik,require
sehingga tidak perlu digunakanpath.join
const path = require('path');
sebelum menggunakanpath.dirname
.require.resolve('@scope/module')
yang memberi saya sesuatu seperti itu/path/to/@scope/module/dist/index.js
, namun jika saya mencoba menjalankannyarequire.resolve('@scope/module/package.json')
akan munculMODULE_NOT_FOUND
kesalahan. Saya menggunakan Node 14.4.0, dan modul yang saya coba selesaikan ada"type": "module"
di package.json denganexports
bidang yang tidak disertakanpackage.json
. Tidak yakin apakah itu ada hubungannya dengan itu ...type: module
, tampaknyapackage.json
harus diekspos secara eksplisit diexports
lapangan. Saya pikir fitur ESM baru Node tidak memblokirrequire
dari jalur penyelesaian seperti biasa, tetapi ternyata memang demikian.FYI,
require.resolve
mengembalikan pengenal modul sesuai dengan CommonJS. Di node.js ini adalah nama file. Di webpack ini adalah angka.Dalam situasi webpack , berikut adalah solusi saya untuk mengetahui jalur modul:
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]);
Kemudian dari
__webpack_modules__[pathToModule]
saya mendapat informasi seperti ini:(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?"); /***/ })
Ternyata saya membutuhkan skrip lama dari file dll build sebelumnya (untuk kecepatan build lebih cepat), sehingga file modul yang saya perbarui tidak berfungsi seperti yang saya harapkan. Akhirnya saya membangun kembali file dll saya dan memecahkan masalah saya.
Ref: Menggunakan
require.resolve
untuk menyelesaikan jalur file (node)sumber
Saya harap saya benar-benar memahami kebutuhan Anda: untuk mendapatkan file titik masuk dari beberapa modul. Katakanlah Anda ingin mendapatkan titik masuk
jugglingdb
modul:node > require('module')._resolveFilename('jugglingdb') '/usr/local/lib/node_modules/jugglingdb/index.js'
Seperti yang Anda lihat, ini bukan cara "resmi" untuk mendapatkan informasi semacam ini tentang modul, jadi perilaku fungsi ini dapat berubah dari versi ke versi. Saya telah menemukannya di sumber node: https://github.com/joyent/node/blob/master/lib/module.js#L280
sumber
Menurut solusi @anatoliy, Di MacOS XI telah menemukan jalur pencarian yang dilakukan
require('module')._resolveLookupPaths('myModule')
jadi saya mendapatkan jalur pencarian terselesaikan
[ 'myModule', [ '/Users/admin/.node_modules', '/Users/admin/.node_libraries', '/usr/local/lib/node' ] ]
sedangkan
require('module')._resolveFilename('myModule')
tidak akan menyelesaikan modul yang saya cari, pada kenyataannya yang gila adalah bahwa
_load
modul tidak akan menyelesaikan:> 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)
sedangkan
require
keinginan:> require('myModule')
tapi saya tidak memiliki modul ini
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/
jadi dimana modul ini ???
Pertama saya harus melakukan a.
$ sudo /usr/libexec/locate.updatedb
Kemudian setelah minum kopi saya lakukanlocate myModule
atau lebih baiklocate myModule/someFile.js
et voilà, ternyata itu ada di folder induk proyek saya yaitu di luar folder root proyek saya:
sehingga Anda tidak dapat menghindari
rm -rf ../../node_modules/myModule/
dan segarnpm install
.Saya dapat berargumen bahwa tidak ada yang menginstruksikan
npm
untuk memindai komputer saya untuk mencari modul di tempat lain selain folder root proyek saya yang seharusnya dijalankan atau di jalur pencarian modul default.sumber
Ini mungkin yang Anda cari, periksa:
sumber
Jawaban Jason adalah jawaban terbaik, sampai Node.js ESM dan
exports
field keluar.Sekarang Node mendukung paket dengan
exports
bidang yang secara default akan mencegah file sepertipackage.json
dapat diatasi kecuali pembuat paket secara eksplisit memutuskan untuk mengekspos mereka, trik dalam jawaban Jason akan gagal untuk paket yang tidak secara eksplisit mengekspospackage.json
.Ada sebuah paket bernama
resolve-package-path
yang melakukan trik.Berikut cara menggunakannya:
const resolvePkg = require('resolve-package-path') console.log(resolvePkg('@some/package'))
yang akan menghasilkan sesuatu seperti
terlepas dari isi
exports
bidang paket .sumber