Node.js import results in ERR_MODULE_NOT_FOUND

26 views Asked by At

Here is how I built and installed node.js(version: 20.11):

./configure --prefix=/home/tester/node
make -j8
make install

Here is how I set the environment:

export PATH=/home/tester/node/bin:$PATH
export NODE_PATH=/home/tester/node/lib/node_modules

Here is how I installed the module to be imported:

npm install -g express

The content of /tmp/test/package.json:

{
    "description": "Test me",
    "type": "module"
}

The content of /tmp/test/test.js:

import express from 'express'

Here is how I executed test.js:

node /tmp/test/test.js

Here is what happened when I executed test.js:

node:internal/process/esm_loader:34
      internalBinding('errors').triggerUncaughtException(
                                ^

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'express' imported from /tmp/test/test.js
Did you mean to import express/index.js?

If I simply remove the line "type": "module" in package.json, and change import express from 'express' to const express = require('express'), then it works. So what is the problem for just using import? I am new to Node.js, and don't know how to figure the issue out. Someone please help me, thank you very much!

2

There are 2 answers

1
Matt Hatcher On

For the way import works, this is an intentional action from the NodeJS team. There is a history behind it but it stems from a decision made long ago that ESM imports would work to automatically resolve index files and extensions (much like require) during the early days of TypeScript.

When using NodeJS ESM imports (not TypeScript ESM imports) you have to specify the file name as well as the extension.

As for express specifically, they don't specify any of the information in their package JSON to help support ESM imports as well as not planning to refactor their codebase from CommonJS to ESM.

When using the import style NodeJS, you'll end up having to do something similar to:

import express from 'express/index.js'

// or the below depending on how they export their code
// import * as express from 'express/index.js'

If you care enough to dig into some conversation about NodeJS and import, this was recently brought up on this GitHub issue

0
張俊芝 On

Finally I figured the issue out myself: NODE_PATH simply doesn't work for import specifiers: https://nodejs.org/docs/latest/api/esm.html#no-node_path.