2015-03-31 6 views
6

के अंदर readFileSync का उपयोग कैसे करें मैं nodeJs vm के साथ प्रयोग कर रहा हूं। इस कोड काम करता है:nodeJs vm

server.js

var fs = require('fs'); 
    var vm = require('vm'); 

    var app = fs.readFileSync(__dirname + '/' + 'app.js'); 
    vm.runInThisContext(app); 


    var http = require('http'); 

    var server = http.createServer(onRequest); 
    server.listen(8080, '127.0.0.1'); 

app.js

function onRequest(req, res) { 
     res.writeHead(200, {'Content-Type': 'text/html'}); 
     res.end('Hello Node.js\n'); 
    } 

अब अगर मैं

function onRequest(req, res) { 
     res.writeHead(200, {'Content-Type': 'text/html'}); 
     res.end(fs.readFileSync(__dirname + '/index.html')); 
    } 

में app.js बदल यह अब काम नहीं करता है: ब्राउज़र प्रिंट करेगा "यह वेबपृष्ठ उपलब्ध नहीं है"

किसी भी तरह से यह कैसे काम कर सकता है fs.readFileSync onRequest के स्थानीय संदर्भ में बाध्यकारी?

उत्तर

1

docs से हवाला देते हुए:

रनिंग कोड स्थानीय गुंजाइश के लिए पहुँच नहीं है, लेकिन मौजूदा वैश्विक वस्तु के लिए उपयोग किया है।

तो, चर __dirname और मॉड्यूल fs उस संदर्भ में undefined हैं।

समस्या को हल करने के लिए, का उपयोग global वस्तु:

server.js

var fs = require('fs'); 
var vm = require('vm'); 

global.fs = fs; 
global.__dirname = __dirname; 

var app = fs.readFileSync(__dirname + '/' + 'app.js'); 
vm.runInThisContext(app); 


var http = require('http'); 

var server = http.createServer(onRequest); 
server.listen(8080, '127.0.0.1'); 

app.js

function onRequest(req, res) { 
    res.writeHead(200, {'Content-Type': 'text/html'}); 
    res.end(global.fs.readFileSync(global.__dirname + '/index.html')); 
} 
+1

साथ app.js चलाने वाह धन्यवाद मैं पूरे गूगल और सी में घूम गया जवाब नहीं मिल रहा है :) – user310291

2

जबकि जवाब JohnKiller द्वारा पोस्ट की गई तकनीकी रूप से सही है, मैं करूंगा vm.runInContext का उपयोग करने वाले समाधान को इंगित करना और मेरी राय में अधिक मजबूत है।

1) वैश्विक संदर्भ केवल लोड स्क्रिप्ट फ़ाइल द्वारा प्रयोग किया जाता अतिरिक्त चर के साथ प्रदूषित नहीं है:

// app.js 
var fs = require('fs'); 
module.exports = function onRequest(req, res) { 
    res.writeHead(200, {'Content-Type': 'text/html'}); 
    res.end(fs.readFileSync(__dirname + '/index.html')); 
} 

// server.js 
var appFile = __dirname + '/' + 'app.js'; 
var app = fs.readFileSync(appFile); 

var context = vm.createContext({ 
    __filename: appFile, 
    __dirname: __dirname, 
    require: require, 
    module: { exports: {} } 
}); 
context.exports = context.module.exports; 

vm.runInContext(app, context, { filename: appFile }); 
var onRequest = context.module.exports; 

var http = require('http'); 
var server = http.createServer(onRequest); 
server.listen(8080, '127.0.0.1'); 

मैं निम्नलिखित प्रमुख लाभ देखते हैं।

2) बाहरी फ़ाइल से लोड किया गया कोड सैंडबॉक्स किया गया है, यह कॉलर के दायरे चर को सीधे नहीं बदल सकता है। यह बहुत स्पष्ट है कि बाहरी फ़ाइल में चर क्या उपलब्ध हैं।

3) बाहरी फ़ाइल में कोड स्वयं-encapsulated है और संदर्भ में प्रदान किए जा रहे किसी भी बाहरी मॉड्यूल पर निर्भर नहीं है। वास्तव में, यह एक नियमित Node.js फ़ाइल है जिसे सीधे require('./app.js')

1

wtf के माध्यम से लोड किया जा सकता है, क्यों?

var app = fs.readFileSync(__dirname + '/' + 'app.js'); 
vm.runInThisContext(app); 

सिर्फ कार्य करें:

server.js

var http = require('http'); 
// use './' for relative paths 
var app = require('./app.js'); 
// load app.js 
var server = http.createServer(app); 
server.listen(8080, '127.0.0.1'); 

app.js

// app.js has to load `fs` for itself 
var fs = require('fs'); 
module.exports = function app(req, res) { 
    res.writeHead(200, {'Content-Type': 'text/html'}); 
    res.end(global.fs.readFileSync('./index.html')); 
} 
:

require('./app.js') 

Sooo आप पूरे अनुप्रयोग की तरह दिखता है

हो गया

लेकिन, आप वास्तव में पढ़ना चाहते हैं किसी कारण से यदि, संकलन और vm के बजाय साधारण वर्ष require

server.js

var http = require('http'); 
// use './' for relative paths 
var app = vm.runInThisContext('./app.js'); 
// load app.js 
var server = http.createServer(app); 
server.listen(8080, '127.0.0.1'); 

app.js

// app.js _still_ has to load `fs` for itself 
var fs = require('fs'); 

// last value is returned 
function app(req, res) { 
    res.writeHead(200, {'Content-Type': 'text/html'}); 
    res.end(global.fs.readFileSync('./index.html')); 
}