أحاول استخدام الوحدات النمطية السير على الرسم البياني التبعية لملف Node.js. إليك في الغالب الحد الأدنى من اختبار الحالة (انظر أدناه للاطلاع على الحد الأدنى المطلق):
var resolve = require('resolve'),
mdeps = require('module-deps'),
builtins = require('builtins'),
through2 = require('through2');
var md = mdeps({
filter: function(id) {
// Just ignore things built in to Node
return !builtins(process.versions.node).includes(id);
},
// Use the regular Node resolution algorithm instead of whatever browser-resolve does
resolve: resolve
});
md.pipe(through2.obj(function(dep) {
// console.log(dep);
}));
md.end(require.resolve(__filename));
لسبب ما هذا يسبب حدث خطأ: Error: Cannot find module './lib/core' from '/Users/alex/Development/audittool/node_modules/resolve/index.js'
.
لا يمكنني أن أبقى على قيد الحياة لما يحدث. حتى أنني أصلحت module-deps
للتخلص من الحجج التي كانت تغذيها resolve
، حتى أتمكن من إعادة إنتاج استدعاء الوظيفة المحدد الذي كان يجريه. يدوياً يعطي نفس الحجج بالضبط resolve
أدى إلى دقة صحيحة.
لقد بحثت في Google كثيرًا ولا زلت لا أجد شيئًا.
في ما يلي اختبار بسيط للغاية:
test.js
:
require('./test2.js');
test2.js
: (فارغة)
test3.js
:
var resolve = require('resolve'),
mdeps = require('module-deps'),
through2 = require('through2');
var md = mdeps({
resolve: resolve
});
md.end(require.resolve('./test.js'));
لاختبار ما المكالمة module-deps
قمت بتحريره node_modules/module-deps/index.js
في السطر 180 لإضافة:
console.log('EQL', self.resolver === require('/Users/alex/Development/audittool/node_modules/resolve/index.js'));
console.log('RESOLVER', id, parent);
self.resolver(id, parent, function onresolve (err, file, pkg, fakePath) {
...
ال self.resolver
السطر للسياق. ادارة test3.js
مطبوعات:
EQL true
RESOLVER /Users/alex/Development/audittool/test.js { id: '/Users/alex/Development/audittool/__fake.js',
filename: '/Users/alex/Development/audittool/_fake.js',
paths: [],
basedir: '/Users/alex/Development/audittool',
packageFilter: [Function],
modules: {} }
EQL true
RESOLVER ./test2.js { id: '/Users/alex/Development/audittool/test.js',
filename: '/Users/alex/Development/audittool/test.js',
paths: [],
package: { __dirname: '/Users/alex/Development/audittool' },
inNodeModules: false,
packageFilter: [Function],
modules: {} }
events.js:183
throw er; // Unhandled 'error' event
^
Error: Cannot find module './test2.js' from '/Users/alex/Development/audittool/test.js'
at /Users/alex/Development/audittool/node_modules/resolve/lib/async.js:64:35
at load (/Users/alex/Development/audittool/node_modules/resolve/lib/async.js:83:43)
at onex (/Users/alex/Development/audittool/node_modules/resolve/lib/async.js:108:17)
at /Users/alex/Development/audittool/node_modules/resolve/lib/async.js:12:69
at FSReqWrap.oncomplete (fs.js:152:21)
بناء على هذا التفريغ ، قمت بإنشائه resolve_test3.js
لمحاولة إعادة إنشاء module-deps
مكالمة:
var resolve = require('resolve');
resolve('./test2.js', {
id: '/Users/alex/Development/audittool/test.js',
filename: '/Users/alex/Development/audittool/test.js',
paths: [],
package: { __dirname: '/Users/alex/Development/audittool' },
inNodeModules: false,
modules: {}
}, console.log);
ولكن هذا يعمل بنجاح ويطبع:
null '/Users/alex/Development/audittool/test2.js' { __dirname: '/Users/alex/Development/audittool' }
AFAICT ، الفرق الوحيد بين المكالمتين هو أن المكالمة الأولى كانت opts.packageFilter
يعرف.
بعد بعض المباحث ، أعتقد أن المشكلة هي module-deps
لا يمر بشكل صحيح opts.basedir
إلى resolve
. أدخلت if (parent.package) parent.basedir = parent.package.__dirname;
بعد السطر 169 من module-deps
" index.js
(أي السطر الذي يقرأ if (opts.modules) parent.modules = opts.modules;
) ، والتي أصلحت المشكلة.
أعتقد أن السبب في ذلك require_test3.js
عملت بسبب خط 35 في node_modules/resolve/lib/async.js
:
var basedir = opts.basedir || path.dirname(caller());
تنويه caller()
. لان resolve_test3.js
كان يتصل resolve
من نفس الدليل عملت ، ولكن module-deps
كان يدعوها من الداخل node_modules
، لذلك حصلت على خطأ basename.