নোড.জেএস-এ আমি যে মডিউলের মাধ্যমে লোড করেছি তা যেভাবে প্রয়োজন তা আমার * নয় * (কোনও কোনও নোড_মডিউলটিতে) কীভাবে পেতে পারি?


94

আমার একটি মডিউল প্রয়োজন যা এনপিএমের মাধ্যমে ইনস্টল করা হয়েছিল। আমি সেই মডিউলের একটি .js ফাইল অধস্তন অ্যাক্সেস করতে চাই (যাতে আমি এটিতে একটি কনস্ট্রাক্টর পদ্ধতি সাবক্লাস করতে পারি)। আমি (ভাল করতে চাই না) মডিউলটির কোডটি সংশোধন করতে পারি না, সুতরাং এর __ ডিরেক্টরিটি বের করার কোনও জায়গা নেই।

আমি নিম্নলিখিত প্রশ্নটি সম্পর্কে সচেতন, তবে এটির একটি মডিউলটির পথ পাওয়ার বিষয়ে যেটির একটিতে কোড নিয়ন্ত্রণ রয়েছে (অতএব, __dirname হল সমাধান): নোড.জেজে আমি কীভাবে `this` মডিউলটির পথ বলতে পারি?

~~~

এমনকি মডিউলটির লোড হওয়া মডিউল তথ্যটি পাওয়া আরও ভাল


আপনি যেখানে ('মডিউল নাম') দিয়ে কোনও ত্রুটি ছাড়াই মডিউলটি লোড করতে সক্ষম হন?
ফুতুর

আপনি এটি আরও ভাল ব্যাখ্যা করতে পারেন? কিছু কোড?
গ্যাব্রিয়েল লামাস

উত্তর:


130

যদি আমি আপনার প্রশ্নটি সঠিকভাবে বুঝতে পারি তবে আপনার প্রয়োজনীয় ব্যবহার করা উচিত res সমাধান করুন () :

একটি মডিউলটির অবস্থান সন্ধানের জন্য অভ্যন্তরীণ প্রয়োজনীয় () যন্ত্রপাতি ব্যবহার করুন, তবে মডিউলটি লোড না করে কেবল সমাধান করা ফাইলের নামটি ফিরিয়ে দিন।

উদাহরণ: var pathToModule = require.resolve('module');


13
এই উত্তরটি সমস্ত নোড মডিউলগুলির সাথে নির্ভরযোগ্যভাবে কাজ করে না। আমার উত্তর দেখুন।
জেসন

61

need.resolve () একটি আংশিক উত্তর। গৃহীত উত্তরটি অনেক নোড মডিউলগুলির জন্য কাজ করতে পারে তবে তাদের সমস্তের জন্য কাজ করবে না।

require.resolve("moduleName")মডিউলটি ইনস্টল হওয়া ডিরেক্টরি আপনাকে দেয় না; এটি আপনাকে mainমডিউলটির বৈশিষ্ট্যে সংজ্ঞায়িত ফাইলের অবস্থান দেয় package.json

এটা হতে পারে moduleName/index.jsবা এটি হতে পারে moduleName/lib/moduleName.js। পরবর্তী ক্ষেত্রে, path.dirname(require.resolve("moduleName"))আপনি চান না বা প্রত্যাশা নাও করতে পারেন এমন একটি ডিরেক্টরি ফিরিয়ে দেবেন:node_modules/moduleName/lib

একটি নির্দিষ্ট মডিউলটির সম্পূর্ণ পাথ পাওয়ার সঠিক উপায় হ'ল ফাইল নামটি সমাধান করে:

let readmePath = require.resolve("moduleName/README.md");

যদি আপনি কেবল মডিউলটির জন্য ডিরেক্টরি চান (সম্ভবত আপনি প্রচুর path.join()কল করতে চলেছেন ), তবে সমাধান করুন package.json- যা অবশ্যই প্রকল্পের মূলের মধ্যে থাকা উচিত - এবং এতে পাস করুন path.dirname():

let packagePath = path.dirname(require.resolve("moduleName/package.json"));

4
package.jsonফাইলটি সনাক্ত করে খুব চতুর উত্তর । path.join('moduleName', 'package.json')উইন্ডোজ সামঞ্জস্যপূর্ণ হওয়ার জন্য আপনার ব্যবহার করা উচিত নয় ?
জোও পিমেন্টেল

4
@ জোওপিমেন্টেলফেরেরাই require.resolveপ্লাটফর্ম অজ্ঞেয় , ঠিক যেমন requireএটি ব্যবহার করার প্রয়োজন হয় নাpath.join
গোপীকৃষ্ণ এস

4
const path = require('path');ব্যবহার করার আগে যোগ করতে ভুলবেন না path.dirname
0

আমি আশা করি এই উত্তরটি সম্পূর্ণ সত্য ছিল! আমি সাফল্যের সাথে এমন কিছু সমাধান করতে পারি require.resolve('@scope/module')যা আমার মতো কিছু দেয় /path/to/@scope/module/dist/index.jsতবে আমি যদি require.resolve('@scope/module/package.json')এটি চালানোর চেষ্টা করি তবে একটি MODULE_NOT_FOUNDত্রুটি ছুঁড়ে যায় । আমি নোডে 14.4.0 এ আছি এবং আমি যে মডিউলটি সমাধান করার চেষ্টা করছি "type": "module"তার প্যাকেজটিতে রয়েছে j জসন এমন একটি exportsক্ষেত্র অন্তর্ভুক্ত নয় package.json। এটির সাথে এর কিছু আছে কিনা তা নিশ্চিত নই ...
trusktr

আমি সমস্যাটি খুঁজে পেয়েছি: যখন কোনও মডিউল রয়েছে তখন type: moduleস্পষ্টতই package.jsonআপনাকে exportsক্ষেত্রের মধ্যে স্পষ্টভাবে প্রকাশ করতে হবে । আমি ভেবেছিলাম নোডের নতুন ইএসএম বৈশিষ্ট্যটি requireস্বাভাবিকের মতো সমাধানের পথগুলি থেকে বিরত রাখেনি , তবে এটি স্পষ্টতই ঘটে।
trusktr

3

এফওয়াইআই, require.resolveকমনজেএস অনুসারে মডিউল শনাক্তকারীকে ফিরিয়ে দেয়। নোড.জেজেসে এটি ফাইলের নাম। ইন webpack এই একটি সংখ্যা।

ইন webpack অবস্থা, এখানে আমার সমাধান মডিউল পথ খুঁজে বের করতে হল:

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]);

তারপরে থেকে __webpack_modules__[pathToModule]আমি এই জাতীয় তথ্য পেয়েছি:

(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?");

    /***/
})

পরিণত হয়েছে আমার পূর্ববর্তী dll বিল্ড ফাইল (দ্রুত বিল্ড গতির জন্য) থেকে পুরানো স্ক্রিপ্টগুলি দরকার, যাতে আমার আপডেট হওয়া মডিউল ফাইলটি আমার প্রত্যাশা অনুযায়ী কাজ না করে। অবশেষে আমি আমার dll ফাইলটি পুনর্নির্মাণ করেছি এবং আমার সমস্যার সমাধান করেছি।

রেফ: ফাইলের সমাধানের পথটি ব্যবহার require.resolveকরার জন্য (নোড)


2

আমি আশা করি আমি আপনার প্রয়োজনগুলি সঠিকভাবে বুঝতে পেরেছি: কিছু মডিউলের প্রবেশ পয়েন্ট ফাইলটি পেতে। ধরা যাক আপনি jugglingdbমডিউলটির প্রবেশ পয়েন্ট পেতে চান :

node
> require('module')._resolveFilename('jugglingdb')
'/usr/local/lib/node_modules/jugglingdb/index.js'

আপনি দেখতে পাচ্ছেন যে মডিউল সম্পর্কে এই জাতীয় তথ্য পাওয়ার এটি "অফিসিয়াল" উপায় নয়, সুতরাং এই ফাংশনের আচরণটি সংস্করণ থেকে সংস্করণে পরিবর্তিত হতে পারে। আমি এটি নোড উত্সে পেয়েছি: https://github.com/joyent/node/blob/master/lib/module.js#L280


2

@ অ্যানাটোলি সমাধান অনুসারে, ম্যাকোস একাদশ অন্বেষণের পথগুলি খুঁজে পেয়েছে

require('module')._resolveLookupPaths('myModule')

তাই আমি সমাধানের জন্য অনুসন্ধানের পথগুলি পেয়েছি

[ 'myModule',
  [ '/Users/admin/.node_modules',
    '/Users/admin/.node_libraries',
    '/usr/local/lib/node' ] ]

যেহেতু

require('module')._resolveFilename('myModule')

আমি যেভাবেই মডিউলটি খুঁজছিলাম তা সমাধান করবে না, আসলে পাগলটি হ'ল _loadমডিউলটি সমাধান করবে না:

> 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)

যখন requireইচ্ছা:

> require('myModule')

তবে আমার এই মডিউলটি নেই

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/

তাহলে এই মডিউলটি কোথায় ???

প্রথমে আমাকে কিছু করতে হবে $ sudo /usr/libexec/locate.updatedb তারপরে কিছু কফির পরে আমি locate myModuleবা আরও ভাল করেছিলামlocate myModule/someFile.js

এছাড়াও, এটি আমার প্রকল্পের মূল ফোল্ডারে অর্থাৎ আমার প্রকল্পের মূল ফোল্ডারের বাইরে ছিল:

$pwd
/Users/admin/Projects/Node/myProject
$ ls ../../node_modules/myModule/

সুতরাং আপনি এড়াতে পারবেন না rm -rf ../../node_modules/myModule/এবং একটি তাজা npm install

আমি তর্ক করতে পারি যে npmআমার প্রকল্পের মূল ফোল্ডারটি যেখানে চালানোর কথা ছিল বা ডিফল্ট মডিউলগুলির অনুসন্ধানের পথের চেয়ে অন্য কোথাও মডিউলগুলির সন্ধানে আমার কম্পিউটার স্ক্যান করার জন্য কেউ নির্দেশ দেয়নি ।


1

এটি সম্ভবত আপনি যা খুঁজছেন, তা পরীক্ষা করুন:

need.main.filename


1

নোড.জেএস ইএসএম এবং exportsক্ষেত্রটি না বের হওয়া পর্যন্ত জেসনের উত্তর ছিল সেরা উত্তর ।

এখন নোড একটি exportsক্ষেত্রের সাথে প্যাকেজগুলিকে সমর্থন করে যা ডিফল্টরূপে ফাইলগুলি package.jsonসমাধানযোগ্য হতে বাধা দেয় যদি না প্যাকেজ লেখক স্পষ্টভাবে তাদের উদ্ঘাটন করার সিদ্ধান্ত না নেয়, জেসনের উত্তরের কৌশলটি প্যাকেজগুলিতে স্পষ্টভাবে প্রকাশ না করে ব্যর্থ হবে package.json

একটি প্যাকেজ বলা resolve-package-pathহয় যা কৌশলটি করে।

এটি কীভাবে ব্যবহার করবেন তা এখানে:

const resolvePkg = require('resolve-package-path')

console.log(resolvePkg('@some/package'))

যা কিছু আউটপুট হবে

/path/to/@some/package/package.json

প্যাকেজের exportsক্ষেত্রটিতে যা রয়েছে তা নির্বিশেষে ।


আমার সন্দেহ হয় যে একবার কোনও লেখক সচেতনভাবে মডিউলটির বিষয়বস্তুর অংশ রফতানি করার পরে আপনি এমনকি শক্তিশালী স্থানে রয়েছেন, কারণ এখন লেখক তাদের পাবলিক ইন্টারফেসটি আনুষ্ঠানিকভাবে সংজ্ঞায়িত করেছেন। আমি মনে করি, যা স্পষ্টত রফতানি হয় না এমন জিনিসগুলির আরও আক্রমণাত্মক রিফ্যাক্টরিংয়ের ঝোঁক তৈরি করবে, তাই না?
জেসন 21

@ জেসন এটি উত্স ফাইলগুলির জন্য সত্য, তবে প্যাকেজ.জসন ফাইলগুলি যাচ্ছে না। সেগুলি আমদানি থেকে আড়াল হওয়ার কোনও কারণ আমি দেখতে পাচ্ছি না।
trusktr
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.