1

I accidentally used require() on a javascript module meant to be used with the browser. The module set this['libraryName'] = .... I noticed that it actually worked.

So, I created 2 files:

test1.js

console.log( require('./test2.js'))

test2.js

console.log(this === module.exports)
this.SOMETHING = 10

The result?

$ node ./test1.js 
true
{ SOMETHING: 10 }
$

I didn't expect this! That true means that module.exports is the SAME as this in the global context.

  • Is that new?
  • Is that part of the specs?
  • Doesn't this make it immensely easier to create files that will work if they are imported OR required?
  • If this works, why do we still do the whole check typeof require === 'undefined'?
    • Have I been oblivious to something this important for years?
Merc
  • 13,909
  • 14
  • 64
  • 109
  • Hey this is most probably because require() invokes the module cache, which is why it looks like it is emulating that it is global [you can read the last paragrap here about it](https://nodejs.org/en/knowledge/getting-started/what-is-require/) – rawk Jan 16 '20 at 05:22
  • I am not sure what the module cache has anything to do with it, and the last paragraph is unrelated... – Merc Jan 16 '20 at 08:13

1 Answers1

0
  1. This isn't new:
    1. What is the 'global' object in NodeJS
    2. Meaning of "this" in node.js modules and functions
    3. Why does a module level return statement work in Node.js?
    4. etc.
  2. It's not part of the specs https://nodejs.org/api/globals.html#globals_global

    That means that in browsers if you're in the global scope var something will define a global variable. In Node.js this is different.

    When some things are different they are most definitely not part of any spec.

  3. Doesn't this make it immensely easier to create files that will work if they are imported OR required?

    Don't see how. In node.js this.SOMETHING = 10 only changes one name (module.exports) for another (this). Nothing more.
    And if you'll try to import test2.js into the browser using webpack or <script type="module" src="..."></script> you will get TypeError: undefined has no properties in both cases.

  4. typeof require === 'undefined'

    Maybe you would be better off with browser-require, browserify or something like that.

x00
  • 11,008
  • 2
  • 10
  • 34