36

I have a file, test.js with these lines of code inside:

import {blabla} from "./bla";

async function dataGenerator() {
..........
}

(async() => {
  console.log('1')
  await dataGenerator()
  console.log('2')
})()

Note: Ignore the import structure. It is just fictive for the question. In my file the imports are auto.

When I'm trying to run from terminal with node test.js it returns error:

Cannot find module 'D:\bla' imported from D:\test.js

I have added into package.json the line: "type": "module". Without this it returns:

Cannot use import statement outside a module

I'm using node v14. How can I run the test.js without adding to all the imports ".js". There are functions in functions in functions and is complicated to add .js extension. Is there any npm to run it?

Youssouf Oumar
  • 29,373
  • 11
  • 46
  • 65
icsul
  • 593
  • 1
  • 6
  • 11
  • Is the path right ? I mean , you are writing "../" but you test.js is allready in the root dir – binaryRat Oct 07 '20 at 10:33
  • @binaryRat Yes is ok. As i said in question: Note: Ignore the import structure. is just fictive for the question. In my file the imports are auto. – icsul Oct 07 '20 at 10:36
  • The problem with running node with the experimental flag is the lack of future support in future node versions. See [this warning by a node developer](https://gist.github.com/jayphelps/51bafb4505558736fdba0aaf8bfe69d3?permalink_comment_id=2725377#gistcomment-2725377). An alternative approach for you might be to use separate tsconfig files for compiling your test code. So for your library code you use `module:"ES6"` (or ESwhatever) while for your test code you use `module:"CommonJS"`. BTW - using tsconfig `extends` feature you can inherit and modify just the setting necessary. I try it now. – Craig Hicks Feb 17 '22 at 20:48
  • OK - the proposal I made in the last comment is a failure. [A clear explanation why.](https://pencilflip.medium.com/using-es-modules-with-commonjs-modules-in-node-js-1015786dab03). Common JS calling ESM is a no-go. Nevertheless the part about lack of future nodejs support for experimental features is still true. I think that means outputting both CommonJS and ESM is good strategy if your project is a library - keep everybody happy. Don't want to run the TS type checker twice though - that's time costly. Idea - Output TS ESM (target ES*) then use rollup to create ESM and CJS versions. – Craig Hicks Feb 17 '22 at 21:53
  • (...cont). Your test code can then remain as CJS - in which case you import the rollup CJS output for that. Optionally also use ESM test code importing the rollup ESM output for that - with all the headaches and future insecurity that involves. --- The problem with ONLY using ESM test code is oneday finding it is no longer supported by a new version of node. – Craig Hicks Feb 17 '22 at 22:01

1 Answers1

40

Node.js by default does not attempt to guess the file extension when using import for ES modules. This is different from CommonJS modules with require.

In the documentation for the ES module loader you can read how files are found on disk.

The heading 'Customizing ESM specifier resolution algorithm' states:

The --experimental-specifier-resolution=[mode] flag can be used to customize the extension resolution algorithm. The default mode is explicit, which requires the full path to a module be provided to the loader. To enable the automatic extension resolution and importing from directories that include an index file use the node mode.

RickN
  • 12,537
  • 4
  • 24
  • 28
  • 6
    The ES module system (ESM) is developed by ECMA, the stewards of the language, specifically the TC-39 group. The CommonJS module system (which came first) was developed at Mozilla. If its behavior is more to your liking, you're free to use CommonJS—it's not deprecated. ESM modules can, however, be more easily shared between browsers or Node alternatives such as Deno. – RickN Feb 23 '21 at 14:42