Access node.js File System module in Meteor - javascript

I'm creating a web app that will edit some config files stored on a user's HD, and decided to give Meteor a shot.
I'd like to use Node.js's File System module to handle to I/O of the config files, but I haven't been able to figure out how to include the module. After some searching, I found the following code here on StackOverlow, which is supposed to allow me to require the module:
var require = __meteor_bootstrap__.require;
var fs = require('fs');
However, even with this placed inside of the if(server) portion of my code, my application is still throwing an error and telling me that 'fs' is undefined.
Has anyone else encountered this issue?

From 0.6.0 you need to use Npm.require
var fs = Npm.require('fs');

Related

Uncaught TypeError: Failed to resolve module specifier "fs". Relative references must start with either "/", "./", or "../"

When I try to import the fs module in my own module like import * as fs from 'fs' the following error in the browser console comes:
Uncaught TypeError: Failed to resolve module specifier "fs". Relative references must start with either "/", "./", or "../".
Using require or using a relative path to the module like ./node_modules/fs will not work, is there any other way of importing the fs module correctly?
You have two basic problems, both of which stem from the fact you are running this code in a browser and not in Node.js.
Passing something like 'fs' to import depends on Node.js style module resolution. Node.js will search the contents of the node_modules folder for matching modules. Browsers can't do that, they haven't got a file system to search; they only deal in URLs.
When dealing with modules in a browser you have to pass either:
A URL that includes an absolute path (like /fs or http://example.com/fs)
A URL that is an explicitly relative path (like ../fs or ./fs).
… just like the error message says.
(Typically you'll also need to put a .js on the end of the URL because your HTTP server is unlikely to do that for you).
You also need to use a module which will run in a browser in the first place.
fs is a Node.js built-in module. It does things which browsers do not allow JavaScript to do (like access the file system).
If you want to use the fs module then you can't use it directly from the browser. Instead, write a web service in Node.js (the Express.js module is useful here) and access it from the browser using Ajax (e.g. the fetch API). This will deal with the server's file system, not the browser's.
If you want to access files on the user's computer, then you'll need to use <input type="file"> and the FileReader API.

Using javascript interpreter 'otto', How to read a file in client side

I'm having difficulties.
I am implementing logic to read the file, encodes it, and send it to the server.
Currently, the library used as javascript interpreter is using 'otto'.
I imported 'fs'(I know it is Built-in module) like
var fs = require("fs");
fs.readFileSync('./test.txt', 'utf8');
but occurred error Module not found: Error: Can't resolve 'fs'
So I inserted node: { fs: "empty" } in webpack.config.js file.
Then compile error is not occurred. But when I called a function that contains fs.readFileSync using cli, occurred error.
TypeError: 'readFileSync' is not a function
First question:
I know that 'otto' is just javascript interpreter. For this reason, when I imported 'fs', is there a failure to find the module?
Second question:
If not, How can I read a file from the clientside and send it to the server?
Last question: Using 'otto', It is impossible??
This is my spec.
macOS High Sierra, Webpack 4.9.1, Node.js 8.11.1.
How to read a file in client side
Since you mention Webpack, I'm assuming the "client side" here is a browser. To read a file from a browser, you use the File API. Note that your code cannot specify what file to read; the user does that, either by picking a file in an input type="file" element, or dragging a file into a drop area. In both cases, you'll get a File object, which you can read using the File API.
You cannot use the fs Node.js module in a browser.

readFileSync is not a function

I am relatively new to Node.js and have been looking around but cannot find a solution. I did check the require javascript file and it does not seem to have a method for "readFileSync". Perhaps I don't have a proper require file? I had a hard time finding this file, everywhere talked about it but most people did not post where to get it.
I installed Node.js and have the require.js file. My current code is like this:
fs = require(['require'], function (foo) {
//foo is now loaded.
});
console.log("\n *STARTING* \n");
// Get content from file
var contents = fs.readFileSync("sliderImages", 'utf8');
I had a bit at first getting require to work however it seems to load the require JavaScript file. I have been following guides and I am not sure why I get this error:
Uncaught TypeError: fs.readFileSync is not a function
I have tried many fixes and cannot seem to figure this one out.
Node.js does not use Require.js. Require.js was built so that you could have asynchronous module loading on the client-side (in your browser).
Node.js uses CommonJS style modules. Your code using CommonJS would look like this:
var fs = require('fs');
console.log("\n *STARTING* \n");
var contents = fs.readFileSync("sliderImages", "utf8");
If we assume you saved this in a file called main.js you would then enter this command in your console (make sure you are in the same directory as the file):
node main.js
This code will not run in the browser. Node.js runs on the server. If you want to load a JSON file on the browser side then you'll need to load it using AJAX. There are numerous resources available to show you how to do this. Be aware that you must either run your page from a server or have a special flag enabled to load in files from the file system.
This error can arise if you write
const fs = import('fs');
in a Node module
but should write
import fs from 'fs';

Requiring/running JavaScript outside of node-webkit application

Suppose I have the following app structure:
outer-folder/
├── my-app/
└── settings.js
where my-app/ is either the unbuilt directory that contains package.json or the packaged application my-app.exe or my-app.app.
I cannot package settings.js with the rest of my app, because I want this file to be editable by users, and loaded upon startup to configure my app. Moreover, I plan to allow settings.js to reside anywhere (for example, in the user's home directory) and be loadable from there.
This works fine when the app is unbuilt. I just have a relative path to the file and require() it like usual. But when the app is built (with grunt-node-webkit-builder if that makes a difference) this fails and I get the dreaded "Cannot find module" error.
I've searched the node-webkit wiki but can't find anything about this issue, am I missing something? What is the best way to load and run an external JavaScript file, like one would do with require(), from a packaged node-webkit app?
I suggest you to use the application data path.
See the documentation here
An exemple
var gui = require('nw.gui');
var path = require('path');
var yaml = require('js-yaml');
var fs = require('fs');
var confPath = path.join(gui.App.dataPath, 'conf', "dev-conf.yml");
try {
conf = yaml.load(fs.readFileSync(confPath, 'utf-8'));
} catch (err) {
throw new Error("Cannot read or parse configuration file '"+confPath+"': "+err);
}
It's a good pratice to separate code and configuration, and App.dataPath aims at the application specific folder in user's application data (different for each OS).
I generally use an installer to copy my configuration file into it.
Next tip: I prefer using YAML instead of JSON for my configuration or settings, because it allows you to insert comments inside the file.

How to run user-submitted modules securely in a node.js?

We are planning to develop a business oriented application platform on node.js + express. And we like to allow users to run their own native node.js modules (set of files js, css, html), so generally it should be like portal and portles/servlets. Users should have ability to install modules on server side with its client part and these modules should interact with platform and other modules throw some api. So needed to isolate these modules from direct access to the system files and database, but they should have access to their own files and database. Please help me what direction should we dig to make it secure.
I have checked information about: sandbox in vm and child process.
I tried:
// Main file:
var util = require('util'),
vm = require('vm'),
fs = require('fs'),
sandbox = {
animal: 'cat',
count: 2,
require: require // I pass it to make possible for the module to
// include some additional files
// but it opens access for all system files
};
var context = vm.createContext(sandbox);
fs.readFile('./user_modules/index.js', 'utf8', function (err, data) {
vm.runInNewContext(data, context);
console.log(util.inspect(context));
});
//** User Module
// user_modules/index.js
var fs = require('fs');
count++;
animal = 'Dog';
fs.readFile('README.md', 'utf8', function (err, data) {
animal = 'Fox';
});
I passed REQUIRE object to module to make possible to include some additional files but it opens access for all system files, is it possible to tell VM or child process to work only with specific folders? Currently I have no idea how to work with database, but I think when user will install his module the platform should copy all files and create a db scheme for the user then when the module will launch I need pass only object which connected to the user dbscheme .
Please help me, I’m really new with nodes, any suggestions how to solve my issue?
Thanks in advance
One thing you could do is to create a shim function around require that does whatever validation you want, and then calls the system's require function. You can then pass that in to the sandbox as a replacement for "require".
I'm not sure of all the changes that would be necessary to make a "secure" sandbox for node.js. To some extent, that's going to depend on what the user-submitted modules need to do.
One way to help ensure that the user modules can't interfere with your code would be to run them in their own process. On a unix system, you can use chroot to create an isolated filesystem for the process to run in, and then communicate with the process over a stdio pipe, or a socket.

Categories

Resources