14

I have a scenario where I want to export data to CSV from the client-side. I will have a textbox/area or whatever where the user can input data and then ideally with one click, a local CSV file will be updated with that data.

This is easily achievable with NodeJS with server interaction, and its core modules (specifically fs module), but apparently not so much from a browser.

I found out that certain node modules (for example underscore), support RequireJS's method of making a particular module work in the browser. So for underscore I did this:

methods.js

define(['underscore'],function(_) {

    var Methods = {
        doSomething: function() {

            var x = _.size({one: 1, two: 2, three: 3, xuz: 3});

            alert(x);
        }
    };

    return Methods;
});

common.js

requirejs.config({
    baseURL: 'node_modules',
    paths: {
        underscore: 'underscore/underscore',
    }
});

require(['methods'], function(y){
    y.doSomething();
});

index.html

<script data-main="common" src="require.js"></script>
<script>
require(['common'], function() {

    require(['methods.js']);
});
</script>

The above works fine and will show an alert: 4.

But when I try the same with the fs module it won't work. It will show this error:

Module name "util" has not been loaded yet for context: _. Use require([])

As far as I can understand, this is because fs requires several other modules, one of them being util.

So I proceeded to add all these modules to the RequireJS config. But still no luck, so I specifically tested util module by itself as this doesn't seem to require other modules to work.

And now I am stuck on this error: Uncaught ReferenceError: exports is not defined

I tried modularizing this util module by encapsulating the whole module source code in this:

define([], function() {})

But it didn't work either... I've also tried copying underscore's model but still no luck.

So I was wondering if anyone managed to use util & fs modules (or any other core NodeJS modules) within the browser with libraries such as RequireJS or Browserify.

magicode118
  • 1,344
  • 2
  • 16
  • 25

2 Answers2

7

That's right, exports is node-specific JS (used to make part of your module available outside the module) and isn't supported by web-browsers. Even though NodeJS is technically JS, there are client specific properties (like the window property for browsers, and exports for NodeJS apps) that can't be interchanged.

That said, here's a client side JS answer to the CSV problem.

Community
  • 1
  • 1
FloatingRock
  • 5,603
  • 5
  • 37
  • 62
  • 1
    Both answers that I received are correct, as I have also found out after more research. What I ended up doing for my specific scenario though (to keep everything away from databases & possibly client-side for the user) is having two NodeJS servers running (one for read & other for write). These listen for CSV file changes and will write/read from/to the file system through NodeJS fs module that way. This approach is not totally client-side, but you avoid DB interaction & maintenance plus everything is in JS from client to server-side. – magicode118 Dec 03 '14 at 08:35
2

Your best bet (and probably only one) is to use HTML5 FileSystem API. I am not aware of any other browser feature that would allow to work with files on client computer except maybe Flash and similar solution.

I am bit confused by your browserify tag since you are not obviously using Browserify. That would fix your issue with "exports is not defined".

FredyC
  • 3,339
  • 2
  • 26
  • 36