1

The complicated answer is: because of the differences between versions 16 and 18 of node.js, and I don't know them all. In version 16, I think what I quote from nodejs.org below does not apply. Also, I tried the extensions cjs and mjs, and node.js v16 will not load a module with require() and needs import instead, but import can only be used from within a module, if I remember my research correctly.

The simple answer is that I was using the wrong version of node.js.

Someone thought the answer was the difference between .js and .mjs (and provided a question about those differences), but that wasn't it. I was not able to answer my own question because it has been closed, but hopefully this edit takes and proves valuable to someone else who tries to use v18 documentation with v16 code.

In mid-October, 2022, https://nodejs.org/api/modules.html#modules-commonjs-modules says (about node.js 18, not node.js 16, which I am using) "In Node.js, each file is treated as a separate module." I have this code which produces the error "SyntaxError: await is only valid in async functions and the top level bodies of modules"

init.js

module.exports.TESTING = (process.argv[2] == 'test');
async function init() {
    let ss = require('./safestore.js');

    let p = await ss.safestore.read();
    return p;
}
await init();

it.js

require('./init.js');

... when I run node it.js test

If I change the last line of init.js to (async () => { await init(); })(); then it works fine, hence fulfilling the "in async functions" part of the error, but apparently, node.js is not treating the file init.js as a separate module. Why isn't it?

Dave Scotese
  • 498
  • 5
  • 17
  • To use top-level await, you need to be using modules, which means you need to be using `.mjs` files (in Node), not `.js` files – CertainPerformance Oct 13 '22 at 00:33
  • I suspect this is because I am using Node.js version 16. I tried updating to 18 but ran into a problem (Windows Subsystem for Linux does not have GLIBC_2.28) and found that attempting to fix that can mess up my system. If someone with node.js v18 tries it and the top level await works, please leave a comment or an answer. – Dave Scotese Oct 13 '22 at 01:00
  • I installed Node 18 and it works as expected - no errors when using `await` at the top level when inside a module – CertainPerformance Oct 13 '22 at 01:03
  • @DaveScotese No. That's not the issue. It doesn't matter what version of node you upgrade to commonjs modules does not support top level await. The problem is because commonjs modules are processed synchronously, therefore it is incompatible with top level await. If you want to use top level await you need to use es6 modules (the `export` **keyword** instead of the `module.exports` or `exports` variable). Es6 modules are processed asynchronously by design. Because of this there is a possibility of supporting top level await – slebetman Oct 13 '22 at 01:28
  • Granted, the documentation could have been written more clearly but the word **module** here have two different meanings: 1. Modular code separated by files and 2. ES6 modules. While ES6 modules are a subtype of modular code when the syntax error says "module" it does not mean modular code but ES6 modules. – slebetman Oct 13 '22 at 01:32
  • slebetman @CertainPerformance tried it in Node 18 and it worked, and I tried it in Node 16, granted always with exports (or module.exports) and it failed. I am trusting CertainPerformance that what he tried was the code I provided, but perhaps he merely tested top level await with different code that would have worked in Node 16, but he hasn't described any change. If his test did work without changes, then the different versions is one way to manifest the effect I asked about. If there is an issue with docs, it should be added to https://github.com/nodejs/node. – Dave Scotese Oct 14 '22 at 02:54

0 Answers0