নোড.জেজে "ভ্যানিলা" জাভাস্ক্রিপ্ট গ্রন্থাগারগুলি লোড করুন


108

কিছু তৃতীয় পক্ষের জাভাস্ক্রিপ্ট লাইব্রেরি রয়েছে যেগুলির একটি কার্যকারিতা রয়েছে যা আমি নোড.জেএস সার্ভারে ব্যবহার করতে চাই। (বিশেষত আমি যে কোয়াডট্রি জাভাস্ক্রিপ্ট লাইব্রেরিটি পেয়েছি সেটি ব্যবহার করতে চাই।) তবে এই লাইব্রেরিগুলি কেবল .js"নোড.জেএস লাইব্রেরি" নয় সরাসরি সরল ফাইল।

এই হিসাবে, এই লাইব্রেরিগুলি exports.var_nameসিনডেক্সটি অনুসরণ করে না যা নোড.জেস তার মডিউলগুলির জন্য প্রত্যাশা করে। যতদূর আমি বুঝতে পেরেছি এর অর্থ আপনি যখন করবেন module = require('module_name');বা module = require('./path/to/file.js');আপনি কোনও মডিউলটি সর্বজনীনভাবে অ্যাক্সেসযোগ্য ফাংশন ইত্যাদির সাথে শেষ করবেন না etc.

আমার প্রশ্নটি তখন "আমি নোড.জেজে একটি স্বেচ্ছাসেবী জাভাস্ক্রিপ্ট ফাইলটি কীভাবে লোড করব যে এটির পুনর্লিখন না করেই আমি এর কার্যকারিতাটি ব্যবহার করতে পারি যাতে এটি করে exports?"

আমি নোড.জেএস-তে খুব নতুন তাই এটি কীভাবে কাজ করে সে সম্পর্কে আমার বোঝার কোনও চমকপ্রদ ছিদ্র আছে কিনা তা দয়া করে আমাকে জানান।


সম্পাদনা : জিনিসগুলিতে আরও গবেষণা করা এবং আমি এখন দেখতে পাচ্ছি যে মডিউল লোডিং প্যাটার্ন যা নোড.জেএস ব্যবহার করে তা আসলে জাভাস্ক্রিপ্ট লাইব্রেরি লোড করার জন্য একটি সম্প্রতি উন্নত মানের অংশ যাকে কমনজেএস বলা হয় । এটি নোড.জেএস এর জন্য মডিউল ডক পৃষ্ঠায় ডানদিকে বলেছে , তবে আমি এখনও এটি মিস করেছি।

আমার প্রশ্নের উত্তরটি হ'ল "আপনার লাইব্রেরির লেখকরা একটি কমনজেএস ইন্টারফেস লেখার জন্য অপেক্ষা না করা বা এটি আপনার অভিশাপটি না করা পর্যন্ত অপেক্ষা করুন।"


সংশ্লিষ্ট প্রশ্ন: stackoverflow.com/questions/22898080/...
Josmar

উত্তর:


75

সেখানে ব্যবহার তুলনায় অনেক ভালো পদ্ধতি eval: vmমডিউল।

উদাহরণস্বরূপ, এখানে আমার execfileমডিউল রয়েছে, যা স্ক্রিপ্টটিকে pathউভয় contextবা বৈশ্বিক প্রসঙ্গে মূল্যায়ন করে:

var vm = require("vm");
var fs = require("fs");
module.exports = function(path, context) {
  context = context || {};
  var data = fs.readFileSync(path);
  vm.runInNewContext(data, context, path);
  return context;
}

এবং এটি এর মতো ব্যবহার করা যেতে পারে:

> var execfile = require("execfile");
> // `someGlobal` will be a global variable while the script runs
> var context = execfile("example.js", { someGlobal: 42 });
> // And `getSomeGlobal` defined in the script is available on `context`:
> context.getSomeGlobal()
42
> context.someGlobal = 16
> context.getSomeGlobal()
16

যেখানে example.jsরয়েছে:

function getSomeGlobal() {
    return someGlobal;
}

এই পদ্ধতির বড় সুবিধা হ'ল আপনি কার্যকর করা স্ক্রিপ্টে গ্লোবাল ভেরিয়েবলের উপর সম্পূর্ণ নিয়ন্ত্রণ পেয়েছেন: আপনি কাস্টম গ্লোবালগুলিতে (মাধ্যমে context) পাস করতে পারবেন এবং স্ক্রিপ্টের দ্বারা তৈরি সমস্ত গ্লোবাল যুক্ত করা হবে context। ডিবাগিংটি আরও সহজ কারণ সিনট্যাক্স ত্রুটি এবং এর মতো সঠিক ফাইলের নামের সাথে প্রতিবেদন করা হবে।


(অন্যথায় ডক্স হিসাবে হিসাবে উল্লেখ করা হয় ) অপরিবর্তিত runInNewContextথাকলে বিশ্বব্যাপী প্রসঙ্গটি কী ব্যবহার করবেন ? (আমি খুঁজে পাওয়া কোনও দস্তাবেজ দ্বারা এই বিষয়টি পরিষ্কার করা হয়নি)contextsandbox
স্টিভেন লু

দেখে মনে হচ্ছে, নোড বা কমনজেএস প্যাটার্ন সম্পর্কে অজ্ঞানহীন তৃতীয় পক্ষের লাইব্রেরিটির সাথে খেলার জন্য, ক্রিস্টোফারের বিবর্তন পদ্ধতি < স্ট্যাকওভারফ্লো .com/a/9823294/ 1450294 > ভাল কাজ করে। এক্ষেত্রে vmমডিউল কী সুবিধা দিতে পারে ?
মাইকেল শ্যাপার

2
এই পদ্ধতিটি কীভাবে বিকাশের চেয়ে ভাল of তার বিবরণের জন্য আমার আপডেটগুলি দেখুন।
ডেভিড ওলবার

1
এটি সম্পূর্ণরূপে শিলা - এটি আমাকে তাত্ক্ষণিকভাবে আমার ওয়েব-ভিত্তিক অ-মডিউল কোডটিকে একটি সার্ভার-সাইড প্রয়োগের জন্য পুনরায় ব্যবহার করার অনুমতি দেয় যা কোনও ওয়েবপৃষ্ঠায় প্রদর্শন না করে ফলাফলগুলি [একটি সময়সূচী অনুসারে] ইমেল করে। সমস্ত ওয়েব কোড আলগা-বৃদ্ধির মডিউল প্যাটার্ন এবং স্ক্রিপ্ট ইনজেকশন ব্যবহার করেছে - সুতরাং এটি এত সূক্ষ্মভাবে কাজ করে !!
আল জোসলিন

উদাহরণ.js উদাহরণ 1.js লাইব্রেরির উপর নির্ভর করে আমরা কীভাবে নোড.জেজে এটি ব্যবহার করতে পারি?
সিটলক

80

এই পরিস্থিতিটির জন্য আমি 'সবচেয়ে শক্তিশালী' উত্তর বলে আমার মনে হয়।

বলুন আপনার কাছে একটি স্ক্রিপ্ট ফাইল আছে quadtree.js

আপনার এমন একটি কাস্টম তৈরি করা উচিত যাতে node_moduleএই ধরণের ডিরেক্টরি কাঠামো থাকে ...

./node_modules/quadtree/quadtree-lib/
./node_modules/quadtree/quadtree-lib/quadtree.js
./node_modules/quadtree/quadtree-lib/README
./node_modules/quadtree/quadtree-lib/some-other-crap.js
./node_modules/quadtree/index.js

আপনার ./node_modules/quadtree/quadtree-lib/ডিরেক্টরিতে থাকা সমস্ত কিছু আপনার তৃতীয় পক্ষের লাইব্রেরির ফাইল।

তারপরে আপনার ./node_modules/quadtree/index.jsফাইলটি কেবল ফাইল সিস্টেম থেকে সেই লাইব্রেরিটি লোড করবে এবং জিনিসগুলি সঠিকভাবে রফতানির কাজ করবে।

var fs = require('fs');

// Read and eval library
filedata = fs.readFileSync('./node_modules/quadtree/quadtree-lib/quadtree.js','utf8');
eval(filedata);

/* The quadtree.js file defines a class 'QuadTree' which is all we want to export */

exports.QuadTree = QuadTree

এখন আপনি quadtreeঅন্য নোড মডিউলের মতো আপনার মডিউলটি ব্যবহার করতে পারেন ...

var qt = require('quadtree');
qt.QuadTree();

আমি এই পদ্ধতিটি পছন্দ করি কারণ আপনার তৃতীয় পক্ষের লাইব্রেরির উত্স কোডের কোনও পরিবর্তন করার দরকার নেই - সুতরাং এটি বজায় রাখা সহজ। আপগ্রেড করার জন্য আপনাকে যা করতে হবে তা হ'ল তাদের উত্স কোডটি লক্ষ্য করা এবং নিশ্চিত করা উচিত যে আপনি এখনও সঠিক অবজেক্টগুলি রফতানি করছেন।


3
স্রেফ আপনার উত্তরটি খুঁজে পেয়েছে (একটি মাল্টিপ্লেয়ার গেম তৈরি করে সার্ভারের সাথে ক্লায়েন্টের পাশাপাশি আমাদের পদার্থবিজ্ঞান ইঞ্জিন, জিগলিবজেএস অন্তর্ভুক্ত করা দরকার) আপনি আমাকে প্রচুর সময় এবং ঝামেলা বাঁচিয়েছেন। ধন্যবাদ!
স্টিভেন্ডেসু

8
আপনি যদি এটি যথাযথভাবে অনুসরণ করেন তবে মনে রাখবেন যে দুর্ঘটনাক্রমে এনপিএম ব্যবহার করে আপনার নোড_মডিউলগুলি ফোল্ডারটি মুছে ফেলা খুব সহজ especially অবশ্যই আপনার কোয়াডট্রি লাইব্রেরিটিকে একটি পৃথক ভান্ডারে স্থাপন করার কথা বিবেচনা করুন, তারপরে npm linkএটি আপনার অ্যাপ্লিকেশনটিতে যুক্ত করুন। তারপরে এটি এমনভাবে পরিচালনা করা হয় যেন এটি কোনও স্থানীয় নোড.জেএস প্যাকেজ।
বিটাউন

@ টাউন, আপনি আমার মতো নতুনদের জন্য কিছুটা প্রসারিত করতে পারেন এসসিএম এবং এনপিএম লিঙ্কটি ঠিক কী করে যা আপনার উল্লিখিত সম্ভাব্য সমস্যাটিকে বাধা দেয়?
ফ্লায়েন

আমি যদি কেবল একটি স্ক্রিপ্ট অন্তর্ভুক্ত করতে চাই তবে এটি কি সত্যিই প্রয়োজনীয়?
কোয়ান্টাম্পোটাটো

1
@ ফ্লাইয়ান অন্যের কাছে পুরানো মন্তব্যের জবাব দেওয়ার কারণে আমি নিশ্চিত যে আপনি এখনই উত্তরটি জানবেন। এসসিএম - সোর্স কন্ট্রোল ম্যানেজমেন্ট (যেমন জিআইটি) এবং এনপিএম লিঙ্কটির
ডেল্প

30

সবচেয়ে সহজ উপায়: eval(require('fs').readFileSync('./path/to/file.js', 'utf8')); এটি ইন্টারেক্টিভ শেলটিতে পরীক্ষার জন্য দুর্দান্ত কাজ করে।


1
চিয়ার্স মেট! সাহায্য করেছিল অনেক
Schoening

এটিও দ্রুততম উপায় এবং কখনও কখনও দ্রুত এবং ময়লা আপনার প্রয়োজন। এই এবং ডেভিডের উত্তরের মধ্যে, এই এসও পৃষ্ঠাটি একটি দুর্দান্ত উত্স।
মাইকেল শ্যাপার

5

আফাইক, মডিউলগুলি অবশ্যই বোঝা উচিত ed যাইহোক, সমস্ত রফতানি ফাংশনটিকে exportsবস্তুটিতে সজ্জিত করার পরিবর্তে আপনি এগুলিতেও পরীক্ষা করতে পারেন this(অন্যথায় বিশ্বব্যাপী বস্তুটি কী হবে)।

সুতরাং, আপনি যদি অন্য লাইব্রেরিগুলিকে সামঞ্জস্য রাখতে চান তবে আপনি এটি করতে পারেন:

this.quadTree = function () {
  // the function's code
};

বা, যখন বাহ্যিক গ্রন্থাগারের ইতিমধ্যে নিজস্ব নেমস্পেস রয়েছে, যেমন jQuery(আপনি এটি সার্ভার-পাশের পরিবেশে ব্যবহার করতে পারবেন না ):

this.jQuery = jQuery;

নন-নোড পরিবেশে, thisবৈশ্বিক অবজেক্টের সমাধান হবে, এটি একে বিশ্বব্যাপী পরিবর্তনশীল করে তুলবে ... যা এটি ইতিমধ্যে ছিল। সুতরাং এটি কিছু ভাঙ্গা উচিত নয়।

সম্পাদনা : জেমস হার্ডম্যান নোড.জেএস সম্পর্কে নতুনদের জন্য একটি সুন্দর লেখার ব্যবস্থা আছে, যা এটির উল্লেখও করে।


'এই' ট্রিকটি জিনিসগুলিকে আরও পোর্টেবল করার মতো ভাল পদ্ধতির মতো বলে মনে হচ্ছে যাতে নোড.জেএস লাইব্রেরিগুলি নোড.জেএস এর বাইরে ব্যবহার করা যেতে পারে, তবে এর অর্থ এখনও নোড.জেসকে সিনট্যাক্সের সমর্থন করতে আমার জাভাস্ক্রিপ্ট লাইব্রেরি নিজেই পরিবর্তন করতে হবে means ।
ক্রিস ডব্লিউ।

@ ক্রিসডাব্লু: হ্যাঁ, আপনাকে নিজের লাইব্রেরিগুলি ম্যানুয়ালি পরিবর্তন করতে হবে। ব্যক্তিগতভাবে, আমি বাহ্যিক ফাইলগুলি অন্তর্ভুক্ত করার জন্য একটি দ্বিতীয় প্রক্রিয়াও পছন্দ করতাম, এটি অন্তর্ভুক্ত ফাইলটির বিশ্বব্যাপী নেমস্পেসকে স্বয়ংক্রিয়ভাবে আমদানিকৃত নামস্থানে রূপান্তর করে। সম্ভবত আপনি নোড বিকাশকারীদের কাছে একটি আরএফই ফাইল করতে পারেন?
মারটিজন

3

আমি নিশ্চিত না যে আমি আসলে এটি ব্যবহার করে শেষ করব কিনা কারণ এটি একটি বরং হ্যাকি সমাধান, তবে এর চারপাশের একটি উপায় হ'ল এইভাবে সামান্য মিনি-মডিউল আমদানিকারক তৈরি করা ...

ফাইলটিতে ./node_modules/vanilla.js:

var fs = require('fs');

exports.require = function(path,names_to_export) {
    filedata = fs.readFileSync(path,'utf8');
    eval(filedata);
    exported_obj = {};
    for (i in names_to_export) {
        to_eval = 'exported_obj[names_to_export[i]] = ' 
            + names_to_export[i] + ';'
        eval(to_eval); 
    }
    return exported_obj;
}

তারপরে আপনি যখন আপনার লাইব্রেরির কার্যকারিতা ব্যবহার করতে চান তখন কোন নামটি রফতানি করতে হবে তা আপনাকে ম্যানুয়ালি চয়ন করতে হবে।

সুতরাং ফাইলের মতো একটি লাইব্রেরির জন্য ./lib/mylibrary.js...

function Foo() { //Do something... }
biz = "Blah blah";
var bar = {'baz':'filler'};

আপনি যখন নিজের নোড.জেএস কোডটিতে এর কার্যকারিতাটি ব্যবহার করতে চান ...

var vanilla = require('vanilla');
var mylibrary = vanilla.require('./lib/mylibrary.js',['biz','Foo'])
mylibrary.Foo // <-- this is Foo()
mylibrary.biz // <-- this is "Blah blah"
mylibrary.bar // <-- this is undefined (because we didn't export it)

বাস্তবে এই সমস্ত কীভাবে কাজ করবে তা জানেন না।


ওহে, বাহ: একই ভোটারটির জন্য একই ব্যবহারকারীর দ্বারা একটি ডাউন-ভোট (আমার দ্বারা নয়) এবং আপ-ভোট দেওয়া উত্তর! তার জন্য একটি ব্যাজ থাকা উচিত! ;-)
মাইকেল শ্যাপার

2

আমি খুব সহজেই তাদের স্ক্রিপ্টটি আপডেট করে এটিকে কাজ করতে সক্ষম করেছিলাম module.exports =যেখানে উপযুক্ত ...

উদাহরণস্বরূপ, আমি তাদের ফাইলটি নিয়েছি এবং আমি './libs/apprise.js' এ অনুলিপি করেছি। তারপরে যেখানে এটি শুরু হয়

function apprise(string, args, callback){

আমি এই কাজটি নিযুক্ত করলাম module.exports =:

module.exports = function(string, args, callback){

সুতরাং আমি বা গ্রন্থাগার আমদানি করতে সক্ষম নই আমার ভালো কোড:

window.apprise = require('./libs/apprise.js');

এবং আমি যেতে ভাল ছিল। ওয়াইএমএমভি , এটি ওয়েবপ্যাক সহ ছিল ।


0

include(filename)ত্রুটির ক্ষেত্রে আরও ভাল ত্রুটি বার্তা (স্ট্যাক, ফাইলের নাম ইত্যাদি) সহ একটি সাধারণ ফাংশন eval:

var fs = require('fs');
// circumvent nodejs/v8 "bug":
// https://github.com/PythonJS/PythonJS/issues/111
// http://perfectionkills.com/global-eval-what-are-the-options/
// e.g. a "function test() {}" will be undefined, but "test = function() {}" will exist
var globalEval = (function() {
    var isIndirectEvalGlobal = (function(original, Object) {
        try {
            // Does `Object` resolve to a local variable, or to a global, built-in `Object`,
            // reference to which we passed as a first argument?
            return (1, eval)('Object') === original;
        } catch (err) {
            // if indirect eval errors out (as allowed per ES3), then just bail out with `false`
            return false;
        }
    })(Object, 123);
    if (isIndirectEvalGlobal) {
        // if indirect eval executes code globally, use it
        return function(expression) {
            return (1, eval)(expression);
        };
    } else if (typeof window.execScript !== 'undefined') {
        // if `window.execScript exists`, use it
        return function(expression) {
            return window.execScript(expression);
        };
    }
    // otherwise, globalEval is `undefined` since nothing is returned
})();

function include(filename) {
    file_contents = fs.readFileSync(filename, "utf8");
    try {
        //console.log(file_contents);
        globalEval(file_contents);
    } catch (e) {
        e.fileName = filename;
        keys = ["columnNumber", "fileName", "lineNumber", "message", "name", "stack"]
        for (key in keys) {
            k = keys[key];
            console.log(k, " = ", e[k])
        }
        fo = e;
        //throw new Error("include failed");
    }
}

তবে এটি নোডেজের সাথে আরও ঘন হয়ে যায়: আপনার এটি নির্দিষ্ট করতে হবে:

export NODE_MODULE_CONTEXTS=1
nodejs tmp.js

অন্যথায় আপনি অন্তর্ভুক্ত ফাইলগুলিতে গ্লোবাল ভেরিয়েবল ব্যবহার করতে পারবেন না include(...)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.