Global variable not working in NodeJS

10,775

Solution 1

It looks to me like an issue with your bundler not respecting the order you're doing those two lines in. Your source is clearly:

global.a = 1;
require('./core/test.js');

...but the bundled result is clearly the other way around:

console.log(a);
commonjsGlobal.a = 1;

It seems like it's hoisting the require calls. In general, having require calls that need to be done at a particular point in the execution control flow is not best practice (in fact, when defining modules for ES2015, import is explicitly defined as not being executed in the module's step-by-step control flow).

So if you need to do this, you'll probably want to look at another bundler. But check that it supports order other than dependency resolution order.

Solution 2

You are right that it should work. Here's a working example:

// file1.js
global.a = 'hello';
require('./file2');

// file2.js
console.log(a);

Run node file1.js, and you'll see 'hello' printed to the console.

It looks like you've got some other tool being used (Laravel / Elixir). Use node directly and see what happens.

Share:
10,775
Wouter Florijn
Author by

Wouter Florijn

Co-founder & CTO, Dyme.

Updated on June 25, 2022

Comments

  • Wouter Florijn
    Wouter Florijn about 2 years

    I am trying to get global variables working in node.js, but it seems like I don't really understand the concept, even though my understanding matches the documentation.

    Minimal example

    My main.js file, which is compiled using rollup is:

    global.a = 1;
    require('./core/test.js');
    

    My core/test.js file is simply:

    console.log(a);
    

    This causes the error:

    Uncaught ReferenceError: a is not defined

    The fully compiled output is:

    (function (exports) {
    'use strict';
    
    var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
    
    console.log(a);
    
    commonjsGlobal.a = 1;
    
    }((this.LaravelElixirBundle = this.LaravelElixirBundle || {})));
    //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjpudWxsLCJzb3VyY2VzIjpbIkM6L3dhbXAvd3d3L3V1YmMvcmVzb3VyY2VzL2Fzc2V0cy9qcy9jb3JlL3Rlc3QuanMiLCJDOi93YW1wL3d3dy91dWJjL3Jlc291cmNlcy9hc3NldHMvanMvYXBwLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnNvbGUubG9nKGEpO1xyXG4iLCJnbG9iYWwuYSA9IDE7XHJcbnJlcXVpcmUoJy4vY29yZS90ZXN0LmpzJyk7XHJcbiJdLCJuYW1lcyI6WyJnbG9iYWwiXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQzs7QUNBZkEsY0FBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7OyJ9
    

    It seems that a gets defined after console.log(a);. I'm not 100% sure if this matters in JS but it could be causing the error.

    So my question is: what causes this, and what am I doing wrong here?

    Possibly relevant information: I'm using Laravel Elixir to compile everything.

    Note: Please don't post discussion on whether or not to use global variables in node.js or in general. I know it's usually a bad idea, but I have a very good reason to do it in this case.

    Edit: Additional context

    What I'm really trying to do is getting Zurb Foundation to work with Laravel Elixir though node.js. I installed foundation-sites through NPM. foundation-sites relies on jquery, which it pulls in itself. However, Foundation doesn't seem to follow the usual conventions of just using something like var jquery = require('jquery'); in its own js file. It actually relies upon a global jQuery variable being available. Therefore I have to ensure that somehow.

    My actual file looks like this:

    global.jQuery = global.$ = require('jquery');
    require('foundation-sites');
    

    So if there are any Foundation/Laravel-specific anwers I would be very happy to hear them as well. Is there something I'm not getting, or did Foundation just not create their package the "right" way?

  • Wouter Florijn
    Wouter Florijn over 7 years
    That's kind of what I was thinking too. Do you have a link to the documentation that says import is explicitly defined as not being executed in the module's step-by-step control flow?
  • Wouter Florijn
    Wouter Florijn over 7 years
    By the way, I added some additional context to the question. Perhaps you know more about this too?